diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java index 3e401d96960..9299c184e24 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java @@ -24,12 +24,17 @@ import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; import org.eclipse.jetty.http.MimeTypes.Type; -import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.resource.Resource; /* ------------------------------------------------------------ */ -/** HttpContent. - * +/** HttpContent interface. + *
This information represents all the information about a + * static resource that is needed to evaluate conditional headers + * and to serve the content if need be. It can be implemented + * either transiently (values and fields generated on demand) or + * persistently (values and fields pre-generated in anticipation of + * reuse in from a cache). + *
* */ public interface HttpContent @@ -55,182 +60,4 @@ public interface HttpContent ReadableByteChannel getReadableByteChannel() throws IOException; void release(); - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - public class ResourceAsHttpContent implements HttpContent - { - final Resource _resource; - final String _contentType; - final int _maxBuffer; - final String _etag; - - /* ------------------------------------------------------------ */ - public ResourceAsHttpContent(final Resource resource, final String contentType) - { - this(resource,contentType,-1,false); - } - - /* ------------------------------------------------------------ */ - public ResourceAsHttpContent(final Resource resource, final String contentType, int maxBuffer) - { - this(resource,contentType,maxBuffer,false); - } - - /* ------------------------------------------------------------ */ - public ResourceAsHttpContent(final Resource resource, final String contentType, boolean etag) - { - this(resource,contentType,-1,etag); - } - - /* ------------------------------------------------------------ */ - public ResourceAsHttpContent(final Resource resource, final String contentType, int maxBuffer, boolean etag) - { - _resource=resource; - _contentType=contentType; - _maxBuffer=maxBuffer; - _etag=etag?resource.getWeakETag():null; - } - - /* ------------------------------------------------------------ */ - @Override - public String getContentTypeValue() - { - return _contentType; - } - - /* ------------------------------------------------------------ */ - @Override - public HttpField getContentType() - { - return _contentType==null?null:new HttpField(HttpHeader.CONTENT_TYPE,_contentType); - } - - /* ------------------------------------------------------------ */ - @Override - public String getCharacterEncoding() - { - return _contentType==null?null:MimeTypes.getCharsetFromContentType(_contentType); - } - - /* ------------------------------------------------------------ */ - @Override - public Type getMimeType() - { - return _contentType==null?null:MimeTypes.CACHE.get(MimeTypes.getContentTypeWithoutCharset(_contentType)); - } - - /* ------------------------------------------------------------ */ - @Override - public HttpField getLastModified() - { - long lm = _resource.lastModified(); - return lm>=0?new HttpField(HttpHeader.LAST_MODIFIED,DateGenerator.formatDate(lm)):null; - } - - /* ------------------------------------------------------------ */ - @Override - public String getLastModifiedValue() - { - long lm = _resource.lastModified(); - return lm>=0?DateGenerator.formatDate(lm):null; - } - - /* ------------------------------------------------------------ */ - @Override - public ByteBuffer getDirectBuffer() - { - if (_resource.length()<=0 || _maxBuffer<_resource.length()) - return null; - try - { - return BufferUtil.toBuffer(_resource,true); - } - catch(IOException e) - { - throw new RuntimeException(e); - } - } - - /* ------------------------------------------------------------ */ - @Override - public HttpField getETag() - { - return _etag==null?null:new HttpField(HttpHeader.ETAG,_etag); - } - - /* ------------------------------------------------------------ */ - @Override - public String getETagValue() - { - return _etag; - } - - /* ------------------------------------------------------------ */ - @Override - public ByteBuffer getIndirectBuffer() - { - if (_resource.length()<=0 || _maxBuffer<_resource.length()) - return null; - try - { - return BufferUtil.toBuffer(_resource,false); - } - catch(IOException e) - { - throw new RuntimeException(e); - } - } - - /* ------------------------------------------------------------ */ - @Override - public HttpField getContentLength() - { - long l=_resource.length(); - return l==-1?null:new HttpField.LongValueHttpField(HttpHeader.CONTENT_LENGTH,_resource.length()); - } - - /* ------------------------------------------------------------ */ - @Override - public long getContentLengthValue() - { - return _resource.length(); - } - - /* ------------------------------------------------------------ */ - @Override - public InputStream getInputStream() throws IOException - { - return _resource.getInputStream(); - } - - /* ------------------------------------------------------------ */ - @Override - public ReadableByteChannel getReadableByteChannel() throws IOException - { - return _resource.getReadableByteChannel(); - } - - /* ------------------------------------------------------------ */ - @Override - public Resource getResource() - { - return _resource; - } - - /* ------------------------------------------------------------ */ - @Override - public void release() - { - _resource.close(); - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return String.format("%s@%x{r=%s}",this.getClass().getSimpleName(),hashCode(),_resource); - } - } - } diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/ResourceHttpContent.java b/jetty-http/src/main/java/org/eclipse/jetty/http/ResourceHttpContent.java new file mode 100644 index 00000000000..f0b0a42973f --- /dev/null +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/ResourceHttpContent.java @@ -0,0 +1,210 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.channels.ReadableByteChannel; + +import org.eclipse.jetty.http.MimeTypes.Type; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.resource.Resource; + + +/* ------------------------------------------------------------ */ +/** HttpContent created from a {@link Resource}. + *The HttpContent is used to server static content that is not + * cached. So fields and values are only generated as need be an not + * kept for reuse
+ */ +public class ResourceHttpContent implements HttpContent +{ + final Resource _resource; + final String _contentType; + final int _maxBuffer; + final String _etag; + + /* ------------------------------------------------------------ */ + public ResourceHttpContent(final Resource resource, final String contentType) + { + this(resource,contentType,-1,false); + } + + /* ------------------------------------------------------------ */ + public ResourceHttpContent(final Resource resource, final String contentType, int maxBuffer) + { + this(resource,contentType,maxBuffer,false); + } + + /* ------------------------------------------------------------ */ + public ResourceHttpContent(final Resource resource, final String contentType, boolean etag) + { + this(resource,contentType,-1,etag); + } + + /* ------------------------------------------------------------ */ + public ResourceHttpContent(final Resource resource, final String contentType, int maxBuffer, boolean etag) + { + _resource=resource; + _contentType=contentType; + _maxBuffer=maxBuffer; + _etag=etag?resource.getWeakETag():null; + } + + /* ------------------------------------------------------------ */ + @Override + public String getContentTypeValue() + { + return _contentType; + } + + /* ------------------------------------------------------------ */ + @Override + public HttpField getContentType() + { + return _contentType==null?null:new HttpField(HttpHeader.CONTENT_TYPE,_contentType); + } + + /* ------------------------------------------------------------ */ + @Override + public String getCharacterEncoding() + { + return _contentType==null?null:MimeTypes.getCharsetFromContentType(_contentType); + } + + /* ------------------------------------------------------------ */ + @Override + public Type getMimeType() + { + return _contentType==null?null:MimeTypes.CACHE.get(MimeTypes.getContentTypeWithoutCharset(_contentType)); + } + + /* ------------------------------------------------------------ */ + @Override + public HttpField getLastModified() + { + long lm = _resource.lastModified(); + return lm>=0?new HttpField(HttpHeader.LAST_MODIFIED,DateGenerator.formatDate(lm)):null; + } + + /* ------------------------------------------------------------ */ + @Override + public String getLastModifiedValue() + { + long lm = _resource.lastModified(); + return lm>=0?DateGenerator.formatDate(lm):null; + } + + /* ------------------------------------------------------------ */ + @Override + public ByteBuffer getDirectBuffer() + { + if (_resource.length()<=0 || _maxBuffer<_resource.length()) + return null; + try + { + return BufferUtil.toBuffer(_resource,true); + } + catch(IOException e) + { + throw new RuntimeException(e); + } + } + + /* ------------------------------------------------------------ */ + @Override + public HttpField getETag() + { + return _etag==null?null:new HttpField(HttpHeader.ETAG,_etag); + } + + /* ------------------------------------------------------------ */ + @Override + public String getETagValue() + { + return _etag; + } + + /* ------------------------------------------------------------ */ + @Override + public ByteBuffer getIndirectBuffer() + { + if (_resource.length()<=0 || _maxBuffer<_resource.length()) + return null; + try + { + return BufferUtil.toBuffer(_resource,false); + } + catch(IOException e) + { + throw new RuntimeException(e); + } + } + + /* ------------------------------------------------------------ */ + @Override + public HttpField getContentLength() + { + long l=_resource.length(); + return l==-1?null:new HttpField.LongValueHttpField(HttpHeader.CONTENT_LENGTH,_resource.length()); + } + + /* ------------------------------------------------------------ */ + @Override + public long getContentLengthValue() + { + return _resource.length(); + } + + /* ------------------------------------------------------------ */ + @Override + public InputStream getInputStream() throws IOException + { + return _resource.getInputStream(); + } + + /* ------------------------------------------------------------ */ + @Override + public ReadableByteChannel getReadableByteChannel() throws IOException + { + return _resource.getReadableByteChannel(); + } + + /* ------------------------------------------------------------ */ + @Override + public Resource getResource() + { + return _resource; + } + + /* ------------------------------------------------------------ */ + @Override + public void release() + { + _resource.close(); + } + + /* ------------------------------------------------------------ */ + @Override + public String toString() + { + return String.format("%s@%x{r=%s}",this.getClass().getSimpleName(),hashCode(),_resource); + } +} \ No newline at end of file diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceCache.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceCache.java index d08b1032efd..f0cc7418c92 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceCache.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceCache.java @@ -38,6 +38,7 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.http.PreEncodedHttpField; import org.eclipse.jetty.http.MimeTypes.Type; +import org.eclipse.jetty.http.ResourceHttpContent; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -53,7 +54,7 @@ public class ResourceCache { private static final Logger LOG = Log.getLogger(ResourceCache.class); - private final ConcurrentMappathInContext
, or a new entry
* if no matching entry was found. If the content exists but is not cachable,
- * then a {@link ResourceAsHttpContent} instance is return. If
+ * then a {@link ResourceHttpContent} instance is return. If
* the resource does not exist, then null is returned.
* @throws IOException Problem loading the resource
*/
@@ -177,7 +178,7 @@ public class ResourceCache
throws IOException
{
// Is the content in this cache?
- Content content =_cache.get(pathInContext);
+ CachedHttpContent content =_cache.get(pathInContext);
if (content!=null && (content).isValid())
return content;
@@ -215,7 +216,7 @@ public class ResourceCache
private HttpContent load(String pathInContext, Resource resource)
throws IOException
{
- Content content=null;
+ CachedHttpContent content=null;
if (resource==null || !resource.exists())
return null;
@@ -224,13 +225,13 @@ public class ResourceCache
if (!resource.isDirectory() && isCacheable(resource))
{
// Create the Content (to increment the cache sizes before adding the content
- content = new Content(pathInContext,resource);
+ content = new CachedHttpContent(pathInContext,resource);
// reduce the cache to an acceptable size.
shrinkCache();
// Add it to the cache.
- Content added = _cache.putIfAbsent(pathInContext,content);
+ CachedHttpContent added = _cache.putIfAbsent(pathInContext,content);
if (added!=null)
{
content.invalidate();
@@ -240,7 +241,7 @@ public class ResourceCache
return content;
}
- return new HttpContent.ResourceAsHttpContent(resource,_mimeTypes.getMimeByExtension(resource.toString()),getMaxCachedFileSize(),_etagSupported);
+ return new ResourceHttpContent(resource,_mimeTypes.getMimeByExtension(resource.toString()),getMaxCachedFileSize(),_etagSupported);
}
@@ -251,10 +252,10 @@ public class ResourceCache
while (_cache.size()>0 && (_cachedFiles.get()>_maxCachedFiles || _cachedSize.get()>_maxCacheSize))
{
// Scan the entire cache and generate an ordered list by last accessed time.
- SortedSet