/** * @param resource the resource to test * @return True if the resource is cacheable. The default implementation tests the cache sizes. */ protected boolean isCacheable(Resource resource) { if (_maxCachedFiles <= 0) return false; long len = resource.length(); // Will it fit in the cache? return (len > 0 && (_useFileMappedBuffer || (len < _maxCachedFileSize && len < _maxCacheSize))); }
/* ------------------------------------------------------------ */ boolean isValid() { if (_lastModified == _resource.lastModified() && _length == _resource.length()) { _lastAccessed = System.currentTimeMillis(); return true; } if (this == _cache.remove(_key)) invalidate(); return false; }
/** * 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(); }
/* ------------------------------------------------------------ */ protected ByteBuffer getDirectBuffer(Resource resource) { // Only use file mapped buffers for cached resources, otherwise too much virtual memory // commitment for // a non shared resource. Also ignore max buffer size try { if (_useFileMappedBuffer && resource.getFile() != null && resource.length() < Integer.MAX_VALUE) return BufferUtil.toMappedBuffer(resource.getFile()); return BufferUtil.toBuffer(resource, true); } catch (IOException | IllegalArgumentException e) { LOG.warn(e); return null; } }
/* ------------------------------------------------------------ */ 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; }
/* ------------------------------------------------------------ */ protected Buffer getIndirectBuffer(Resource resource) { try { int len = (int) resource.length(); if (len < 0) { LOG.warn("invalid resource: " + String.valueOf(resource) + " " + len); return null; } Buffer buffer = new IndirectNIOBuffer(len); InputStream is = resource.getInputStream(); buffer.readFrom(is, len); is.close(); return buffer; } catch (IOException e) { LOG.warn(e); return 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); }
/** * @param resource * @return True if the resource is cacheable. The default implementation tests the cache sizes. */ protected boolean isCacheable(Resource resource) { long len = resource.length(); // Will it fit in the cache? return (len > 0 && len < _maxCachedFileSize && len < _maxCacheSize); }
/* ------------------------------------------------------------ */ 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); }