/* ------------------------------------------------------------ */ boolean isValid() { if (_lastModified == _resource.lastModified() && _length == _resource.length()) { _lastAccessed = System.currentTimeMillis(); return true; } if (this == _cache.remove(_key)) invalidate(); return false; }
/* ------------------------------------------------------------ */ @Override public String toString() { return String.format( "%s %s %d %s %s", _resource, _resource.exists(), _resource.lastModified(), _contentType, _lastModifiedBytes); }
/** * Get the resource list as a HTML directory listing. * * @param base The base URL * @param parent True if the parent directory should be included * @return String of HTML */ public String getListHTML(String base, boolean parent) throws IOException { base = URIUtil.canonicalPath(base); if (base == null || !isDirectory()) return null; String[] ls = list(); if (ls == null) return null; Arrays.sort(ls); String decodedBase = URIUtil.decodePath(base); String title = "Directory: " + deTag(decodedBase); StringBuilder buf = new StringBuilder(4096); buf.append("<HTML><HEAD>"); buf.append("<LINK HREF=\"") .append("jetty-dir.css") .append("\" REL=\"stylesheet\" TYPE=\"text/css\"/><TITLE>"); buf.append(title); buf.append("</TITLE></HEAD><BODY>\n<H1>"); buf.append(title); buf.append("</H1>\n<TABLE BORDER=0>\n"); if (parent) { buf.append("<TR><TD><A HREF=\""); buf.append(URIUtil.addPaths(base, "../")); buf.append("\">Parent Directory</A></TD><TD></TD><TD></TD></TR>\n"); } String encodedBase = hrefEncodeURI(base); DateFormat dfmt = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM); for (int i = 0; i < ls.length; i++) { Resource item = addPath(ls[i]); buf.append("\n<TR><TD><A HREF=\""); String path = URIUtil.addPaths(encodedBase, URIUtil.encodePath(ls[i])); buf.append(path); if (item.isDirectory() && !path.endsWith("/")) buf.append(URIUtil.SLASH); // URIUtil.encodePath(buf,path); buf.append("\">"); buf.append(deTag(ls[i])); buf.append(" "); buf.append("</A></TD><TD ALIGN=right>"); buf.append(item.length()); buf.append(" bytes </TD><TD>"); buf.append(dfmt.format(new Date(item.lastModified()))); buf.append("</TD></TR>"); } buf.append("</TABLE>\n"); buf.append("</BODY></HTML>\n"); return buf.toString(); }
/* ------------------------------------------------------------ */ @Test public void testJarFileLastModified() throws Exception { String s = "jar:" + __userURL + "TestData/test.zip!/subdir/numbers"; ZipFile zf = new ZipFile( MavenTestingUtils.getProjectFile( "src/test/resources/org/eclipse/jetty/util/resource/TestData/test.zip")); long last = zf.getEntry("subdir/numbers").getTime(); Resource r = Resource.newResource(s); assertEquals(last, r.lastModified()); }
/* ------------------------------------------------------------ */ Content(String pathInContext, Resource resource) { _key = pathInContext; _resource = resource; _contentType = _mimeTypes.getMimeByExtension(_resource.toString()); boolean exists = resource.exists(); _lastModified = exists ? resource.lastModified() : -1; _lastModifiedBytes = _lastModified < 0 ? null : new ByteArrayBuffer(HttpFields.formatDate(_lastModified)); _length = exists ? (int) resource.length() : 0; _cachedSize.addAndGet(_length); _cachedFiles.incrementAndGet(); _lastAccessed = System.currentTimeMillis(); _etagBuffer = _etags ? new ByteArrayBuffer(resource.getWeakETag()) : null; }
/* ------------------------------------------------------------ */ CachedHttpContent(String pathInContext, Resource resource, CachedHttpContent gzipped) { _key = pathInContext; _resource = resource; String contentType = _mimeTypes.getMimeByExtension(_resource.toString()); _contentType = contentType == null ? null : new PreEncodedHttpField(HttpHeader.CONTENT_TYPE, contentType); _characterEncoding = _contentType == null ? null : MimeTypes.getCharsetFromContentType(contentType); _mimeType = _contentType == null ? null : MimeTypes.CACHE.get(MimeTypes.getContentTypeWithoutCharset(contentType)); boolean exists = resource.exists(); _lastModifiedValue = exists ? resource.lastModified() : -1L; _lastModified = _lastModifiedValue == -1 ? null : new PreEncodedHttpField( HttpHeader.LAST_MODIFIED, DateGenerator.formatDate(_lastModifiedValue)); _contentLengthValue = exists ? (int) resource.length() : 0; _contentLength = new PreEncodedHttpField(HttpHeader.CONTENT_LENGTH, Long.toString(_contentLengthValue)); if (_cachedFiles.incrementAndGet() > _maxCachedFiles) shrinkCache(); _lastAccessed = System.currentTimeMillis(); _etag = ResourceCache.this._etags ? new PreEncodedHttpField(HttpHeader.ETAG, resource.getWeakETag()) : null; _gzipped = gzipped == null ? null : new CachedGzipHttpContent(this, gzipped); }
public void unpack(WebAppContext context) throws IOException { Resource web_app = context.getBaseResource(); _preUnpackBaseResource = context.getBaseResource(); if (web_app == null) { String war = context.getWar(); if (war != null && war.length() > 0) web_app = context.newResource(war); else web_app = context.getBaseResource(); // Accept aliases for WAR files if (web_app.getAlias() != null) { LOG.debug(web_app + " anti-aliased to " + web_app.getAlias()); web_app = context.newResource(web_app.getAlias()); } if (LOG.isDebugEnabled()) LOG.debug( "Try webapp=" + web_app + ", exists=" + web_app.exists() + ", directory=" + web_app.isDirectory() + " file=" + (web_app.getFile())); // Is the WAR usable directly? if (web_app.exists() && !web_app.isDirectory() && !web_app.toString().startsWith("jar:")) { // No - then lets see if it can be turned into a jar URL. Resource jarWebApp = JarResource.newJarResource(web_app); if (jarWebApp.exists() && jarWebApp.isDirectory()) web_app = jarWebApp; } // If we should extract or the URL is still not usable if (web_app.exists() && ((context.isCopyWebDir() && web_app.getFile() != null && web_app.getFile().isDirectory()) || (context.isExtractWAR() && web_app.getFile() != null && !web_app.getFile().isDirectory()) || (context.isExtractWAR() && web_app.getFile() == null) || !web_app.isDirectory())) { // Look for sibling directory. File extractedWebAppDir = null; if (war != null) { // look for a sibling like "foo/" to a "foo.war" File warfile = Resource.newResource(war).getFile(); if (warfile != null && warfile.getName().toLowerCase(Locale.ENGLISH).endsWith(".war")) { File sibling = new File( warfile.getParent(), warfile.getName().substring(0, warfile.getName().length() - 4)); if (sibling.exists() && sibling.isDirectory() && sibling.canWrite()) extractedWebAppDir = sibling; } } if (extractedWebAppDir == null) // Then extract it if necessary to the temporary location extractedWebAppDir = new File(context.getTempDirectory(), "webapp"); if (web_app.getFile() != null && web_app.getFile().isDirectory()) { // Copy directory LOG.info("Copy " + web_app + " to " + extractedWebAppDir); web_app.copyTo(extractedWebAppDir); } else { // Use a sentinel file that will exist only whilst the extraction is taking place. // This will help us detect interrupted extractions. File extractionLock = new File(context.getTempDirectory(), ".extract_lock"); if (!extractedWebAppDir.exists()) { // it hasn't been extracted before so extract it extractionLock.createNewFile(); extractedWebAppDir.mkdir(); LOG.info("Extract " + web_app + " to " + extractedWebAppDir); Resource jar_web_app = JarResource.newJarResource(web_app); jar_web_app.copyTo(extractedWebAppDir); extractionLock.delete(); } else { // only extract if the war file is newer, or a .extract_lock file is left behind meaning // a possible partial extraction if (web_app.lastModified() > extractedWebAppDir.lastModified() || extractionLock.exists()) { extractionLock.createNewFile(); IO.delete(extractedWebAppDir); extractedWebAppDir.mkdir(); LOG.info("Extract " + web_app + " to " + extractedWebAppDir); Resource jar_web_app = JarResource.newJarResource(web_app); jar_web_app.copyTo(extractedWebAppDir); extractionLock.delete(); } } } web_app = Resource.newResource(extractedWebAppDir.getCanonicalPath()); } // Now do we have something usable? if (!web_app.exists() || !web_app.isDirectory()) { LOG.warn("Web application not found " + war); throw new java.io.FileNotFoundException(war); } context.setBaseResource(web_app); if (LOG.isDebugEnabled()) LOG.debug("webapp=" + web_app); } // Do we need to extract WEB-INF/lib? if (context.isCopyWebInf() && !context.isCopyWebDir()) { Resource web_inf = web_app.addPath("WEB-INF/"); File extractedWebInfDir = new File(context.getTempDirectory(), "webinf"); if (extractedWebInfDir.exists()) IO.delete(extractedWebInfDir); extractedWebInfDir.mkdir(); Resource web_inf_lib = web_inf.addPath("lib/"); File webInfDir = new File(extractedWebInfDir, "WEB-INF"); webInfDir.mkdir(); if (web_inf_lib.exists()) { File webInfLibDir = new File(webInfDir, "lib"); if (webInfLibDir.exists()) IO.delete(webInfLibDir); webInfLibDir.mkdir(); LOG.info("Copying WEB-INF/lib " + web_inf_lib + " to " + webInfLibDir); web_inf_lib.copyTo(webInfLibDir); } Resource web_inf_classes = web_inf.addPath("classes/"); if (web_inf_classes.exists()) { File webInfClassesDir = new File(webInfDir, "classes"); if (webInfClassesDir.exists()) IO.delete(webInfClassesDir); webInfClassesDir.mkdir(); LOG.info( "Copying WEB-INF/classes from " + web_inf_classes + " to " + webInfClassesDir.getAbsolutePath()); web_inf_classes.copyTo(webInfClassesDir); } web_inf = Resource.newResource(extractedWebInfDir.getCanonicalPath()); ResourceCollection rc = new ResourceCollection(web_inf, web_app); if (LOG.isDebugEnabled()) LOG.debug("context.resourcebase = " + rc); context.setBaseResource(rc); } }
/* ------------------------------------------------------------ */ public void sendContent(Object content) throws IOException { Resource resource = null; if (isClosed()) throw new IOException("Closed"); if (super._generator.isWritten()) throw new IllegalStateException("!empty"); // Convert HTTP content to contentl if (content instanceof HttpContent) { HttpContent httpContent = (HttpContent) content; Buffer contentType = httpContent.getContentType(); if (contentType != null && !_responseFields.containsKey(HttpHeaders.CONTENT_TYPE_BUFFER)) { String enc = _response.getSetCharacterEncoding(); if (enc == null) _responseFields.add(HttpHeaders.CONTENT_TYPE_BUFFER, contentType); else { if (contentType instanceof CachedBuffer) { CachedBuffer content_type = ((CachedBuffer) contentType).getAssociate(enc); if (content_type != null) _responseFields.put(HttpHeaders.CONTENT_TYPE_BUFFER, content_type); else { _responseFields.put( HttpHeaders.CONTENT_TYPE_BUFFER, contentType + ";charset=" + QuotedStringTokenizer.quoteIfNeeded(enc, ";= ")); } } else { _responseFields.put( HttpHeaders.CONTENT_TYPE_BUFFER, contentType + ";charset=" + QuotedStringTokenizer.quoteIfNeeded(enc, ";= ")); } } } if (httpContent.getContentLength() > 0) _responseFields.putLongField( HttpHeaders.CONTENT_LENGTH_BUFFER, httpContent.getContentLength()); Buffer lm = httpContent.getLastModified(); long lml = httpContent.getResource().lastModified(); if (lm != null) _responseFields.put(HttpHeaders.LAST_MODIFIED_BUFFER, lm); else if (httpContent.getResource() != null) { if (lml != -1) _responseFields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER, lml); } boolean direct = _connector instanceof NIOConnector && ((NIOConnector) _connector).getUseDirectBuffers() && !(_connector instanceof SslConnector); content = direct ? httpContent.getDirectBuffer() : httpContent.getIndirectBuffer(); if (content == null) content = httpContent.getInputStream(); } else if (content instanceof Resource) { resource = (Resource) content; _responseFields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER, resource.lastModified()); content = resource.getInputStream(); } // Process content. if (content instanceof Buffer) { super._generator.addContent((Buffer) content, Generator.LAST); commitResponse(Generator.LAST); } else if (content instanceof InputStream) { InputStream in = (InputStream) content; try { int max = super._generator.prepareUncheckedAddContent(); Buffer buffer = super._generator.getUncheckedBuffer(); int len = buffer.readFrom(in, max); while (len >= 0) { super._generator.completeUncheckedAddContent(); _out.flush(); max = super._generator.prepareUncheckedAddContent(); buffer = super._generator.getUncheckedBuffer(); len = buffer.readFrom(in, max); } super._generator.completeUncheckedAddContent(); _out.flush(); } finally { if (resource != null) resource.release(); else in.close(); } } else throw new IllegalArgumentException("unknown content type?"); }
/* ------------------------------------------------------------ */ private HttpContent load(String pathInContext, Resource resource, int maxBufferSize) throws IOException { if (resource == null || !resource.exists()) return null; if (resource.isDirectory()) return new ResourceHttpContent( resource, _mimeTypes.getMimeByExtension(resource.toString()), getMaxCachedFileSize()); // Will it fit in the cache? if (isCacheable(resource)) { CachedHttpContent content = null; // Look for a gzip resource if (_gzip) { String pathInContextGz = pathInContext + ".gz"; CachedHttpContent contentGz = _cache.get(pathInContextGz); if (contentGz == null || !contentGz.isValid()) { contentGz = null; Resource resourceGz = _factory.getResource(pathInContextGz); if (resourceGz.exists() && resourceGz.lastModified() >= resource.lastModified() && resourceGz.length() < resource.length()) { contentGz = new CachedHttpContent(pathInContextGz, resourceGz, null); CachedHttpContent added = _cache.putIfAbsent(pathInContextGz, contentGz); if (added != null) { contentGz.invalidate(); contentGz = added; } } } content = new CachedHttpContent(pathInContext, resource, contentGz); } else content = new CachedHttpContent(pathInContext, resource, null); // Add it to the cache. CachedHttpContent added = _cache.putIfAbsent(pathInContext, content); if (added != null) { content.invalidate(); content = added; } return content; } // Look for non Cacheable gzip resource or content String mt = _mimeTypes.getMimeByExtension(pathInContext); if (_gzip) { // Is the gzip content cached? String pathInContextGz = pathInContext + ".gz"; CachedHttpContent contentGz = _cache.get(pathInContextGz); if (contentGz != null && contentGz.isValid() && contentGz.getResource().lastModified() >= resource.lastModified()) return new ResourceHttpContent(resource, mt, maxBufferSize, contentGz); // Is there a gzip resource? Resource resourceGz = _factory.getResource(pathInContextGz); if (resourceGz.exists() && resourceGz.lastModified() >= resource.lastModified() && resourceGz.length() < resource.length()) return new ResourceHttpContent( resource, mt, maxBufferSize, new ResourceHttpContent( resourceGz, _mimeTypes.getMimeByExtension(pathInContextGz), maxBufferSize)); } return new ResourceHttpContent(resource, mt, maxBufferSize); }