Mercurial Hosting > luan
comparison src/org/eclipse/jetty/server/handler/ResourceHandler.java @ 805:fc3e366caa51
add jetty-dir.css
| author | Franklin Schmidt <fschmidt@gmail.com> |
|---|---|
| date | Wed, 07 Sep 2016 22:46:38 -0600 |
| parents | 3428c60d7cfc |
| children | 8e9db0bbf4f9 |
comparison
equal
deleted
inserted
replaced
| 804:9f5ba30722bb | 805:fc3e366caa51 |
|---|---|
| 56 * | 56 * |
| 57 * @org.apache.xbean.XBean | 57 * @org.apache.xbean.XBean |
| 58 */ | 58 */ |
| 59 public class ResourceHandler extends HandlerWrapper | 59 public class ResourceHandler extends HandlerWrapper |
| 60 { | 60 { |
| 61 private static final Logger LOG = Log.getLogger(ResourceHandler.class); | 61 private static final Logger LOG = Log.getLogger(ResourceHandler.class); |
| 62 | 62 |
| 63 ContextHandler _context; | 63 ContextHandler _context; |
| 64 Resource _baseResource; | 64 Resource _baseResource; |
| 65 Resource _defaultStylesheet; | 65 Resource _defaultStylesheet; |
| 66 Resource _stylesheet; | 66 Resource _stylesheet; |
| 67 String[] _welcomeFiles={"index.html"}; | 67 String[] _welcomeFiles={"index.html"}; |
| 68 MimeTypes _mimeTypes = new MimeTypes(); | 68 MimeTypes _mimeTypes = new MimeTypes(); |
| 69 ByteArrayBuffer _cacheControl; | 69 ByteArrayBuffer _cacheControl; |
| 70 boolean _aliases; | 70 boolean _aliases; |
| 71 boolean _directory; | 71 boolean _directory; |
| 72 boolean _etags; | 72 boolean _etags; |
| 73 | 73 |
| 74 /* ------------------------------------------------------------ */ | 74 /* ------------------------------------------------------------ */ |
| 75 public ResourceHandler() | 75 public ResourceHandler() |
| 76 { | 76 { |
| 77 | 77 |
| 78 } | 78 } |
| 79 | 79 |
| 80 /* ------------------------------------------------------------ */ | 80 /* ------------------------------------------------------------ */ |
| 81 public MimeTypes getMimeTypes() | 81 public MimeTypes getMimeTypes() |
| 82 { | 82 { |
| 83 return _mimeTypes; | 83 return _mimeTypes; |
| 84 } | 84 } |
| 85 | 85 |
| 86 /* ------------------------------------------------------------ */ | 86 /* ------------------------------------------------------------ */ |
| 87 public void setMimeTypes(MimeTypes mimeTypes) | 87 public void setMimeTypes(MimeTypes mimeTypes) |
| 88 { | 88 { |
| 89 _mimeTypes = mimeTypes; | 89 _mimeTypes = mimeTypes; |
| 90 } | 90 } |
| 91 | 91 |
| 92 /* ------------------------------------------------------------ */ | 92 /* ------------------------------------------------------------ */ |
| 93 /** | 93 /** |
| 94 * @return True if resource aliases are allowed. | 94 * @return True if resource aliases are allowed. |
| 95 */ | 95 */ |
| 96 public boolean isAliases() | 96 public boolean isAliases() |
| 97 { | 97 { |
| 98 return _aliases; | 98 return _aliases; |
| 99 } | 99 } |
| 100 | 100 |
| 101 /* ------------------------------------------------------------ */ | 101 /* ------------------------------------------------------------ */ |
| 102 /** | 102 /** |
| 103 * Set if resource aliases (eg symlink, 8.3 names, case insensitivity) are allowed. | 103 * Set if resource aliases (eg symlink, 8.3 names, case insensitivity) are allowed. |
| 104 * Allowing aliases can significantly increase security vulnerabilities. | 104 * Allowing aliases can significantly increase security vulnerabilities. |
| 105 * If this handler is deployed inside a ContextHandler, then the | 105 * If this handler is deployed inside a ContextHandler, then the |
| 106 * {@link ContextHandler#isAliases()} takes precedent. | 106 * {@link ContextHandler#isAliases()} takes precedent. |
| 107 * @param aliases True if aliases are supported. | 107 * @param aliases True if aliases are supported. |
| 108 */ | 108 */ |
| 109 public void setAliases(boolean aliases) | 109 public void setAliases(boolean aliases) |
| 110 { | 110 { |
| 111 _aliases = aliases; | 111 _aliases = aliases; |
| 112 } | 112 } |
| 113 | 113 |
| 114 /* ------------------------------------------------------------ */ | 114 /* ------------------------------------------------------------ */ |
| 115 /** Get the directory option. | 115 /** Get the directory option. |
| 116 * @return true if directories are listed. | 116 * @return true if directories are listed. |
| 117 */ | 117 */ |
| 118 public boolean isDirectoriesListed() | 118 public boolean isDirectoriesListed() |
| 119 { | 119 { |
| 120 return _directory; | 120 return _directory; |
| 121 } | 121 } |
| 122 | 122 |
| 123 /* ------------------------------------------------------------ */ | 123 /* ------------------------------------------------------------ */ |
| 124 /** Set the directory. | 124 /** Set the directory. |
| 125 * @param directory true if directories are listed. | 125 * @param directory true if directories are listed. |
| 126 */ | 126 */ |
| 127 public void setDirectoriesListed(boolean directory) | 127 public void setDirectoriesListed(boolean directory) |
| 128 { | 128 { |
| 129 _directory = directory; | 129 _directory = directory; |
| 130 } | 130 } |
| 131 | 131 |
| 132 /* ------------------------------------------------------------ */ | 132 /* ------------------------------------------------------------ */ |
| 133 /** | 133 /** |
| 134 * @return True if ETag processing is done | 134 * @return True if ETag processing is done |
| 135 */ | 135 */ |
| 136 public boolean isEtags() | 136 public boolean isEtags() |
| 137 { | 137 { |
| 138 return _etags; | 138 return _etags; |
| 139 } | 139 } |
| 140 | 140 |
| 141 /* ------------------------------------------------------------ */ | 141 /* ------------------------------------------------------------ */ |
| 142 /** | 142 /** |
| 143 * @param etags True if ETag processing is done | 143 * @param etags True if ETag processing is done |
| 144 */ | 144 */ |
| 145 public void setEtags(boolean etags) | 145 public void setEtags(boolean etags) |
| 146 { | 146 { |
| 147 _etags = etags; | 147 _etags = etags; |
| 148 } | 148 } |
| 149 | 149 |
| 150 /* ------------------------------------------------------------ */ | 150 /* ------------------------------------------------------------ */ |
| 151 @Override | 151 @Override |
| 152 public void doStart() | 152 public void doStart() |
| 153 throws Exception | 153 throws Exception |
| 154 { | 154 { |
| 155 Context scontext = ContextHandler.getCurrentContext(); | 155 Context scontext = ContextHandler.getCurrentContext(); |
| 156 _context = (scontext==null?null:scontext.getContextHandler()); | 156 _context = (scontext==null?null:scontext.getContextHandler()); |
| 157 | 157 |
| 158 if (_context!=null) | 158 if (_context!=null) |
| 159 _aliases=_context.isAliases(); | 159 _aliases=_context.isAliases(); |
| 160 | 160 |
| 161 if (!_aliases && !FileResource.getCheckAliases()) | 161 if (!_aliases && !FileResource.getCheckAliases()) |
| 162 throw new IllegalStateException("Alias checking disabled"); | 162 throw new IllegalStateException("Alias checking disabled"); |
| 163 | 163 |
| 164 super.doStart(); | 164 super.doStart(); |
| 165 } | 165 } |
| 166 | 166 |
| 167 /* ------------------------------------------------------------ */ | 167 /* ------------------------------------------------------------ */ |
| 168 /** | 168 /** |
| 169 * @return Returns the resourceBase. | 169 * @return Returns the resourceBase. |
| 170 */ | 170 */ |
| 171 public Resource getBaseResource() | 171 public Resource getBaseResource() |
| 172 { | 172 { |
| 173 if (_baseResource==null) | 173 if (_baseResource==null) |
| 174 return null; | 174 return null; |
| 175 return _baseResource; | 175 return _baseResource; |
| 176 } | 176 } |
| 177 | 177 |
| 178 /* ------------------------------------------------------------ */ | 178 /* ------------------------------------------------------------ */ |
| 179 /** | 179 /** |
| 180 * @return Returns the base resource as a string. | 180 * @return Returns the base resource as a string. |
| 181 */ | 181 */ |
| 182 public String getResourceBase() | 182 public String getResourceBase() |
| 183 { | 183 { |
| 184 if (_baseResource==null) | 184 if (_baseResource==null) |
| 185 return null; | 185 return null; |
| 186 return _baseResource.toString(); | 186 return _baseResource.toString(); |
| 187 } | 187 } |
| 188 | 188 |
| 189 | 189 |
| 190 /* ------------------------------------------------------------ */ | 190 /* ------------------------------------------------------------ */ |
| 191 /** | 191 /** |
| 192 * @param base The resourceBase to set. | 192 * @param base The resourceBase to set. |
| 193 */ | 193 */ |
| 194 public void setBaseResource(Resource base) | 194 public void setBaseResource(Resource base) |
| 195 { | 195 { |
| 196 _baseResource=base; | 196 _baseResource=base; |
| 197 } | 197 } |
| 198 | 198 |
| 199 /* ------------------------------------------------------------ */ | 199 /* ------------------------------------------------------------ */ |
| 200 /** | 200 /** |
| 201 * @param resourceBase The base resource as a string. | 201 * @param resourceBase The base resource as a string. |
| 202 */ | 202 */ |
| 203 public void setResourceBase(String resourceBase) | 203 public void setResourceBase(String resourceBase) |
| 204 { | 204 { |
| 205 try | 205 try |
| 206 { | 206 { |
| 207 setBaseResource(Resource.newResource(resourceBase)); | 207 setBaseResource(Resource.newResource(resourceBase)); |
| 208 } | 208 } |
| 209 catch (Exception e) | 209 catch (Exception e) |
| 210 { | 210 { |
| 211 LOG.warn(e.toString()); | 211 LOG.warn(e.toString()); |
| 212 LOG.debug(e); | 212 LOG.debug(e); |
| 213 throw new IllegalArgumentException(resourceBase); | 213 throw new IllegalArgumentException(resourceBase); |
| 214 } | 214 } |
| 215 } | 215 } |
| 216 | 216 |
| 217 /* ------------------------------------------------------------ */ | 217 /* ------------------------------------------------------------ */ |
| 218 /** | 218 /** |
| 219 * @return Returns the stylesheet as a Resource. | 219 * @return Returns the stylesheet as a Resource. |
| 220 */ | 220 */ |
| 221 public Resource getStylesheet() | 221 public Resource getStylesheet() |
| 222 { | 222 { |
| 223 if(_stylesheet != null) | 223 if(_stylesheet != null) |
| 224 { | 224 { |
| 225 return _stylesheet; | 225 return _stylesheet; |
| 226 } | 226 } |
| 227 else | 227 else |
| 228 { | 228 { |
| 229 if(_defaultStylesheet == null) | 229 if(_defaultStylesheet == null) |
| 230 { | 230 { |
| 231 try | 231 try |
| 232 { | 232 { |
| 233 _defaultStylesheet = Resource.newResource(this.getClass().getResource("/jetty-dir.css")); | 233 _defaultStylesheet = Resource.newResource(this.getClass().getResource("/org/eclipse/jetty/jetty-dir.css")); |
| 234 } | 234 } |
| 235 catch(IOException e) | 235 catch(IOException e) |
| 236 { | 236 { |
| 237 LOG.warn(e.toString()); | 237 LOG.warn(e.toString()); |
| 238 LOG.debug(e); | 238 LOG.debug(e); |
| 239 } | 239 } |
| 240 } | 240 } |
| 241 return _defaultStylesheet; | 241 return _defaultStylesheet; |
| 242 } | 242 } |
| 243 } | 243 } |
| 244 | 244 |
| 245 /* ------------------------------------------------------------ */ | 245 /* ------------------------------------------------------------ */ |
| 246 /** | 246 /** |
| 247 * @param stylesheet The location of the stylesheet to be used as a String. | 247 * @param stylesheet The location of the stylesheet to be used as a String. |
| 248 */ | 248 */ |
| 249 public void setStylesheet(String stylesheet) | 249 public void setStylesheet(String stylesheet) |
| 250 { | 250 { |
| 251 try | 251 try |
| 252 { | 252 { |
| 253 _stylesheet = Resource.newResource(stylesheet); | 253 _stylesheet = Resource.newResource(stylesheet); |
| 254 if(!_stylesheet.exists()) | 254 if(!_stylesheet.exists()) |
| 255 { | 255 { |
| 256 LOG.warn("unable to find custom stylesheet: " + stylesheet); | 256 LOG.warn("unable to find custom stylesheet: " + stylesheet); |
| 257 _stylesheet = null; | 257 _stylesheet = null; |
| 258 } | 258 } |
| 259 } | 259 } |
| 260 catch(Exception e) | 260 catch(Exception e) |
| 261 { | 261 { |
| 262 LOG.warn(e.toString()); | 262 LOG.warn(e.toString()); |
| 263 LOG.debug(e); | 263 LOG.debug(e); |
| 264 throw new IllegalArgumentException(stylesheet.toString()); | 264 throw new IllegalArgumentException(stylesheet.toString()); |
| 265 } | 265 } |
| 266 } | 266 } |
| 267 | 267 |
| 268 /* ------------------------------------------------------------ */ | 268 /* ------------------------------------------------------------ */ |
| 269 /** | 269 /** |
| 270 * @return the cacheControl header to set on all static content. | 270 * @return the cacheControl header to set on all static content. |
| 271 */ | 271 */ |
| 272 public String getCacheControl() | 272 public String getCacheControl() |
| 273 { | 273 { |
| 274 return _cacheControl.toString(); | 274 return _cacheControl.toString(); |
| 275 } | 275 } |
| 276 | 276 |
| 277 /* ------------------------------------------------------------ */ | 277 /* ------------------------------------------------------------ */ |
| 278 /** | 278 /** |
| 279 * @param cacheControl the cacheControl header to set on all static content. | 279 * @param cacheControl the cacheControl header to set on all static content. |
| 280 */ | 280 */ |
| 281 public void setCacheControl(String cacheControl) | 281 public void setCacheControl(String cacheControl) |
| 282 { | 282 { |
| 283 _cacheControl=cacheControl==null?null:new ByteArrayBuffer(cacheControl); | 283 _cacheControl=cacheControl==null?null:new ByteArrayBuffer(cacheControl); |
| 284 } | 284 } |
| 285 | 285 |
| 286 /* ------------------------------------------------------------ */ | 286 /* ------------------------------------------------------------ */ |
| 287 /* | 287 /* |
| 288 */ | 288 */ |
| 289 public Resource getResource(String path) throws MalformedURLException | 289 public Resource getResource(String path) throws MalformedURLException |
| 290 { | 290 { |
| 291 if (path==null || !path.startsWith("/")) | 291 if (path==null || !path.startsWith("/")) |
| 292 throw new MalformedURLException(path); | 292 throw new MalformedURLException(path); |
| 293 | 293 |
| 294 Resource base = _baseResource; | 294 Resource base = _baseResource; |
| 295 if (base==null) | 295 if (base==null) |
| 296 { | 296 { |
| 297 if (_context==null) | 297 if (_context==null) |
| 298 return null; | 298 return null; |
| 299 base=_context.getBaseResource(); | 299 base=_context.getBaseResource(); |
| 300 if (base==null) | 300 if (base==null) |
| 301 return null; | 301 return null; |
| 302 } | 302 } |
| 303 | 303 |
| 304 try | 304 try |
| 305 { | 305 { |
| 306 path=URIUtil.canonicalPath(path); | 306 path=URIUtil.canonicalPath(path); |
| 307 return base.addPath(path); | 307 return base.addPath(path); |
| 308 } | 308 } |
| 309 catch(Exception e) | 309 catch(Exception e) |
| 310 { | 310 { |
| 311 LOG.ignore(e); | 311 LOG.ignore(e); |
| 312 } | 312 } |
| 313 | 313 |
| 314 return null; | 314 return null; |
| 315 } | 315 } |
| 316 | 316 |
| 317 /* ------------------------------------------------------------ */ | 317 /* ------------------------------------------------------------ */ |
| 318 protected Resource getResource(HttpServletRequest request) throws MalformedURLException | 318 protected Resource getResource(HttpServletRequest request) throws MalformedURLException |
| 319 { | 319 { |
| 320 String servletPath; | 320 String servletPath; |
| 321 String pathInfo; | 321 String pathInfo; |
| 322 Boolean included = request.getAttribute(Dispatcher.INCLUDE_REQUEST_URI) != null; | 322 Boolean included = request.getAttribute(Dispatcher.INCLUDE_REQUEST_URI) != null; |
| 323 if (included != null && included.booleanValue()) | 323 if (included != null && included.booleanValue()) |
| 324 { | 324 { |
| 325 servletPath = (String)request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH); | 325 servletPath = (String)request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH); |
| 326 pathInfo = (String)request.getAttribute(Dispatcher.INCLUDE_PATH_INFO); | 326 pathInfo = (String)request.getAttribute(Dispatcher.INCLUDE_PATH_INFO); |
| 327 | 327 |
| 328 if (servletPath == null && pathInfo == null) | 328 if (servletPath == null && pathInfo == null) |
| 329 { | 329 { |
| 330 servletPath = request.getServletPath(); | 330 servletPath = request.getServletPath(); |
| 331 pathInfo = request.getPathInfo(); | 331 pathInfo = request.getPathInfo(); |
| 332 } | 332 } |
| 333 } | 333 } |
| 334 else | 334 else |
| 335 { | 335 { |
| 336 servletPath = request.getServletPath(); | 336 servletPath = request.getServletPath(); |
| 337 pathInfo = request.getPathInfo(); | 337 pathInfo = request.getPathInfo(); |
| 338 } | 338 } |
| 339 | 339 |
| 340 String pathInContext=URIUtil.addPaths(servletPath,pathInfo); | 340 String pathInContext=URIUtil.addPaths(servletPath,pathInfo); |
| 341 return getResource(pathInContext); | 341 return getResource(pathInContext); |
| 342 } | 342 } |
| 343 | 343 |
| 344 | 344 |
| 345 /* ------------------------------------------------------------ */ | 345 /* ------------------------------------------------------------ */ |
| 346 public String[] getWelcomeFiles() | 346 public String[] getWelcomeFiles() |
| 347 { | 347 { |
| 348 return _welcomeFiles; | 348 return _welcomeFiles; |
| 349 } | 349 } |
| 350 | 350 |
| 351 /* ------------------------------------------------------------ */ | 351 /* ------------------------------------------------------------ */ |
| 352 public void setWelcomeFiles(String[] welcomeFiles) | 352 public void setWelcomeFiles(String[] welcomeFiles) |
| 353 { | 353 { |
| 354 _welcomeFiles=welcomeFiles; | 354 _welcomeFiles=welcomeFiles; |
| 355 } | 355 } |
| 356 | 356 |
| 357 /* ------------------------------------------------------------ */ | 357 /* ------------------------------------------------------------ */ |
| 358 protected Resource getWelcome(Resource directory) throws MalformedURLException, IOException | 358 protected Resource getWelcome(Resource directory) throws MalformedURLException, IOException |
| 359 { | 359 { |
| 360 for (int i=0;i<_welcomeFiles.length;i++) | 360 for (int i=0;i<_welcomeFiles.length;i++) |
| 361 { | 361 { |
| 362 Resource welcome=directory.addPath(_welcomeFiles[i]); | 362 Resource welcome=directory.addPath(_welcomeFiles[i]); |
| 363 if (welcome.exists() && !welcome.isDirectory()) | 363 if (welcome.exists() && !welcome.isDirectory()) |
| 364 return welcome; | 364 return welcome; |
| 365 } | 365 } |
| 366 | 366 |
| 367 return null; | 367 return null; |
| 368 } | 368 } |
| 369 | 369 |
| 370 /* ------------------------------------------------------------ */ | 370 /* ------------------------------------------------------------ */ |
| 371 /* | 371 /* |
| 372 * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) | 372 * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) |
| 373 */ | 373 */ |
| 374 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException | 374 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException |
| 375 { | 375 { |
| 376 if (baseRequest.isHandled()) | 376 if (baseRequest.isHandled()) |
| 377 return; | 377 return; |
| 378 | 378 |
| 379 boolean skipContentBody = false; | 379 boolean skipContentBody = false; |
| 380 | 380 |
| 381 if(!HttpMethods.GET.equals(request.getMethod())) | 381 if(!HttpMethods.GET.equals(request.getMethod())) |
| 382 { | 382 { |
| 383 if(!HttpMethods.HEAD.equals(request.getMethod())) | 383 if(!HttpMethods.HEAD.equals(request.getMethod())) |
| 384 { | 384 { |
| 385 //try another handler | 385 //try another handler |
| 386 super.handle(target, baseRequest, request, response); | 386 super.handle(target, baseRequest, request, response); |
| 387 return; | 387 return; |
| 388 } | 388 } |
| 389 skipContentBody = true; | 389 skipContentBody = true; |
| 390 } | 390 } |
| 391 | 391 |
| 392 Resource resource = getResource(request); | 392 Resource resource = getResource(request); |
| 393 | 393 |
| 394 if (resource==null || !resource.exists()) | 394 if (resource==null || !resource.exists()) |
| 395 { | 395 { |
| 396 if (target.endsWith("/jetty-dir.css")) | 396 if (target.endsWith("/jetty-dir.css")) |
| 397 { | 397 { |
| 398 resource = getStylesheet(); | 398 resource = getStylesheet(); |
| 399 if (resource==null) | 399 if (resource==null) |
| 400 return; | 400 return; |
| 401 response.setContentType("text/css"); | 401 response.setContentType("text/css"); |
| 402 } | 402 } |
| 403 else | 403 else |
| 404 { | 404 { |
| 405 //no resource - try other handlers | 405 //no resource - try other handlers |
| 406 super.handle(target, baseRequest, request, response); | 406 super.handle(target, baseRequest, request, response); |
| 407 return; | 407 return; |
| 408 } | 408 } |
| 409 } | 409 } |
| 410 | 410 |
| 411 if (!_aliases && resource.getAlias()!=null) | 411 if (!_aliases && resource.getAlias()!=null) |
| 412 { | 412 { |
| 413 LOG.info(resource+" aliased to "+resource.getAlias()); | 413 LOG.info(resource+" aliased to "+resource.getAlias()); |
| 414 return; | 414 return; |
| 415 } | 415 } |
| 416 | 416 |
| 417 // We are going to serve something | 417 // We are going to serve something |
| 418 baseRequest.setHandled(true); | 418 baseRequest.setHandled(true); |
| 419 | 419 |
| 420 if (resource.isDirectory()) | 420 if (resource.isDirectory()) |
| 421 { | 421 { |
| 422 if (!request.getPathInfo().endsWith(URIUtil.SLASH)) | 422 if (!request.getPathInfo().endsWith(URIUtil.SLASH)) |
| 423 { | 423 { |
| 424 response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH))); | 424 response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH))); |
| 425 return; | 425 return; |
| 426 } | 426 } |
| 427 | 427 |
| 428 Resource welcome=getWelcome(resource); | 428 Resource welcome=getWelcome(resource); |
| 429 if (welcome!=null && welcome.exists()) | 429 if (welcome!=null && welcome.exists()) |
| 430 resource=welcome; | 430 resource=welcome; |
| 431 else | 431 else |
| 432 { | 432 { |
| 433 doDirectory(request,response,resource); | 433 doDirectory(request,response,resource); |
| 434 baseRequest.setHandled(true); | 434 baseRequest.setHandled(true); |
| 435 return; | 435 return; |
| 436 } | 436 } |
| 437 } | 437 } |
| 438 | 438 |
| 439 // set some headers | 439 // set some headers |
| 440 long last_modified=resource.lastModified(); | 440 long last_modified=resource.lastModified(); |
| 441 String etag=null; | 441 String etag=null; |
| 442 if (_etags) | 442 if (_etags) |
| 443 { | 443 { |
| 444 // simple handling of only a single etag | 444 // simple handling of only a single etag |
| 445 String ifnm = request.getHeader(HttpHeaders.IF_NONE_MATCH); | 445 String ifnm = request.getHeader(HttpHeaders.IF_NONE_MATCH); |
| 446 etag=resource.getWeakETag(); | 446 etag=resource.getWeakETag(); |
| 447 if (ifnm!=null && resource!=null && ifnm.equals(etag)) | 447 if (ifnm!=null && resource!=null && ifnm.equals(etag)) |
| 448 { | 448 { |
| 449 response.setStatus(HttpStatus.NOT_MODIFIED_304); | 449 response.setStatus(HttpStatus.NOT_MODIFIED_304); |
| 450 baseRequest.getResponse().getHttpFields().put(HttpHeaders.ETAG_BUFFER,etag); | 450 baseRequest.getResponse().getHttpFields().put(HttpHeaders.ETAG_BUFFER,etag); |
| 451 return; | 451 return; |
| 452 } | 452 } |
| 453 } | 453 } |
| 454 | 454 |
| 455 | 455 |
| 456 if (last_modified>0) | 456 if (last_modified>0) |
| 457 { | 457 { |
| 458 long if_modified=request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE); | 458 long if_modified=request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE); |
| 459 if (if_modified>0 && last_modified/1000<=if_modified/1000) | 459 if (if_modified>0 && last_modified/1000<=if_modified/1000) |
| 460 { | 460 { |
| 461 response.setStatus(HttpStatus.NOT_MODIFIED_304); | 461 response.setStatus(HttpStatus.NOT_MODIFIED_304); |
| 462 return; | 462 return; |
| 463 } | 463 } |
| 464 } | 464 } |
| 465 | 465 |
| 466 Buffer mime=_mimeTypes.getMimeByExtension(resource.toString()); | 466 Buffer mime=_mimeTypes.getMimeByExtension(resource.toString()); |
| 467 if (mime==null) | 467 if (mime==null) |
| 468 mime=_mimeTypes.getMimeByExtension(request.getPathInfo()); | 468 mime=_mimeTypes.getMimeByExtension(request.getPathInfo()); |
| 469 | 469 |
| 470 // set the headers | 470 // set the headers |
| 471 doResponseHeaders(response,resource,mime!=null?mime.toString():null); | 471 doResponseHeaders(response,resource,mime!=null?mime.toString():null); |
| 472 response.setDateHeader(HttpHeaders.LAST_MODIFIED,last_modified); | 472 response.setDateHeader(HttpHeaders.LAST_MODIFIED,last_modified); |
| 473 if (_etags) | 473 if (_etags) |
| 474 baseRequest.getResponse().getHttpFields().put(HttpHeaders.ETAG_BUFFER,etag); | 474 baseRequest.getResponse().getHttpFields().put(HttpHeaders.ETAG_BUFFER,etag); |
| 475 | 475 |
| 476 if(skipContentBody) | 476 if(skipContentBody) |
| 477 return; | 477 return; |
| 478 // Send the content | 478 // Send the content |
| 479 OutputStream out =null; | 479 OutputStream out =null; |
| 480 try {out = response.getOutputStream();} | 480 try {out = response.getOutputStream();} |
| 481 catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());} | 481 catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());} |
| 482 | 482 |
| 483 // See if a short direct method can be used? | 483 // See if a short direct method can be used? |
| 484 if (out instanceof AbstractHttpConnection.Output) | 484 if (out instanceof AbstractHttpConnection.Output) |
| 485 { | 485 { |
| 486 // TODO file mapped buffers | 486 // TODO file mapped buffers |
| 487 ((AbstractHttpConnection.Output)out).sendContent(resource.getInputStream()); | 487 ((AbstractHttpConnection.Output)out).sendContent(resource.getInputStream()); |
| 488 } | 488 } |
| 489 else | 489 else |
| 490 { | 490 { |
| 491 // Write content normally | 491 // Write content normally |
| 492 resource.writeTo(out,0,resource.length()); | 492 resource.writeTo(out,0,resource.length()); |
| 493 } | 493 } |
| 494 } | 494 } |
| 495 | 495 |
| 496 /* ------------------------------------------------------------ */ | 496 /* ------------------------------------------------------------ */ |
| 497 protected void doDirectory(HttpServletRequest request,HttpServletResponse response, Resource resource) | 497 protected void doDirectory(HttpServletRequest request,HttpServletResponse response, Resource resource) |
| 498 throws IOException | 498 throws IOException |
| 499 { | 499 { |
| 500 if (_directory) | 500 if (_directory) |
| 501 { | 501 { |
| 502 String listing = resource.getListHTML(request.getRequestURI(),request.getPathInfo().lastIndexOf("/") > 0); | 502 String listing = resource.getListHTML(request.getRequestURI(),request.getPathInfo().lastIndexOf("/") > 0); |
| 503 response.setContentType("text/html; charset=UTF-8"); | 503 response.setContentType("text/html; charset=UTF-8"); |
| 504 response.getWriter().println(listing); | 504 response.getWriter().println(listing); |
| 505 } | 505 } |
| 506 else | 506 else |
| 507 response.sendError(HttpStatus.FORBIDDEN_403); | 507 response.sendError(HttpStatus.FORBIDDEN_403); |
| 508 } | 508 } |
| 509 | 509 |
| 510 /* ------------------------------------------------------------ */ | 510 /* ------------------------------------------------------------ */ |
| 511 /** Set the response headers. | 511 /** Set the response headers. |
| 512 * This method is called to set the response headers such as content type and content length. | 512 * This method is called to set the response headers such as content type and content length. |
| 513 * May be extended to add additional headers. | 513 * May be extended to add additional headers. |
| 514 * @param response | 514 * @param response |
| 515 * @param resource | 515 * @param resource |
| 516 * @param mimeType | 516 * @param mimeType |
| 517 */ | 517 */ |
| 518 protected void doResponseHeaders(HttpServletResponse response, Resource resource, String mimeType) | 518 protected void doResponseHeaders(HttpServletResponse response, Resource resource, String mimeType) |
| 519 { | 519 { |
| 520 if (mimeType!=null) | 520 if (mimeType!=null) |
| 521 response.setContentType(mimeType); | 521 response.setContentType(mimeType); |
| 522 | 522 |
| 523 long length=resource.length(); | 523 long length=resource.length(); |
| 524 | 524 |
| 525 if (response instanceof Response) | 525 if (response instanceof Response) |
| 526 { | 526 { |
| 527 HttpFields fields = ((Response)response).getHttpFields(); | 527 HttpFields fields = ((Response)response).getHttpFields(); |
| 528 | 528 |
| 529 if (length>0) | 529 if (length>0) |
| 530 fields.putLongField(HttpHeaders.CONTENT_LENGTH_BUFFER,length); | 530 fields.putLongField(HttpHeaders.CONTENT_LENGTH_BUFFER,length); |
| 531 | 531 |
| 532 if (_cacheControl!=null) | 532 if (_cacheControl!=null) |
| 533 fields.put(HttpHeaders.CACHE_CONTROL_BUFFER,_cacheControl); | 533 fields.put(HttpHeaders.CACHE_CONTROL_BUFFER,_cacheControl); |
| 534 } | 534 } |
| 535 else | 535 else |
| 536 { | 536 { |
| 537 if (length>0) | 537 if (length>0) |
| 538 response.setHeader(HttpHeaders.CONTENT_LENGTH,Long.toString(length)); | 538 response.setHeader(HttpHeaders.CONTENT_LENGTH,Long.toString(length)); |
| 539 | 539 |
| 540 if (_cacheControl!=null) | 540 if (_cacheControl!=null) |
| 541 response.setHeader(HttpHeaders.CACHE_CONTROL,_cacheControl.toString()); | 541 response.setHeader(HttpHeaders.CACHE_CONTROL,_cacheControl.toString()); |
| 542 } | 542 } |
| 543 | 543 |
| 544 } | 544 } |
| 545 } | 545 } |
