103928aee4356845252ac6b662d5c72c29903813eJake Slack// 203928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 303928aee4356845252ac6b662d5c72c29903813eJake Slack// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 403928aee4356845252ac6b662d5c72c29903813eJake Slack// ------------------------------------------------------------------------ 503928aee4356845252ac6b662d5c72c29903813eJake Slack// All rights reserved. This program and the accompanying materials 603928aee4356845252ac6b662d5c72c29903813eJake Slack// are made available under the terms of the Eclipse Public License v1.0 703928aee4356845252ac6b662d5c72c29903813eJake Slack// and Apache License v2.0 which accompanies this distribution. 803928aee4356845252ac6b662d5c72c29903813eJake Slack// 903928aee4356845252ac6b662d5c72c29903813eJake Slack// The Eclipse Public License is available at 1003928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.eclipse.org/legal/epl-v10.html 1103928aee4356845252ac6b662d5c72c29903813eJake Slack// 1203928aee4356845252ac6b662d5c72c29903813eJake Slack// The Apache License v2.0 is available at 1303928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.opensource.org/licenses/apache2.0.php 1403928aee4356845252ac6b662d5c72c29903813eJake Slack// 1503928aee4356845252ac6b662d5c72c29903813eJake Slack// You may elect to redistribute this code under either of these licenses. 1603928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 1703928aee4356845252ac6b662d5c72c29903813eJake Slack// 1803928aee4356845252ac6b662d5c72c29903813eJake Slack 1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.server.handler; 2003928aee4356845252ac6b662d5c72c29903813eJake Slack 2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException; 2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.OutputStream; 2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.MalformedURLException; 2403928aee4356845252ac6b662d5c72c29903813eJake Slack 2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.ServletException; 2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.http.HttpServletRequest; 2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.http.HttpServletResponse; 2803928aee4356845252ac6b662d5c72c29903813eJake Slack 2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.HttpFields; 3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.HttpHeaders; 3103928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.HttpMethods; 3203928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.HttpStatus; 3303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.MimeTypes; 3403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.Buffer; 3503928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.ByteArrayBuffer; 3603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.WriterOutputStream; 3703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.AbstractHttpConnection; 3803928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.Dispatcher; 3903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.Request; 4003928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.Response; 4103928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.handler.ContextHandler.Context; 4203928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.URIUtil; 4303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log; 4403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger; 4503928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.resource.FileResource; 4603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.resource.Resource; 4703928aee4356845252ac6b662d5c72c29903813eJake Slack 4803928aee4356845252ac6b662d5c72c29903813eJake Slack 4903928aee4356845252ac6b662d5c72c29903813eJake Slack/* ------------------------------------------------------------ */ 5003928aee4356845252ac6b662d5c72c29903813eJake Slack/** Resource Handler. 5103928aee4356845252ac6b662d5c72c29903813eJake Slack * 5203928aee4356845252ac6b662d5c72c29903813eJake Slack * This handle will serve static content and handle If-Modified-Since headers. 5303928aee4356845252ac6b662d5c72c29903813eJake Slack * No caching is done. 5403928aee4356845252ac6b662d5c72c29903813eJake Slack * Requests for resources that do not exist are let pass (Eg no 404's). 5503928aee4356845252ac6b662d5c72c29903813eJake Slack * 5603928aee4356845252ac6b662d5c72c29903813eJake Slack * 5703928aee4356845252ac6b662d5c72c29903813eJake Slack * @org.apache.xbean.XBean 5803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 5903928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class ResourceHandler extends HandlerWrapper 6003928aee4356845252ac6b662d5c72c29903813eJake Slack{ 6103928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Logger LOG = Log.getLogger(ResourceHandler.class); 6203928aee4356845252ac6b662d5c72c29903813eJake Slack 6303928aee4356845252ac6b662d5c72c29903813eJake Slack ContextHandler _context; 6403928aee4356845252ac6b662d5c72c29903813eJake Slack Resource _baseResource; 6503928aee4356845252ac6b662d5c72c29903813eJake Slack Resource _defaultStylesheet; 6603928aee4356845252ac6b662d5c72c29903813eJake Slack Resource _stylesheet; 6703928aee4356845252ac6b662d5c72c29903813eJake Slack String[] _welcomeFiles={"index.html"}; 6803928aee4356845252ac6b662d5c72c29903813eJake Slack MimeTypes _mimeTypes = new MimeTypes(); 6903928aee4356845252ac6b662d5c72c29903813eJake Slack ByteArrayBuffer _cacheControl; 7003928aee4356845252ac6b662d5c72c29903813eJake Slack boolean _aliases; 7103928aee4356845252ac6b662d5c72c29903813eJake Slack boolean _directory; 7203928aee4356845252ac6b662d5c72c29903813eJake Slack boolean _etags; 7303928aee4356845252ac6b662d5c72c29903813eJake Slack 7403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 7503928aee4356845252ac6b662d5c72c29903813eJake Slack public ResourceHandler() 7603928aee4356845252ac6b662d5c72c29903813eJake Slack { 7703928aee4356845252ac6b662d5c72c29903813eJake Slack 7803928aee4356845252ac6b662d5c72c29903813eJake Slack } 7903928aee4356845252ac6b662d5c72c29903813eJake Slack 8003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 8103928aee4356845252ac6b662d5c72c29903813eJake Slack public MimeTypes getMimeTypes() 8203928aee4356845252ac6b662d5c72c29903813eJake Slack { 8303928aee4356845252ac6b662d5c72c29903813eJake Slack return _mimeTypes; 8403928aee4356845252ac6b662d5c72c29903813eJake Slack } 8503928aee4356845252ac6b662d5c72c29903813eJake Slack 8603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 8703928aee4356845252ac6b662d5c72c29903813eJake Slack public void setMimeTypes(MimeTypes mimeTypes) 8803928aee4356845252ac6b662d5c72c29903813eJake Slack { 8903928aee4356845252ac6b662d5c72c29903813eJake Slack _mimeTypes = mimeTypes; 9003928aee4356845252ac6b662d5c72c29903813eJake Slack } 9103928aee4356845252ac6b662d5c72c29903813eJake Slack 9203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 9303928aee4356845252ac6b662d5c72c29903813eJake Slack /** 9403928aee4356845252ac6b662d5c72c29903813eJake Slack * @return True if resource aliases are allowed. 9503928aee4356845252ac6b662d5c72c29903813eJake Slack */ 9603928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isAliases() 9703928aee4356845252ac6b662d5c72c29903813eJake Slack { 9803928aee4356845252ac6b662d5c72c29903813eJake Slack return _aliases; 9903928aee4356845252ac6b662d5c72c29903813eJake Slack } 10003928aee4356845252ac6b662d5c72c29903813eJake Slack 10103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 10203928aee4356845252ac6b662d5c72c29903813eJake Slack /** 10303928aee4356845252ac6b662d5c72c29903813eJake Slack * Set if resource aliases (eg symlink, 8.3 names, case insensitivity) are allowed. 10403928aee4356845252ac6b662d5c72c29903813eJake Slack * Allowing aliases can significantly increase security vulnerabilities. 10503928aee4356845252ac6b662d5c72c29903813eJake Slack * If this handler is deployed inside a ContextHandler, then the 10603928aee4356845252ac6b662d5c72c29903813eJake Slack * {@link ContextHandler#isAliases()} takes precedent. 10703928aee4356845252ac6b662d5c72c29903813eJake Slack * @param aliases True if aliases are supported. 10803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 10903928aee4356845252ac6b662d5c72c29903813eJake Slack public void setAliases(boolean aliases) 11003928aee4356845252ac6b662d5c72c29903813eJake Slack { 11103928aee4356845252ac6b662d5c72c29903813eJake Slack _aliases = aliases; 11203928aee4356845252ac6b662d5c72c29903813eJake Slack } 11303928aee4356845252ac6b662d5c72c29903813eJake Slack 11403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 11503928aee4356845252ac6b662d5c72c29903813eJake Slack /** Get the directory option. 11603928aee4356845252ac6b662d5c72c29903813eJake Slack * @return true if directories are listed. 11703928aee4356845252ac6b662d5c72c29903813eJake Slack */ 11803928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isDirectoriesListed() 11903928aee4356845252ac6b662d5c72c29903813eJake Slack { 12003928aee4356845252ac6b662d5c72c29903813eJake Slack return _directory; 12103928aee4356845252ac6b662d5c72c29903813eJake Slack } 12203928aee4356845252ac6b662d5c72c29903813eJake Slack 12303928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 12403928aee4356845252ac6b662d5c72c29903813eJake Slack /** Set the directory. 12503928aee4356845252ac6b662d5c72c29903813eJake Slack * @param directory true if directories are listed. 12603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 12703928aee4356845252ac6b662d5c72c29903813eJake Slack public void setDirectoriesListed(boolean directory) 12803928aee4356845252ac6b662d5c72c29903813eJake Slack { 12903928aee4356845252ac6b662d5c72c29903813eJake Slack _directory = directory; 13003928aee4356845252ac6b662d5c72c29903813eJake Slack } 13103928aee4356845252ac6b662d5c72c29903813eJake Slack 13203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 13303928aee4356845252ac6b662d5c72c29903813eJake Slack /** 13403928aee4356845252ac6b662d5c72c29903813eJake Slack * @return True if ETag processing is done 13503928aee4356845252ac6b662d5c72c29903813eJake Slack */ 13603928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isEtags() 13703928aee4356845252ac6b662d5c72c29903813eJake Slack { 13803928aee4356845252ac6b662d5c72c29903813eJake Slack return _etags; 13903928aee4356845252ac6b662d5c72c29903813eJake Slack } 14003928aee4356845252ac6b662d5c72c29903813eJake Slack 14103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 14203928aee4356845252ac6b662d5c72c29903813eJake Slack /** 14303928aee4356845252ac6b662d5c72c29903813eJake Slack * @param etags True if ETag processing is done 14403928aee4356845252ac6b662d5c72c29903813eJake Slack */ 14503928aee4356845252ac6b662d5c72c29903813eJake Slack public void setEtags(boolean etags) 14603928aee4356845252ac6b662d5c72c29903813eJake Slack { 14703928aee4356845252ac6b662d5c72c29903813eJake Slack _etags = etags; 14803928aee4356845252ac6b662d5c72c29903813eJake Slack } 14903928aee4356845252ac6b662d5c72c29903813eJake Slack 15003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 15103928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 15203928aee4356845252ac6b662d5c72c29903813eJake Slack public void doStart() 15303928aee4356845252ac6b662d5c72c29903813eJake Slack throws Exception 15403928aee4356845252ac6b662d5c72c29903813eJake Slack { 15503928aee4356845252ac6b662d5c72c29903813eJake Slack Context scontext = ContextHandler.getCurrentContext(); 15603928aee4356845252ac6b662d5c72c29903813eJake Slack _context = (scontext==null?null:scontext.getContextHandler()); 15703928aee4356845252ac6b662d5c72c29903813eJake Slack 15803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_context!=null) 15903928aee4356845252ac6b662d5c72c29903813eJake Slack _aliases=_context.isAliases(); 16003928aee4356845252ac6b662d5c72c29903813eJake Slack 16103928aee4356845252ac6b662d5c72c29903813eJake Slack if (!_aliases && !FileResource.getCheckAliases()) 16203928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalStateException("Alias checking disabled"); 16303928aee4356845252ac6b662d5c72c29903813eJake Slack 16403928aee4356845252ac6b662d5c72c29903813eJake Slack super.doStart(); 16503928aee4356845252ac6b662d5c72c29903813eJake Slack } 16603928aee4356845252ac6b662d5c72c29903813eJake Slack 16703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 16803928aee4356845252ac6b662d5c72c29903813eJake Slack /** 16903928aee4356845252ac6b662d5c72c29903813eJake Slack * @return Returns the resourceBase. 17003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 17103928aee4356845252ac6b662d5c72c29903813eJake Slack public Resource getBaseResource() 17203928aee4356845252ac6b662d5c72c29903813eJake Slack { 17303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_baseResource==null) 17403928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 17503928aee4356845252ac6b662d5c72c29903813eJake Slack return _baseResource; 17603928aee4356845252ac6b662d5c72c29903813eJake Slack } 17703928aee4356845252ac6b662d5c72c29903813eJake Slack 17803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 17903928aee4356845252ac6b662d5c72c29903813eJake Slack /** 18003928aee4356845252ac6b662d5c72c29903813eJake Slack * @return Returns the base resource as a string. 18103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 18203928aee4356845252ac6b662d5c72c29903813eJake Slack public String getResourceBase() 18303928aee4356845252ac6b662d5c72c29903813eJake Slack { 18403928aee4356845252ac6b662d5c72c29903813eJake Slack if (_baseResource==null) 18503928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 18603928aee4356845252ac6b662d5c72c29903813eJake Slack return _baseResource.toString(); 18703928aee4356845252ac6b662d5c72c29903813eJake Slack } 18803928aee4356845252ac6b662d5c72c29903813eJake Slack 18903928aee4356845252ac6b662d5c72c29903813eJake Slack 19003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 19103928aee4356845252ac6b662d5c72c29903813eJake Slack /** 19203928aee4356845252ac6b662d5c72c29903813eJake Slack * @param base The resourceBase to set. 19303928aee4356845252ac6b662d5c72c29903813eJake Slack */ 19403928aee4356845252ac6b662d5c72c29903813eJake Slack public void setBaseResource(Resource base) 19503928aee4356845252ac6b662d5c72c29903813eJake Slack { 19603928aee4356845252ac6b662d5c72c29903813eJake Slack _baseResource=base; 19703928aee4356845252ac6b662d5c72c29903813eJake Slack } 19803928aee4356845252ac6b662d5c72c29903813eJake Slack 19903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 20003928aee4356845252ac6b662d5c72c29903813eJake Slack /** 20103928aee4356845252ac6b662d5c72c29903813eJake Slack * @param resourceBase The base resource as a string. 20203928aee4356845252ac6b662d5c72c29903813eJake Slack */ 20303928aee4356845252ac6b662d5c72c29903813eJake Slack public void setResourceBase(String resourceBase) 20403928aee4356845252ac6b662d5c72c29903813eJake Slack { 20503928aee4356845252ac6b662d5c72c29903813eJake Slack try 20603928aee4356845252ac6b662d5c72c29903813eJake Slack { 20703928aee4356845252ac6b662d5c72c29903813eJake Slack setBaseResource(Resource.newResource(resourceBase)); 20803928aee4356845252ac6b662d5c72c29903813eJake Slack } 20903928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 21003928aee4356845252ac6b662d5c72c29903813eJake Slack { 21103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e.toString()); 21203928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug(e); 21303928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalArgumentException(resourceBase); 21403928aee4356845252ac6b662d5c72c29903813eJake Slack } 21503928aee4356845252ac6b662d5c72c29903813eJake Slack } 21603928aee4356845252ac6b662d5c72c29903813eJake Slack 21703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 21803928aee4356845252ac6b662d5c72c29903813eJake Slack /** 21903928aee4356845252ac6b662d5c72c29903813eJake Slack * @return Returns the stylesheet as a Resource. 22003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 22103928aee4356845252ac6b662d5c72c29903813eJake Slack public Resource getStylesheet() 22203928aee4356845252ac6b662d5c72c29903813eJake Slack { 22303928aee4356845252ac6b662d5c72c29903813eJake Slack if(_stylesheet != null) 22403928aee4356845252ac6b662d5c72c29903813eJake Slack { 22503928aee4356845252ac6b662d5c72c29903813eJake Slack return _stylesheet; 22603928aee4356845252ac6b662d5c72c29903813eJake Slack } 22703928aee4356845252ac6b662d5c72c29903813eJake Slack else 22803928aee4356845252ac6b662d5c72c29903813eJake Slack { 22903928aee4356845252ac6b662d5c72c29903813eJake Slack if(_defaultStylesheet == null) 23003928aee4356845252ac6b662d5c72c29903813eJake Slack { 23103928aee4356845252ac6b662d5c72c29903813eJake Slack try 23203928aee4356845252ac6b662d5c72c29903813eJake Slack { 23303928aee4356845252ac6b662d5c72c29903813eJake Slack _defaultStylesheet = Resource.newResource(this.getClass().getResource("/jetty-dir.css")); 23403928aee4356845252ac6b662d5c72c29903813eJake Slack } 23503928aee4356845252ac6b662d5c72c29903813eJake Slack catch(IOException e) 23603928aee4356845252ac6b662d5c72c29903813eJake Slack { 23703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e.toString()); 23803928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug(e); 23903928aee4356845252ac6b662d5c72c29903813eJake Slack } 24003928aee4356845252ac6b662d5c72c29903813eJake Slack } 24103928aee4356845252ac6b662d5c72c29903813eJake Slack return _defaultStylesheet; 24203928aee4356845252ac6b662d5c72c29903813eJake Slack } 24303928aee4356845252ac6b662d5c72c29903813eJake Slack } 24403928aee4356845252ac6b662d5c72c29903813eJake Slack 24503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 24603928aee4356845252ac6b662d5c72c29903813eJake Slack /** 24703928aee4356845252ac6b662d5c72c29903813eJake Slack * @param stylesheet The location of the stylesheet to be used as a String. 24803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 24903928aee4356845252ac6b662d5c72c29903813eJake Slack public void setStylesheet(String stylesheet) 25003928aee4356845252ac6b662d5c72c29903813eJake Slack { 25103928aee4356845252ac6b662d5c72c29903813eJake Slack try 25203928aee4356845252ac6b662d5c72c29903813eJake Slack { 25303928aee4356845252ac6b662d5c72c29903813eJake Slack _stylesheet = Resource.newResource(stylesheet); 25403928aee4356845252ac6b662d5c72c29903813eJake Slack if(!_stylesheet.exists()) 25503928aee4356845252ac6b662d5c72c29903813eJake Slack { 25603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("unable to find custom stylesheet: " + stylesheet); 25703928aee4356845252ac6b662d5c72c29903813eJake Slack _stylesheet = null; 25803928aee4356845252ac6b662d5c72c29903813eJake Slack } 25903928aee4356845252ac6b662d5c72c29903813eJake Slack } 26003928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) 26103928aee4356845252ac6b662d5c72c29903813eJake Slack { 26203928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e.toString()); 26303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug(e); 26403928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalArgumentException(stylesheet.toString()); 26503928aee4356845252ac6b662d5c72c29903813eJake Slack } 26603928aee4356845252ac6b662d5c72c29903813eJake Slack } 26703928aee4356845252ac6b662d5c72c29903813eJake Slack 26803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 26903928aee4356845252ac6b662d5c72c29903813eJake Slack /** 27003928aee4356845252ac6b662d5c72c29903813eJake Slack * @return the cacheControl header to set on all static content. 27103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 27203928aee4356845252ac6b662d5c72c29903813eJake Slack public String getCacheControl() 27303928aee4356845252ac6b662d5c72c29903813eJake Slack { 27403928aee4356845252ac6b662d5c72c29903813eJake Slack return _cacheControl.toString(); 27503928aee4356845252ac6b662d5c72c29903813eJake Slack } 27603928aee4356845252ac6b662d5c72c29903813eJake Slack 27703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 27803928aee4356845252ac6b662d5c72c29903813eJake Slack /** 27903928aee4356845252ac6b662d5c72c29903813eJake Slack * @param cacheControl the cacheControl header to set on all static content. 28003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 28103928aee4356845252ac6b662d5c72c29903813eJake Slack public void setCacheControl(String cacheControl) 28203928aee4356845252ac6b662d5c72c29903813eJake Slack { 28303928aee4356845252ac6b662d5c72c29903813eJake Slack _cacheControl=cacheControl==null?null:new ByteArrayBuffer(cacheControl); 28403928aee4356845252ac6b662d5c72c29903813eJake Slack } 28503928aee4356845252ac6b662d5c72c29903813eJake Slack 28603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 28703928aee4356845252ac6b662d5c72c29903813eJake Slack /* 28803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 28903928aee4356845252ac6b662d5c72c29903813eJake Slack public Resource getResource(String path) throws MalformedURLException 29003928aee4356845252ac6b662d5c72c29903813eJake Slack { 29103928aee4356845252ac6b662d5c72c29903813eJake Slack if (path==null || !path.startsWith("/")) 29203928aee4356845252ac6b662d5c72c29903813eJake Slack throw new MalformedURLException(path); 29303928aee4356845252ac6b662d5c72c29903813eJake Slack 29403928aee4356845252ac6b662d5c72c29903813eJake Slack Resource base = _baseResource; 29503928aee4356845252ac6b662d5c72c29903813eJake Slack if (base==null) 29603928aee4356845252ac6b662d5c72c29903813eJake Slack { 29703928aee4356845252ac6b662d5c72c29903813eJake Slack if (_context==null) 29803928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 29903928aee4356845252ac6b662d5c72c29903813eJake Slack base=_context.getBaseResource(); 30003928aee4356845252ac6b662d5c72c29903813eJake Slack if (base==null) 30103928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 30203928aee4356845252ac6b662d5c72c29903813eJake Slack } 30303928aee4356845252ac6b662d5c72c29903813eJake Slack 30403928aee4356845252ac6b662d5c72c29903813eJake Slack try 30503928aee4356845252ac6b662d5c72c29903813eJake Slack { 30603928aee4356845252ac6b662d5c72c29903813eJake Slack path=URIUtil.canonicalPath(path); 30703928aee4356845252ac6b662d5c72c29903813eJake Slack return base.addPath(path); 30803928aee4356845252ac6b662d5c72c29903813eJake Slack } 30903928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) 31003928aee4356845252ac6b662d5c72c29903813eJake Slack { 31103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 31203928aee4356845252ac6b662d5c72c29903813eJake Slack } 31303928aee4356845252ac6b662d5c72c29903813eJake Slack 31403928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 31503928aee4356845252ac6b662d5c72c29903813eJake Slack } 31603928aee4356845252ac6b662d5c72c29903813eJake Slack 31703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 31803928aee4356845252ac6b662d5c72c29903813eJake Slack protected Resource getResource(HttpServletRequest request) throws MalformedURLException 31903928aee4356845252ac6b662d5c72c29903813eJake Slack { 32003928aee4356845252ac6b662d5c72c29903813eJake Slack String servletPath; 32103928aee4356845252ac6b662d5c72c29903813eJake Slack String pathInfo; 32203928aee4356845252ac6b662d5c72c29903813eJake Slack Boolean included = request.getAttribute(Dispatcher.INCLUDE_REQUEST_URI) != null; 32303928aee4356845252ac6b662d5c72c29903813eJake Slack if (included != null && included.booleanValue()) 32403928aee4356845252ac6b662d5c72c29903813eJake Slack { 32503928aee4356845252ac6b662d5c72c29903813eJake Slack servletPath = (String)request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH); 32603928aee4356845252ac6b662d5c72c29903813eJake Slack pathInfo = (String)request.getAttribute(Dispatcher.INCLUDE_PATH_INFO); 32703928aee4356845252ac6b662d5c72c29903813eJake Slack 32803928aee4356845252ac6b662d5c72c29903813eJake Slack if (servletPath == null && pathInfo == null) 32903928aee4356845252ac6b662d5c72c29903813eJake Slack { 33003928aee4356845252ac6b662d5c72c29903813eJake Slack servletPath = request.getServletPath(); 33103928aee4356845252ac6b662d5c72c29903813eJake Slack pathInfo = request.getPathInfo(); 33203928aee4356845252ac6b662d5c72c29903813eJake Slack } 33303928aee4356845252ac6b662d5c72c29903813eJake Slack } 33403928aee4356845252ac6b662d5c72c29903813eJake Slack else 33503928aee4356845252ac6b662d5c72c29903813eJake Slack { 33603928aee4356845252ac6b662d5c72c29903813eJake Slack servletPath = request.getServletPath(); 33703928aee4356845252ac6b662d5c72c29903813eJake Slack pathInfo = request.getPathInfo(); 33803928aee4356845252ac6b662d5c72c29903813eJake Slack } 33903928aee4356845252ac6b662d5c72c29903813eJake Slack 34003928aee4356845252ac6b662d5c72c29903813eJake Slack String pathInContext=URIUtil.addPaths(servletPath,pathInfo); 34103928aee4356845252ac6b662d5c72c29903813eJake Slack return getResource(pathInContext); 34203928aee4356845252ac6b662d5c72c29903813eJake Slack } 34303928aee4356845252ac6b662d5c72c29903813eJake Slack 34403928aee4356845252ac6b662d5c72c29903813eJake Slack 34503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 34603928aee4356845252ac6b662d5c72c29903813eJake Slack public String[] getWelcomeFiles() 34703928aee4356845252ac6b662d5c72c29903813eJake Slack { 34803928aee4356845252ac6b662d5c72c29903813eJake Slack return _welcomeFiles; 34903928aee4356845252ac6b662d5c72c29903813eJake Slack } 35003928aee4356845252ac6b662d5c72c29903813eJake Slack 35103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 35203928aee4356845252ac6b662d5c72c29903813eJake Slack public void setWelcomeFiles(String[] welcomeFiles) 35303928aee4356845252ac6b662d5c72c29903813eJake Slack { 35403928aee4356845252ac6b662d5c72c29903813eJake Slack _welcomeFiles=welcomeFiles; 35503928aee4356845252ac6b662d5c72c29903813eJake Slack } 35603928aee4356845252ac6b662d5c72c29903813eJake Slack 35703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 35803928aee4356845252ac6b662d5c72c29903813eJake Slack protected Resource getWelcome(Resource directory) throws MalformedURLException, IOException 35903928aee4356845252ac6b662d5c72c29903813eJake Slack { 36003928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i=0;i<_welcomeFiles.length;i++) 36103928aee4356845252ac6b662d5c72c29903813eJake Slack { 36203928aee4356845252ac6b662d5c72c29903813eJake Slack Resource welcome=directory.addPath(_welcomeFiles[i]); 36303928aee4356845252ac6b662d5c72c29903813eJake Slack if (welcome.exists() && !welcome.isDirectory()) 36403928aee4356845252ac6b662d5c72c29903813eJake Slack return welcome; 36503928aee4356845252ac6b662d5c72c29903813eJake Slack } 36603928aee4356845252ac6b662d5c72c29903813eJake Slack 36703928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 36803928aee4356845252ac6b662d5c72c29903813eJake Slack } 36903928aee4356845252ac6b662d5c72c29903813eJake Slack 37003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 37103928aee4356845252ac6b662d5c72c29903813eJake Slack /* 37203928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) 37303928aee4356845252ac6b662d5c72c29903813eJake Slack */ 37403928aee4356845252ac6b662d5c72c29903813eJake Slack public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException 37503928aee4356845252ac6b662d5c72c29903813eJake Slack { 37603928aee4356845252ac6b662d5c72c29903813eJake Slack if (baseRequest.isHandled()) 37703928aee4356845252ac6b662d5c72c29903813eJake Slack return; 37803928aee4356845252ac6b662d5c72c29903813eJake Slack 37903928aee4356845252ac6b662d5c72c29903813eJake Slack boolean skipContentBody = false; 38003928aee4356845252ac6b662d5c72c29903813eJake Slack 38103928aee4356845252ac6b662d5c72c29903813eJake Slack if(!HttpMethods.GET.equals(request.getMethod())) 38203928aee4356845252ac6b662d5c72c29903813eJake Slack { 38303928aee4356845252ac6b662d5c72c29903813eJake Slack if(!HttpMethods.HEAD.equals(request.getMethod())) 38403928aee4356845252ac6b662d5c72c29903813eJake Slack { 38503928aee4356845252ac6b662d5c72c29903813eJake Slack //try another handler 38603928aee4356845252ac6b662d5c72c29903813eJake Slack super.handle(target, baseRequest, request, response); 38703928aee4356845252ac6b662d5c72c29903813eJake Slack return; 38803928aee4356845252ac6b662d5c72c29903813eJake Slack } 38903928aee4356845252ac6b662d5c72c29903813eJake Slack skipContentBody = true; 39003928aee4356845252ac6b662d5c72c29903813eJake Slack } 39103928aee4356845252ac6b662d5c72c29903813eJake Slack 39203928aee4356845252ac6b662d5c72c29903813eJake Slack Resource resource = getResource(request); 39303928aee4356845252ac6b662d5c72c29903813eJake Slack 39403928aee4356845252ac6b662d5c72c29903813eJake Slack if (resource==null || !resource.exists()) 39503928aee4356845252ac6b662d5c72c29903813eJake Slack { 39603928aee4356845252ac6b662d5c72c29903813eJake Slack if (target.endsWith("/jetty-dir.css")) 39703928aee4356845252ac6b662d5c72c29903813eJake Slack { 39803928aee4356845252ac6b662d5c72c29903813eJake Slack resource = getStylesheet(); 39903928aee4356845252ac6b662d5c72c29903813eJake Slack if (resource==null) 40003928aee4356845252ac6b662d5c72c29903813eJake Slack return; 40103928aee4356845252ac6b662d5c72c29903813eJake Slack response.setContentType("text/css"); 40203928aee4356845252ac6b662d5c72c29903813eJake Slack } 40303928aee4356845252ac6b662d5c72c29903813eJake Slack else 40403928aee4356845252ac6b662d5c72c29903813eJake Slack { 40503928aee4356845252ac6b662d5c72c29903813eJake Slack //no resource - try other handlers 40603928aee4356845252ac6b662d5c72c29903813eJake Slack super.handle(target, baseRequest, request, response); 40703928aee4356845252ac6b662d5c72c29903813eJake Slack return; 40803928aee4356845252ac6b662d5c72c29903813eJake Slack } 40903928aee4356845252ac6b662d5c72c29903813eJake Slack } 41003928aee4356845252ac6b662d5c72c29903813eJake Slack 41103928aee4356845252ac6b662d5c72c29903813eJake Slack if (!_aliases && resource.getAlias()!=null) 41203928aee4356845252ac6b662d5c72c29903813eJake Slack { 41303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.info(resource+" aliased to "+resource.getAlias()); 41403928aee4356845252ac6b662d5c72c29903813eJake Slack return; 41503928aee4356845252ac6b662d5c72c29903813eJake Slack } 41603928aee4356845252ac6b662d5c72c29903813eJake Slack 41703928aee4356845252ac6b662d5c72c29903813eJake Slack // We are going to serve something 41803928aee4356845252ac6b662d5c72c29903813eJake Slack baseRequest.setHandled(true); 41903928aee4356845252ac6b662d5c72c29903813eJake Slack 42003928aee4356845252ac6b662d5c72c29903813eJake Slack if (resource.isDirectory()) 42103928aee4356845252ac6b662d5c72c29903813eJake Slack { 42203928aee4356845252ac6b662d5c72c29903813eJake Slack if (!request.getPathInfo().endsWith(URIUtil.SLASH)) 42303928aee4356845252ac6b662d5c72c29903813eJake Slack { 42403928aee4356845252ac6b662d5c72c29903813eJake Slack response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH))); 42503928aee4356845252ac6b662d5c72c29903813eJake Slack return; 42603928aee4356845252ac6b662d5c72c29903813eJake Slack } 42703928aee4356845252ac6b662d5c72c29903813eJake Slack 42803928aee4356845252ac6b662d5c72c29903813eJake Slack Resource welcome=getWelcome(resource); 42903928aee4356845252ac6b662d5c72c29903813eJake Slack if (welcome!=null && welcome.exists()) 43003928aee4356845252ac6b662d5c72c29903813eJake Slack resource=welcome; 43103928aee4356845252ac6b662d5c72c29903813eJake Slack else 43203928aee4356845252ac6b662d5c72c29903813eJake Slack { 43303928aee4356845252ac6b662d5c72c29903813eJake Slack doDirectory(request,response,resource); 43403928aee4356845252ac6b662d5c72c29903813eJake Slack baseRequest.setHandled(true); 43503928aee4356845252ac6b662d5c72c29903813eJake Slack return; 43603928aee4356845252ac6b662d5c72c29903813eJake Slack } 43703928aee4356845252ac6b662d5c72c29903813eJake Slack } 43803928aee4356845252ac6b662d5c72c29903813eJake Slack 43903928aee4356845252ac6b662d5c72c29903813eJake Slack // set some headers 44003928aee4356845252ac6b662d5c72c29903813eJake Slack long last_modified=resource.lastModified(); 44103928aee4356845252ac6b662d5c72c29903813eJake Slack String etag=null; 44203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_etags) 44303928aee4356845252ac6b662d5c72c29903813eJake Slack { 44403928aee4356845252ac6b662d5c72c29903813eJake Slack // simple handling of only a single etag 44503928aee4356845252ac6b662d5c72c29903813eJake Slack String ifnm = request.getHeader(HttpHeaders.IF_NONE_MATCH); 44603928aee4356845252ac6b662d5c72c29903813eJake Slack etag=resource.getWeakETag(); 44703928aee4356845252ac6b662d5c72c29903813eJake Slack if (ifnm!=null && resource!=null && ifnm.equals(etag)) 44803928aee4356845252ac6b662d5c72c29903813eJake Slack { 44903928aee4356845252ac6b662d5c72c29903813eJake Slack response.setStatus(HttpStatus.NOT_MODIFIED_304); 45003928aee4356845252ac6b662d5c72c29903813eJake Slack baseRequest.getResponse().getHttpFields().put(HttpHeaders.ETAG_BUFFER,etag); 45103928aee4356845252ac6b662d5c72c29903813eJake Slack return; 45203928aee4356845252ac6b662d5c72c29903813eJake Slack } 45303928aee4356845252ac6b662d5c72c29903813eJake Slack } 45403928aee4356845252ac6b662d5c72c29903813eJake Slack 45503928aee4356845252ac6b662d5c72c29903813eJake Slack 45603928aee4356845252ac6b662d5c72c29903813eJake Slack if (last_modified>0) 45703928aee4356845252ac6b662d5c72c29903813eJake Slack { 45803928aee4356845252ac6b662d5c72c29903813eJake Slack long if_modified=request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE); 45903928aee4356845252ac6b662d5c72c29903813eJake Slack if (if_modified>0 && last_modified/1000<=if_modified/1000) 46003928aee4356845252ac6b662d5c72c29903813eJake Slack { 46103928aee4356845252ac6b662d5c72c29903813eJake Slack response.setStatus(HttpStatus.NOT_MODIFIED_304); 46203928aee4356845252ac6b662d5c72c29903813eJake Slack return; 46303928aee4356845252ac6b662d5c72c29903813eJake Slack } 46403928aee4356845252ac6b662d5c72c29903813eJake Slack } 46503928aee4356845252ac6b662d5c72c29903813eJake Slack 46603928aee4356845252ac6b662d5c72c29903813eJake Slack Buffer mime=_mimeTypes.getMimeByExtension(resource.toString()); 46703928aee4356845252ac6b662d5c72c29903813eJake Slack if (mime==null) 46803928aee4356845252ac6b662d5c72c29903813eJake Slack mime=_mimeTypes.getMimeByExtension(request.getPathInfo()); 46903928aee4356845252ac6b662d5c72c29903813eJake Slack 47003928aee4356845252ac6b662d5c72c29903813eJake Slack // set the headers 47103928aee4356845252ac6b662d5c72c29903813eJake Slack doResponseHeaders(response,resource,mime!=null?mime.toString():null); 47203928aee4356845252ac6b662d5c72c29903813eJake Slack response.setDateHeader(HttpHeaders.LAST_MODIFIED,last_modified); 47303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_etags) 47403928aee4356845252ac6b662d5c72c29903813eJake Slack baseRequest.getResponse().getHttpFields().put(HttpHeaders.ETAG_BUFFER,etag); 47503928aee4356845252ac6b662d5c72c29903813eJake Slack 47603928aee4356845252ac6b662d5c72c29903813eJake Slack if(skipContentBody) 47703928aee4356845252ac6b662d5c72c29903813eJake Slack return; 47803928aee4356845252ac6b662d5c72c29903813eJake Slack // Send the content 47903928aee4356845252ac6b662d5c72c29903813eJake Slack OutputStream out =null; 48003928aee4356845252ac6b662d5c72c29903813eJake Slack try {out = response.getOutputStream();} 48103928aee4356845252ac6b662d5c72c29903813eJake Slack catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());} 48203928aee4356845252ac6b662d5c72c29903813eJake Slack 48303928aee4356845252ac6b662d5c72c29903813eJake Slack // See if a short direct method can be used? 48403928aee4356845252ac6b662d5c72c29903813eJake Slack if (out instanceof AbstractHttpConnection.Output) 48503928aee4356845252ac6b662d5c72c29903813eJake Slack { 48603928aee4356845252ac6b662d5c72c29903813eJake Slack // TODO file mapped buffers 48703928aee4356845252ac6b662d5c72c29903813eJake Slack ((AbstractHttpConnection.Output)out).sendContent(resource.getInputStream()); 48803928aee4356845252ac6b662d5c72c29903813eJake Slack } 48903928aee4356845252ac6b662d5c72c29903813eJake Slack else 49003928aee4356845252ac6b662d5c72c29903813eJake Slack { 49103928aee4356845252ac6b662d5c72c29903813eJake Slack // Write content normally 49203928aee4356845252ac6b662d5c72c29903813eJake Slack resource.writeTo(out,0,resource.length()); 49303928aee4356845252ac6b662d5c72c29903813eJake Slack } 49403928aee4356845252ac6b662d5c72c29903813eJake Slack } 49503928aee4356845252ac6b662d5c72c29903813eJake Slack 49603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 49703928aee4356845252ac6b662d5c72c29903813eJake Slack protected void doDirectory(HttpServletRequest request,HttpServletResponse response, Resource resource) 49803928aee4356845252ac6b662d5c72c29903813eJake Slack throws IOException 49903928aee4356845252ac6b662d5c72c29903813eJake Slack { 50003928aee4356845252ac6b662d5c72c29903813eJake Slack if (_directory) 50103928aee4356845252ac6b662d5c72c29903813eJake Slack { 50203928aee4356845252ac6b662d5c72c29903813eJake Slack String listing = resource.getListHTML(request.getRequestURI(),request.getPathInfo().lastIndexOf("/") > 0); 50303928aee4356845252ac6b662d5c72c29903813eJake Slack response.setContentType("text/html; charset=UTF-8"); 50403928aee4356845252ac6b662d5c72c29903813eJake Slack response.getWriter().println(listing); 50503928aee4356845252ac6b662d5c72c29903813eJake Slack } 50603928aee4356845252ac6b662d5c72c29903813eJake Slack else 50703928aee4356845252ac6b662d5c72c29903813eJake Slack response.sendError(HttpStatus.FORBIDDEN_403); 50803928aee4356845252ac6b662d5c72c29903813eJake Slack } 50903928aee4356845252ac6b662d5c72c29903813eJake Slack 51003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 51103928aee4356845252ac6b662d5c72c29903813eJake Slack /** Set the response headers. 51203928aee4356845252ac6b662d5c72c29903813eJake Slack * This method is called to set the response headers such as content type and content length. 51303928aee4356845252ac6b662d5c72c29903813eJake Slack * May be extended to add additional headers. 51403928aee4356845252ac6b662d5c72c29903813eJake Slack * @param response 51503928aee4356845252ac6b662d5c72c29903813eJake Slack * @param resource 51603928aee4356845252ac6b662d5c72c29903813eJake Slack * @param mimeType 51703928aee4356845252ac6b662d5c72c29903813eJake Slack */ 51803928aee4356845252ac6b662d5c72c29903813eJake Slack protected void doResponseHeaders(HttpServletResponse response, Resource resource, String mimeType) 51903928aee4356845252ac6b662d5c72c29903813eJake Slack { 52003928aee4356845252ac6b662d5c72c29903813eJake Slack if (mimeType!=null) 52103928aee4356845252ac6b662d5c72c29903813eJake Slack response.setContentType(mimeType); 52203928aee4356845252ac6b662d5c72c29903813eJake Slack 52303928aee4356845252ac6b662d5c72c29903813eJake Slack long length=resource.length(); 52403928aee4356845252ac6b662d5c72c29903813eJake Slack 52503928aee4356845252ac6b662d5c72c29903813eJake Slack if (response instanceof Response) 52603928aee4356845252ac6b662d5c72c29903813eJake Slack { 52703928aee4356845252ac6b662d5c72c29903813eJake Slack HttpFields fields = ((Response)response).getHttpFields(); 52803928aee4356845252ac6b662d5c72c29903813eJake Slack 52903928aee4356845252ac6b662d5c72c29903813eJake Slack if (length>0) 53003928aee4356845252ac6b662d5c72c29903813eJake Slack fields.putLongField(HttpHeaders.CONTENT_LENGTH_BUFFER,length); 53103928aee4356845252ac6b662d5c72c29903813eJake Slack 53203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_cacheControl!=null) 53303928aee4356845252ac6b662d5c72c29903813eJake Slack fields.put(HttpHeaders.CACHE_CONTROL_BUFFER,_cacheControl); 53403928aee4356845252ac6b662d5c72c29903813eJake Slack } 53503928aee4356845252ac6b662d5c72c29903813eJake Slack else 53603928aee4356845252ac6b662d5c72c29903813eJake Slack { 53703928aee4356845252ac6b662d5c72c29903813eJake Slack if (length>0) 53803928aee4356845252ac6b662d5c72c29903813eJake Slack response.setHeader(HttpHeaders.CONTENT_LENGTH,Long.toString(length)); 53903928aee4356845252ac6b662d5c72c29903813eJake Slack 54003928aee4356845252ac6b662d5c72c29903813eJake Slack if (_cacheControl!=null) 54103928aee4356845252ac6b662d5c72c29903813eJake Slack response.setHeader(HttpHeaders.CACHE_CONTROL,_cacheControl.toString()); 54203928aee4356845252ac6b662d5c72c29903813eJake Slack } 54303928aee4356845252ac6b662d5c72c29903813eJake Slack 54403928aee4356845252ac6b662d5c72c29903813eJake Slack } 54503928aee4356845252ac6b662d5c72c29903813eJake Slack} 546