KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > jetty > servlet > Default


1 // ========================================================================
2
// $Id: Default.java,v 1.51 2006/10/08 14:13:18 gregwilkins Exp $
3
// Copyright 199-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.jetty.servlet;
17
18 import java.io.IOException JavaDoc;
19 import java.io.InputStream JavaDoc;
20 import java.io.OutputStream JavaDoc;
21 import java.util.Enumeration JavaDoc;
22 import java.util.List JavaDoc;
23
24 import javax.servlet.RequestDispatcher JavaDoc;
25 import javax.servlet.ServletContext JavaDoc;
26 import javax.servlet.ServletException JavaDoc;
27 import javax.servlet.UnavailableException JavaDoc;
28 import javax.servlet.http.HttpServlet JavaDoc;
29 import javax.servlet.http.HttpServletRequest JavaDoc;
30 import javax.servlet.http.HttpServletResponse JavaDoc;
31
32 import org.apache.commons.logging.Log;
33 import org.mortbay.log.LogFactory;
34 import org.mortbay.http.HttpContext;
35 import org.mortbay.http.HttpFields;
36 import org.mortbay.http.HttpRequest;
37 import org.mortbay.http.HttpResponse;
38 import org.mortbay.http.InclusiveByteRange;
39 import org.mortbay.http.MultiPartResponse;
40 import org.mortbay.http.ResourceCache;
41 import org.mortbay.util.CachedResource;
42 import org.mortbay.util.IO;
43 import org.mortbay.util.LogSupport;
44 import org.mortbay.util.Resource;
45 import org.mortbay.util.URI;
46 import org.mortbay.util.WriterOutputStream;
47
48 /* ------------------------------------------------------------ */
49 /**
50  * The default servlet. This servlet, normally mapped to /, provides the handling for static
51  * content, OPTION and TRACE methods for the context. The following initParameters are supported:
52  *
53  * <PRE>
54  *
55  * acceptRanges If true, range requests and responses are supported
56  *
57  * dirAllowed If true, directory listings are returned if no welcome file is found. Else 403
58  * Forbidden.
59  *
60  * putAllowed If true, the PUT method is allowed
61  *
62  * delAllowed If true, the DELETE method is allowed
63  *
64  * redirectWelcome If true, welcome files are redirected rather than forwarded to.
65  *
66  * minGzipLength If set to a positive integer, then static content larger than this will be served
67  * as gzip content encoded if a matching resource is found ending with ".gz"
68  *
69  * resourceBase Set to replace the context resource base
70  *
71  * relativeResourceBase Set with a pathname relative to the base of the servlet context root. Useful
72  * for only serving static content out of only specific subdirectories.
73  *
74  * </PRE>
75  *
76  * The MOVE method is allowed if PUT and DELETE are allowed
77  *
78  * @version $Id: Default.java,v 1.51 2006/10/08 14:13:18 gregwilkins Exp $
79  * @author Greg Wilkins (gregw)
80  */

81 public class Default extends HttpServlet JavaDoc
82 {
83     private static Log log = LogFactory.getLog(Default.class);
84
85     private HttpContext _httpContext;
86     private ServletHandler _servletHandler;
87     private String JavaDoc _AllowString = "GET, POST, HEAD, OPTIONS, TRACE";
88
89     private boolean _acceptRanges = true;
90     private boolean _dirAllowed;
91     private boolean _putAllowed;
92     private boolean _delAllowed;
93     private boolean _redirectWelcomeFiles;
94     private int _minGzipLength = -1;
95     private Resource _resourceBase;
96
97     /* ------------------------------------------------------------ */
98     public void init() throws UnavailableException JavaDoc
99     {
100         ServletContext JavaDoc config = getServletContext();
101         _servletHandler = ((ServletHandler.Context) config).getServletHandler();
102         _httpContext = _servletHandler.getHttpContext();
103
104         _acceptRanges = getInitBoolean("acceptRanges");
105         _dirAllowed = getInitBoolean("dirAllowed");
106         _putAllowed = getInitBoolean("putAllowed");
107         _delAllowed = getInitBoolean("delAllowed");
108         _redirectWelcomeFiles = getInitBoolean("redirectWelcome");
109         _minGzipLength = getInitInt("minGzipLength");
110
111         String JavaDoc rrb = getInitParameter("relativeResourceBase");
112         if (rrb != null)
113         {
114             try
115             {
116                 _resourceBase = _httpContext.getBaseResource().addPath(rrb);
117             }
118             catch (Exception JavaDoc e)
119             {
120                 log.warn(LogSupport.EXCEPTION, e);
121                 throw new UnavailableException JavaDoc(e.toString());
122             }
123         }
124
125         String JavaDoc rb = getInitParameter("resourceBase");
126
127         if (rrb != null && rb != null)
128             throw new UnavailableException JavaDoc("resourceBase & relativeResourceBase");
129
130         if (rb != null)
131         {
132             try
133             {
134                 _resourceBase = Resource.newResource(rb);
135             }
136             catch (Exception JavaDoc e)
137             {
138                 log.warn(LogSupport.EXCEPTION, e);
139                 throw new UnavailableException JavaDoc(e.toString());
140             }
141         }
142         if (log.isDebugEnabled())
143             log.debug("resource base = " + _resourceBase);
144
145         if (_putAllowed)
146             _AllowString += ", PUT";
147         if (_delAllowed)
148             _AllowString += ", DELETE";
149         if (_putAllowed && _delAllowed)
150             _AllowString += ", MOVE";
151     }
152
153     /* ------------------------------------------------------------ */
154     private boolean getInitBoolean(String JavaDoc name)
155     {
156         String JavaDoc value = getInitParameter(name);
157         return value != null && value.length() > 0 && (value.startsWith("t") || value.startsWith("T") || value.startsWith("y") || value.startsWith("Y") || value.startsWith("1"));
158     }
159
160     /* ------------------------------------------------------------ */
161     private int getInitInt(String JavaDoc name)
162     {
163         String JavaDoc value = getInitParameter(name);
164         if (value != null && value.length() > 0)
165             return Integer.parseInt(value);
166         return -1;
167     }
168
169     /* ------------------------------------------------------------ */
170     /**
171      * get Resource to serve. Map a path to a resource. The default implementation calls
172      * HttpContext.getResource but derived servlets may provide their own mapping.
173      *
174      * @param pathInContext The path to find a resource for.
175      * @return The resource to serve.
176      */

177     protected Resource getResource(String JavaDoc pathInContext) throws IOException JavaDoc
178     {
179         Resource r = (_resourceBase == null) ? _httpContext.getResource(pathInContext) : _resourceBase.addPath(pathInContext);
180         
181         if (log.isDebugEnabled())
182             log.debug("RESOURCE=" + r);
183         return r;
184     }
185
186     /* ------------------------------------------------------------ */
187     protected void service(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) throws ServletException JavaDoc, IOException JavaDoc
188     {
189         String JavaDoc servletPath = (String JavaDoc) request.getAttribute(Dispatcher.__INCLUDE_SERVLET_PATH);
190         String JavaDoc pathInfo = null;
191         if (servletPath == null)
192         {
193             servletPath = request.getServletPath();
194             pathInfo = request.getPathInfo();
195         }
196         else
197             pathInfo = (String JavaDoc) request.getAttribute(Dispatcher.__INCLUDE_PATH_INFO);
198
199         String JavaDoc pathInContext = URI.addPaths(servletPath, pathInfo);
200                 
201         boolean endsWithSlash = pathInContext.endsWith("/");
202         Resource resource = getResource(pathInContext);
203
204         // Is the method allowed?
205
String JavaDoc method = request.getMethod();
206         if (_AllowString.indexOf(method) < 0)
207         {
208             if (resource != null && resource.exists())
209             {
210                 response.setHeader(HttpFields.__Allow, _AllowString);
211                 response.sendError(HttpResponse.__405_Method_Not_Allowed);
212             }
213             else
214                 response.sendError(HttpResponse.__404_Not_Found);
215             return;
216         }
217
218         // Handle the request
219
try
220         {
221             // handle by method.
222
if (method.equals(HttpRequest.__GET) || method.equals(HttpRequest.__POST) || method.equals(HttpRequest.__HEAD))
223                 handleGet(request, response, pathInContext, resource, endsWithSlash);
224             else if (_putAllowed && method.equals(HttpRequest.__PUT))
225                 handlePut(request, response, pathInContext, resource);
226             else if (_delAllowed && method.equals(HttpRequest.__DELETE))
227                 handleDelete(request, response, pathInContext, resource);
228             else if (_putAllowed && _delAllowed && method.equals(HttpRequest.__MOVE))
229                 handleMove(request, response, pathInContext, resource);
230             else if (method.equals(HttpRequest.__OPTIONS))
231                 handleOptions(request, response);
232             else if (method.equals(HttpRequest.__TRACE))
233                 _servletHandler.handleTrace(request, response);
234             else
235             {
236                 // anything else...
237
try
238                 {
239                     if (resource.exists())
240                         response.sendError(HttpResponse.__501_Not_Implemented);
241                     else
242                         _servletHandler.notFound(request, response);
243                 }
244                 catch (Exception JavaDoc e)
245                 {
246                     LogSupport.ignore(log, e);
247                 }
248             }
249         }
250         catch (IllegalArgumentException JavaDoc e)
251         {
252             LogSupport.ignore(log, e);
253         }
254         finally
255         {
256             if (resource != null && !(resource instanceof CachedResource))
257                 resource.release();
258         }
259
260     }
261
262     /* ------------------------------------------------------------------- */
263     public void handleGet(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, String JavaDoc pathInContext, Resource resource, boolean endsWithSlash) throws ServletException JavaDoc, IOException JavaDoc
264     {
265         if (resource == null || !resource.exists())
266             response.sendError(HttpResponse.__404_Not_Found);
267         else
268         {
269
270             // check if directory
271
if (resource.isDirectory())
272             {
273                 if (!endsWithSlash && !pathInContext.equals("/"))
274                 {
275                     String JavaDoc q = request.getQueryString();
276                     StringBuffer JavaDoc buf = request.getRequestURL();
277                     if (q != null && q.length() != 0)
278                     {
279                         buf.append('?');
280                         buf.append(q);
281                     }
282                     response.setContentLength(0);
283                     response.sendRedirect(response.encodeRedirectURL(URI.addPaths(buf.toString(), "/")));
284                     return;
285                 }
286
287                 // See if index file exists
288
String JavaDoc welcome = _httpContext.getWelcomeFile(resource);
289                 if (welcome != null)
290                 {
291                     String JavaDoc ipath = URI.addPaths(pathInContext, welcome);
292                     if (_redirectWelcomeFiles)
293                     {
294                         // Redirect to the index
295
response.setContentLength(0);
296                         response.sendRedirect(URI.addPaths(_httpContext.getContextPath(), ipath));
297                     }
298                     else
299                     {
300                         // Forward to the index
301
RequestDispatcher JavaDoc dispatcher = _servletHandler.getRequestDispatcher(ipath);
302                         dispatcher.forward(request, response);
303                     }
304                     return;
305                 }
306
307                 // Check modified dates
308
if (!passConditionalHeaders(request, response, resource))
309                     return;
310
311                 // If we got here, no forward to index took place
312
sendDirectory(request, response, resource, pathInContext.length() > 1);
313             }
314             else
315             {
316                 // Check modified dates
317
if (!passConditionalHeaders(request, response, resource))
318                     return;
319
320                 // just send it
321
sendData(request, response, pathInContext, resource);
322             }
323         }
324     }
325
326     /* ------------------------------------------------------------------- */
327     public void handlePut(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, String JavaDoc pathInContext, Resource resource) throws ServletException JavaDoc, IOException JavaDoc
328     {
329         boolean exists = resource != null && resource.exists();
330         if (exists && !passConditionalHeaders(request, response, resource))
331             return;
332
333         if (pathInContext.endsWith("/"))
334         {
335             if (!exists)
336             {
337                 if (!resource.getFile().mkdirs())
338                     response.sendError(HttpResponse.__403_Forbidden, "Directories could not be created");
339                 else
340                 {
341                     response.setStatus(HttpResponse.__201_Created);
342                     response.flushBuffer();
343                 }
344             }
345             else
346             {
347                 response.setStatus(HttpResponse.__200_OK);
348                 response.flushBuffer();
349             }
350         }
351         else
352         {
353             try
354             {
355                 int toRead = request.getContentLength();
356                 InputStream JavaDoc in = request.getInputStream();
357                 OutputStream JavaDoc out = resource.getOutputStream();
358                 if (toRead >= 0)
359                     IO.copy(in, out, toRead);
360                 else
361                     IO.copy(in, out);
362                 out.close();
363
364                 response.setStatus(exists ? HttpResponse.__200_OK : HttpResponse.__201_Created);
365                 response.flushBuffer();
366             }
367             catch (Exception JavaDoc ex)
368             {
369                 log.warn(LogSupport.EXCEPTION, ex);
370                 response.sendError(HttpResponse.__403_Forbidden, ex.getMessage());
371             }
372         }
373     }
374
375     /* ------------------------------------------------------------------- */
376     public void handleDelete(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, String JavaDoc pathInContext, Resource resource) throws ServletException JavaDoc, IOException JavaDoc
377     {
378         if (!resource.exists() || !passConditionalHeaders(request, response, resource))
379             return;
380         try
381         {
382             // delete the file
383
if (resource.delete())
384             {
385                 response.setStatus(HttpResponse.__204_No_Content);
386                 response.flushBuffer();
387             }
388             else
389                 response.sendError(HttpResponse.__403_Forbidden);
390         }
391         catch (SecurityException JavaDoc sex)
392         {
393             log.warn(LogSupport.EXCEPTION, sex);
394             response.sendError(HttpResponse.__403_Forbidden, sex.getMessage());
395         }
396     }
397
398     /* ------------------------------------------------------------------- */
399     public void handleMove(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, String JavaDoc pathInContext, Resource resource) throws ServletException JavaDoc, IOException JavaDoc
400     {
401         if (!resource.exists() || !passConditionalHeaders(request, response, resource))
402             return;
403
404         String JavaDoc newPath = URI.canonicalPath(request.getHeader("new-uri"));
405         if (newPath == null)
406         {
407             response.sendError(HttpResponse.__400_Bad_Request, "No new-uri");
408             return;
409         }
410
411         String JavaDoc contextPath = _httpContext.getContextPath();
412         if (contextPath != null && !newPath.startsWith(contextPath))
413         {
414             response.sendError(HttpResponse.__405_Method_Not_Allowed, "Not in context");
415             return;
416         }
417
418         try
419         {
420             String JavaDoc newInfo = newPath;
421             if (contextPath != null)
422                 newInfo = newInfo.substring(contextPath.length());
423             Resource newFile = _httpContext.getBaseResource().addPath(newInfo);
424
425             resource.renameTo(newFile);
426             response.setStatus(HttpResponse.__204_No_Content);
427             response.flushBuffer();
428         }
429         catch (Exception JavaDoc ex)
430         {
431             log.warn(LogSupport.EXCEPTION, ex);
432             response.sendError(HttpResponse.__500_Internal_Server_Error, "Error:" + ex);
433             return;
434         }
435
436     }
437
438     /* ------------------------------------------------------------ */
439     public void handleOptions(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) throws IOException JavaDoc
440     {
441         // Handle OPTIONS request for entire server
442
// 9.2
443
response.setIntHeader(HttpFields.__ContentLength, 0);
444         response.setHeader(HttpFields.__Allow, _AllowString);
445         response.flushBuffer();
446     }
447
448     /* ------------------------------------------------------------ */
449     /*
450      * Check modification date headers.
451      */

452     protected boolean passConditionalHeaders(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, Resource resource) throws IOException JavaDoc
453     {
454         if (!request.getMethod().equals(HttpRequest.__HEAD) && request.getAttribute(Dispatcher.__INCLUDE_REQUEST_URI) == null)
455         {
456             // If we have meta data for the file
457
// Try a direct match for most common requests. Avoids
458
// parsing the date.
459
ResourceCache.ResourceMetaData metaData = _httpContext.getResourceMetaData(resource);
460             if (metaData != null)
461             {
462                 String JavaDoc ifms = request.getHeader(HttpFields.__IfModifiedSince);
463                 String JavaDoc mdlm = metaData.getLastModified();
464                 if (ifms != null && mdlm != null && ifms.equals(mdlm))
465                 {
466                     response.reset();
467                     response.setStatus(HttpResponse.__304_Not_Modified);
468                     response.flushBuffer();
469                     return false;
470                 }
471             }
472
473             long date = 0;
474             // Parse the if[un]modified dates and compare to resource
475

476             if ((date = request.getDateHeader(HttpFields.__IfUnmodifiedSince)) > 0)
477             {
478                 if (resource.lastModified() / 1000 > date / 1000)
479                 {
480                     response.sendError(HttpResponse.__412_Precondition_Failed);
481                     return false;
482                 }
483             }
484
485             if ((date = request.getDateHeader(HttpFields.__IfModifiedSince)) > 0)
486             {
487                 if (resource.lastModified() / 1000 <= date / 1000)
488                 {
489                     response.reset();
490                     response.setStatus(HttpResponse.__304_Not_Modified);
491                     response.flushBuffer();
492                     return false;
493                 }
494             }
495         }
496         return true;
497     }
498
499     /* ------------------------------------------------------------------- */
500     protected void sendDirectory(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, Resource resource, boolean parent) throws IOException JavaDoc
501     {
502         if (!_dirAllowed)
503         {
504             response.sendError(HttpResponse.__403_Forbidden);
505             return;
506         }
507
508         byte[] data = null;
509         if (resource instanceof CachedResource)
510             data = ((CachedResource) resource).getCachedData();
511
512         if (data == null)
513         {
514             String JavaDoc base = URI.addPaths(request.getRequestURI(), "/");
515             String JavaDoc dir = resource.getListHTML(base, parent);
516             if (dir == null)
517             {
518                 response.sendError(HttpResponse.__403_Forbidden, "No directory");
519                 return;
520             }
521             data = dir.getBytes("UTF-8");
522             if (resource instanceof CachedResource)
523                 ((CachedResource) resource).setCachedData(data);
524         }
525
526         response.setContentType("text/html; charset=UTF-8");
527         response.setContentLength(data.length);
528
529         if (!request.getMethod().equals(HttpRequest.__HEAD))
530             response.getOutputStream().write(data);
531     }
532
533     /* ------------------------------------------------------------ */
534     protected void sendData(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, String JavaDoc pathInContext, Resource resource) throws IOException JavaDoc
535     {
536         long resLength = resource.length();
537
538         boolean include = request.getAttribute(Dispatcher.__INCLUDE_REQUEST_URI) != null;
539
540         // Get the output stream (or writer)
541
OutputStream JavaDoc out = null;
542         try
543         {
544             out = response.getOutputStream();
545         }
546         catch (IllegalStateException JavaDoc e)
547         {
548             out = new WriterOutputStream(response.getWriter());
549         }
550
551         // see if there are any range headers
552
Enumeration JavaDoc reqRanges = include ? null : request.getHeaders(HttpFields.__Range);
553
554         if (reqRanges == null || !reqRanges.hasMoreElements())
555         {
556             // if there were no ranges, send entire entity
557
Resource data = resource;
558             if (!include)
559             {
560                 // look for a gziped content.
561
if (_minGzipLength > 0)
562                 {
563                     String JavaDoc accept = request.getHeader(HttpFields.__AcceptEncoding);
564                     if (accept != null && resLength > _minGzipLength && !pathInContext.endsWith(".gz"))
565                     {
566                         Resource gz = getResource(pathInContext + ".gz");
567                         if (gz.exists() && accept.indexOf("gzip") >= 0 && request.getAttribute(Dispatcher.__INCLUDE_REQUEST_URI) == null)
568                         {
569                             response.setHeader(HttpFields.__ContentEncoding, "gzip");
570                             data = gz;
571                             resLength = data.length();
572                         }
573                     }
574                 }
575                 writeHeaders(response, resource, resLength);
576             }
577
578             data.writeTo(out, 0, resLength);
579             return;
580         }
581
582         // Parse the satisfiable ranges
583
List JavaDoc ranges = InclusiveByteRange.satisfiableRanges(reqRanges, resLength);
584
585         // if there are no satisfiable ranges, send 416 response
586
if (ranges == null || ranges.size() == 0)
587         {
588             writeHeaders(response, resource, resLength);
589             response.setStatus(HttpResponse.__416_Requested_Range_Not_Satisfiable);
590             response.setHeader(HttpFields.__ContentRange, InclusiveByteRange.to416HeaderRangeString(resLength));
591             resource.writeTo(out, 0, resLength);
592             return;
593         }
594
595         // if there is only a single valid range (must be satisfiable
596
// since were here now), send that range with a 216 response
597
if (ranges.size() == 1)
598         {
599             InclusiveByteRange singleSatisfiableRange = (InclusiveByteRange) ranges.get(0);
600             long singleLength = singleSatisfiableRange.getSize(resLength);
601             writeHeaders(response, resource, singleLength);
602             response.setStatus(HttpResponse.__206_Partial_Content);
603             response.setHeader(HttpFields.__ContentRange, singleSatisfiableRange.toHeaderRangeString(resLength));
604             resource.writeTo(out, singleSatisfiableRange.getFirst(resLength), singleLength);
605             return;
606         }
607
608         // multiple non-overlapping valid ranges cause a multipart
609
// 216 response which does not require an overall
610
// content-length header
611
//
612
writeHeaders(response, resource, -1);
613         ResourceCache.ResourceMetaData metaData = _httpContext.getResourceMetaData(resource);
614         String JavaDoc encoding = metaData.getMimeType();
615         MultiPartResponse multi = new MultiPartResponse(response.getOutputStream());
616         response.setStatus(HttpResponse.__206_Partial_Content);
617
618         // If the request has a "Request-Range" header then we need to
619
// send an old style multipart/x-byteranges Content-Type. This
620
// keeps Netscape and acrobat happy. This is what Apache does.
621
String JavaDoc ctp;
622         if (request.getHeader(HttpFields.__RequestRange) != null)
623             ctp = "multipart/x-byteranges; boundary=";
624         else
625             ctp = "multipart/byteranges; boundary=";
626         response.setContentType(ctp + multi.getBoundary());
627
628         InputStream JavaDoc in = (resource instanceof CachedResource) ? null : resource.getInputStream();
629         long pos = 0;
630
631         for (int i = 0; i < ranges.size(); i++)
632         {
633             InclusiveByteRange ibr = (InclusiveByteRange) ranges.get(i);
634             String JavaDoc header = HttpFields.__ContentRange + ": " + ibr.toHeaderRangeString(resLength);
635             multi.startPart(encoding, new String JavaDoc[]
636             { header});
637
638             long start = ibr.getFirst(resLength);
639             long size = ibr.getSize(resLength);
640             if (in != null)
641             {
642                 // Handle non cached resource
643
if (start < pos)
644                 {
645                     in.close();
646                     in = resource.getInputStream();
647                     pos = 0;
648                 }
649                 if (pos < start)
650                 {
651                     in.skip(start - pos);
652                     pos = start;
653                 }
654                 IO.copy(in, out, size);
655                 pos += size;
656             }
657             else
658                 // Handle cached resource
659
(resource).writeTo(out, start, size);
660
661         }
662         if (in != null)
663             in.close();
664         multi.close();
665
666         return;
667     }
668
669     /* ------------------------------------------------------------ */
670     protected void writeHeaders(HttpServletResponse JavaDoc response, Resource resource, long count) throws IOException JavaDoc
671     {
672         ResourceCache.ResourceMetaData metaData = _httpContext.getResourceMetaData(resource);
673
674         response.setContentType(metaData.getMimeType());
675         if (count != -1)
676         {
677             if (count == resource.length() && response instanceof ServletHttpResponse )
678                 response.setHeader(HttpFields.__ContentLength, metaData.getLength());
679             else
680                 response.setContentLength((int) count);
681         }
682
683         response.setHeader(HttpFields.__LastModified, metaData.getLastModified());
684
685         if (_acceptRanges)
686             response.setHeader(HttpFields.__AcceptRanges, "bytes");
687     }
688
689 }
690
Popular Tags