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 }