1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.jetty.servlet;
16
17 import java.io.File;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.OutputStream;
21 import java.net.MalformedURLException;
22 import java.util.Enumeration;
23 import java.util.List;
24 import java.util.Map.Entry;
25
26 import javax.servlet.RequestDispatcher;
27 import javax.servlet.ServletContext;
28 import javax.servlet.ServletException;
29 import javax.servlet.UnavailableException;
30 import javax.servlet.http.HttpServlet;
31 import javax.servlet.http.HttpServletRequest;
32 import javax.servlet.http.HttpServletResponse;
33
34 import org.mortbay.io.Buffer;
35 import org.mortbay.io.ByteArrayBuffer;
36 import org.mortbay.io.WriterOutputStream;
37 import org.mortbay.io.nio.DirectNIOBuffer;
38 import org.mortbay.io.nio.IndirectNIOBuffer;
39 import org.mortbay.io.nio.NIOBuffer;
40 import org.mortbay.jetty.Connector;
41 import org.mortbay.jetty.HttpConnection;
42 import org.mortbay.jetty.HttpContent;
43 import org.mortbay.jetty.HttpFields;
44 import org.mortbay.jetty.HttpHeaderValues;
45 import org.mortbay.jetty.HttpHeaders;
46 import org.mortbay.jetty.HttpMethods;
47 import org.mortbay.jetty.InclusiveByteRange;
48 import org.mortbay.jetty.MimeTypes;
49 import org.mortbay.jetty.ResourceCache;
50 import org.mortbay.jetty.Response;
51 import org.mortbay.jetty.handler.ContextHandler;
52 import org.mortbay.jetty.nio.NIOConnector;
53 import org.mortbay.log.Log;
54 import org.mortbay.resource.FileResource;
55 import org.mortbay.resource.Resource;
56 import org.mortbay.resource.ResourceFactory;
57 import org.mortbay.util.IO;
58 import org.mortbay.util.MultiPartOutputStream;
59 import org.mortbay.util.TypeUtil;
60 import org.mortbay.util.URIUtil;
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 public class DefaultServlet extends HttpServlet implements ResourceFactory
126 {
127 private ContextHandler.SContext _context;
128
129 private boolean _acceptRanges=true;
130 private boolean _dirAllowed=true;
131 private boolean _welcomeServlets=false;
132 private boolean _redirectWelcome=false;
133 private boolean _gzip=true;
134
135 private Resource _resourceBase;
136 private NIOResourceCache _nioCache;
137 private ResourceCache _bioCache;
138
139 private MimeTypes _mimeTypes;
140 private String[] _welcomes;
141 private boolean _aliases=false;
142 private boolean _useFileMappedBuffer=false;
143 ByteArrayBuffer _cacheControl;
144
145
146
147 public void init()
148 throws UnavailableException
149 {
150 ServletContext config=getServletContext();
151 _context = (ContextHandler.SContext)config;
152 _mimeTypes = _context.getContextHandler().getMimeTypes();
153
154 _welcomes = _context.getContextHandler().getWelcomeFiles();
155 if (_welcomes==null)
156 _welcomes=new String[] {"index.jsp","index.html"};
157
158 _acceptRanges=getInitBoolean("acceptRanges",_acceptRanges);
159 _dirAllowed=getInitBoolean("dirAllowed",_dirAllowed);
160 _welcomeServlets=getInitBoolean("welcomeServlets", _welcomeServlets);
161 _redirectWelcome=getInitBoolean("redirectWelcome",_redirectWelcome);
162 _gzip=getInitBoolean("gzip",_gzip);
163
164 _aliases=getInitBoolean("aliases",_aliases);
165
166 if (!_aliases && !FileResource.getCheckAliases())
167 throw new IllegalStateException("Alias checking disabled");
168 if (_aliases)
169 config.log("Aliases are enabled");
170
171 _useFileMappedBuffer=getInitBoolean("useFileMappedBuffer",_useFileMappedBuffer);
172
173 String rrb = getInitParameter("relativeResourceBase");
174 if (rrb!=null)
175 {
176 try
177 {
178 _resourceBase = _context.getContextHandler().getResource(URIUtil.SLASH).addPath(rrb);
179 }
180 catch (Exception e)
181 {
182 Log.warn(Log.EXCEPTION,e);
183 throw new UnavailableException(e.toString());
184 }
185 }
186
187 String rb=getInitParameter("resourceBase");
188 if (rrb != null && rb != null)
189 throw new UnavailableException("resourceBase & relativeResourceBase");
190
191 if (rb!=null)
192 {
193 try{_resourceBase=Resource.newResource(rb);}
194 catch (Exception e)
195 {
196 Log.warn(Log.EXCEPTION,e);
197 throw new UnavailableException(e.toString());
198 }
199 }
200
201 String t=getInitParameter("cacheControl");
202 if (t!=null)
203 _cacheControl=new ByteArrayBuffer(t);
204
205 try
206 {
207 if (_resourceBase==null)
208 _resourceBase = _context.getContextHandler().getResource(URIUtil.SLASH);
209
210 String cache_type =getInitParameter("cacheType");
211 int max_cache_size=getInitInt("maxCacheSize", -2);
212 int max_cached_file_size=getInitInt("maxCachedFileSize", -2);
213 int max_cached_files=getInitInt("maxCachedFiles", -2);
214
215 if (cache_type==null || "nio".equals(cache_type)|| "both".equals(cache_type))
216 {
217 if (max_cache_size==-2 || max_cache_size>0)
218 {
219 _nioCache=new NIOResourceCache(_mimeTypes);
220 if (max_cache_size>0)
221 _nioCache.setMaxCacheSize(max_cache_size);
222 if (max_cached_file_size>=-1)
223 _nioCache.setMaxCachedFileSize(max_cached_file_size);
224 if (max_cached_files>=-1)
225 _nioCache.setMaxCachedFiles(max_cached_files);
226 _nioCache.start();
227 }
228 }
229 if ("bio".equals(cache_type)|| "both".equals(cache_type))
230 {
231 if (max_cache_size==-2 || max_cache_size>0)
232 {
233 _bioCache=new ResourceCache(_mimeTypes);
234 if (max_cache_size>0)
235 _bioCache.setMaxCacheSize(max_cache_size);
236 if (max_cached_file_size>=-1)
237 _bioCache.setMaxCachedFileSize(max_cached_file_size);
238 if (max_cached_files>=-1)
239 _bioCache.setMaxCachedFiles(max_cached_files);
240 _bioCache.start();
241 }
242 }
243 if (_nioCache==null)
244 _bioCache=null;
245
246 }
247 catch (Exception e)
248 {
249 Log.warn(Log.EXCEPTION,e);
250 throw new UnavailableException(e.toString());
251 }
252
253 if (Log.isDebugEnabled()) Log.debug("resource base = "+_resourceBase);
254 }
255
256
257 public String getInitParameter(String name)
258 {
259 String value=getServletContext().getInitParameter("org.mortbay.jetty.servlet.Default."+name);
260 if (value==null)
261 value=super.getInitParameter(name);
262 return value;
263 }
264
265
266 private boolean getInitBoolean(String name, boolean dft)
267 {
268 String value=getInitParameter(name);
269 if (value==null || value.length()==0)
270 return dft;
271 return (value.startsWith("t")||
272 value.startsWith("T")||
273 value.startsWith("y")||
274 value.startsWith("Y")||
275 value.startsWith("1"));
276 }
277
278
279 private int getInitInt(String name, int dft)
280 {
281 String value=getInitParameter(name);
282 if (value==null)
283 value=getInitParameter(name);
284 if (value!=null && value.length()>0)
285 return Integer.parseInt(value);
286 return dft;
287 }
288
289
290
291
292
293
294
295
296
297 public Resource getResource(String pathInContext)
298 {
299 if (_resourceBase==null)
300 return null;
301 Resource r=null;
302 try
303 {
304 r = _resourceBase.addPath(pathInContext);
305 if (!_aliases && r.getAlias()!=null)
306 {
307 if (r.exists())
308 Log.warn("Aliased resource: "+r+"=="+r.getAlias());
309 return null;
310 }
311 if (Log.isDebugEnabled()) Log.debug("RESOURCE="+r);
312 }
313 catch (IOException e)
314 {
315 Log.ignore(e);
316 }
317 return r;
318 }
319
320
321 protected void doGet(HttpServletRequest request, HttpServletResponse response)
322 throws ServletException, IOException
323 {
324 String servletPath=null;
325 String pathInfo=null;
326 Enumeration reqRanges = null;
327 Boolean included =(Boolean)request.getAttribute(Dispatcher.__INCLUDE_JETTY);
328 if (included!=null && included.booleanValue())
329 {
330 servletPath=(String)request.getAttribute(Dispatcher.__INCLUDE_SERVLET_PATH);
331 pathInfo=(String)request.getAttribute(Dispatcher.__INCLUDE_PATH_INFO);
332 if (servletPath==null)
333 {
334 servletPath=request.getServletPath();
335 pathInfo=request.getPathInfo();
336 }
337 }
338 else
339 {
340 included=Boolean.FALSE;
341 servletPath=request.getServletPath();
342 pathInfo=request.getPathInfo();
343
344
345 reqRanges = request.getHeaders(HttpHeaders.RANGE);
346 if (reqRanges!=null && !reqRanges.hasMoreElements())
347 reqRanges=null;
348 }
349
350 String pathInContext=URIUtil.addPaths(servletPath,pathInfo);
351 boolean endsWithSlash=pathInContext.endsWith(URIUtil.SLASH);
352
353
354 String pathInContextGz=null;
355 boolean gzip=false;
356 if (!included.booleanValue() && _gzip && reqRanges==null && !endsWithSlash )
357 {
358 String accept=request.getHeader(HttpHeaders.ACCEPT_ENCODING);
359 if (accept!=null && accept.indexOf("gzip")>=0)
360 gzip=true;
361 }
362
363
364 Resource resource=null;
365 HttpContent content=null;
366
367 Connector connector = HttpConnection.getCurrentConnection().getConnector();
368 ResourceCache cache=(connector instanceof NIOConnector) ?_nioCache:_bioCache;
369 try
370 {
371
372 if (gzip)
373 {
374 pathInContextGz=pathInContext+".gz";
375 resource=getResource(pathInContextGz);
376
377 if (resource==null || !resource.exists()|| resource.isDirectory())
378 {
379 gzip=false;
380 pathInContextGz=null;
381 }
382 else if (cache!=null)
383 {
384 content=cache.lookup(pathInContextGz,resource);
385 if (content!=null)
386 resource=content.getResource();
387 }
388
389 if (resource==null || !resource.exists()|| resource.isDirectory())
390 {
391 gzip=false;
392 pathInContextGz=null;
393 }
394 }
395
396
397 if (!gzip)
398 {
399 if (cache==null)
400 resource=getResource(pathInContext);
401 else
402 {
403 content=cache.lookup(pathInContext,this);
404
405 if (content!=null)
406 resource=content.getResource();
407 else
408 resource=getResource(pathInContext);
409 }
410 }
411
412 if (Log.isDebugEnabled())
413 Log.debug("resource="+resource+(content!=null?" content":""));
414
415
416 if (resource==null || !resource.exists())
417 response.sendError(HttpServletResponse.SC_NOT_FOUND);
418 else if (!resource.isDirectory())
419 {
420 if (endsWithSlash && _aliases && pathInContext.length()>1)
421 {
422 String q=request.getQueryString();
423 pathInContext=pathInContext.substring(0,pathInContext.length()-1);
424 if (q!=null&&q.length()!=0)
425 pathInContext+="?"+q;
426 response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths( _context.getContextPath(),pathInContext)));
427 }
428 else
429 {
430
431 if (content==null)
432 content=new UnCachedContent(resource);
433
434 if (included.booleanValue() || passConditionalHeaders(request,response, resource,content))
435 {
436 if (gzip)
437 {
438 response.setHeader(HttpHeaders.CONTENT_ENCODING,"gzip");
439 String mt=_context.getMimeType(pathInContext);
440 if (mt!=null)
441 response.setContentType(mt);
442 }
443 sendData(request,response,included.booleanValue(),resource,content,reqRanges);
444 }
445 }
446 }
447 else
448 {
449 String welcome=null;
450
451 if (!endsWithSlash || (pathInContext.length()==1 && request.getAttribute("org.mortbay.jetty.nullPathInfo")!=null))
452 {
453 StringBuffer buf=request.getRequestURL();
454 int param=buf.lastIndexOf(";");
455 if (param<0)
456 buf.append('/');
457 else
458 buf.insert(param,'/');
459 String q=request.getQueryString();
460 if (q!=null&&q.length()!=0)
461 {
462 buf.append('?');
463 buf.append(q);
464 }
465 response.setContentLength(0);
466 response.sendRedirect(response.encodeRedirectURL(buf.toString()));
467 }
468
469 else if (null!=(welcome=getWelcomeFile(resource)))
470 {
471 String ipath=URIUtil.addPaths(pathInContext,welcome);
472 if (_redirectWelcome)
473 {
474
475 response.setContentLength(0);
476 String q=request.getQueryString();
477 if (q!=null&&q.length()!=0)
478 response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths( _context.getContextPath(),ipath)+"?"+q));
479 else
480 response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths( _context.getContextPath(),ipath)));
481 }
482 else
483 {
484
485 RequestDispatcher dispatcher=request.getRequestDispatcher(ipath);
486 if (dispatcher!=null)
487 {
488 if (included.booleanValue())
489 dispatcher.include(request,response);
490 else
491 {
492 request.setAttribute("org.mortbay.jetty.welcome",ipath);
493 dispatcher.forward(request,response);
494 }
495 }
496 }
497 }
498 else
499 {
500 content=new UnCachedContent(resource);
501 if (included.booleanValue() || passConditionalHeaders(request,response, resource,content))
502 sendDirectory(request,response,resource,pathInContext.length()>1);
503 }
504 }
505 }
506 catch(IllegalArgumentException e)
507 {
508 Log.warn(Log.EXCEPTION,e);
509 if(!response.isCommitted())
510 response.sendError(500, e.getMessage());
511 }
512 finally
513 {
514 if (content!=null)
515 content.release();
516 else if (resource!=null)
517 resource.release();
518 }
519
520 }
521
522
523 protected void doPost(HttpServletRequest request, HttpServletResponse response)
524 throws ServletException, IOException
525 {
526 doGet(request,response);
527 }
528
529
530
531
532
533 protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
534 {
535 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
536 }
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551 private String getWelcomeFile(Resource resource) throws MalformedURLException, IOException
552 {
553 if (!resource.isDirectory() || _welcomes==null)
554 return null;
555
556 for (int i=0;i<_welcomes.length;i++)
557 {
558 Resource welcome=resource.addPath(_welcomes[i]);
559 if (welcome.exists())
560 return _welcomes[i];
561 }
562
563 if (_welcomeServlets)
564 {
565 ServletHandler servletHandler = (ServletHandler)_context.getContextHandler().getChildHandlerByClass(ServletHandler.class);
566 for (int i=0;i<_welcomes.length;i++)
567 {
568 if (servletHandler.matchesPath(_welcomes[i]))
569 return _welcomes[i];
570 }
571 }
572
573 return null;
574 }
575
576
577
578
579 protected boolean passConditionalHeaders(HttpServletRequest request,HttpServletResponse response, Resource resource, HttpContent content)
580 throws IOException
581 {
582 try
583 {
584 if (!request.getMethod().equals(HttpMethods.HEAD) )
585 {
586 String ifms=request.getHeader(HttpHeaders.IF_MODIFIED_SINCE);
587 if (ifms!=null)
588 {
589 if (content!=null)
590 {
591 Buffer mdlm=content.getLastModified();
592 if (mdlm!=null)
593 {
594 if (ifms.equals(mdlm.toString()))
595 {
596 response.reset();
597 response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
598 response.flushBuffer();
599 return false;
600 }
601 }
602 }
603
604 long ifmsl=request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
605 if (ifmsl!=-1)
606 {
607 if (resource.lastModified()/1000 <= ifmsl/1000)
608 {
609 response.reset();
610 response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
611 response.flushBuffer();
612 return false;
613 }
614 }
615 }
616
617
618 long date=request.getDateHeader(HttpHeaders.IF_UNMODIFIED_SINCE);
619
620 if (date!=-1)
621 {
622 if (resource.lastModified()/1000 > date/1000)
623 {
624 response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
625 return false;
626 }
627 }
628
629 }
630 }
631 catch(IllegalArgumentException iae)
632 {
633 if(!response.isCommitted())
634 response.sendError(400, iae.getMessage());
635 throw iae;
636 }
637 return true;
638 }
639
640
641
642 protected void sendDirectory(HttpServletRequest request,
643 HttpServletResponse response,
644 Resource resource,
645 boolean parent)
646 throws IOException
647 {
648 if (!_dirAllowed)
649 {
650 response.sendError(HttpServletResponse.SC_FORBIDDEN);
651 return;
652 }
653
654 byte[] data=null;
655 String base = URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH);
656 String dir = resource.getListHTML(base,parent);
657 if (dir==null)
658 {
659 response.sendError(HttpServletResponse.SC_FORBIDDEN,
660 "No directory");
661 return;
662 }
663
664 data=dir.getBytes("UTF-8");
665 response.setContentType("text/html; charset=UTF-8");
666 response.setContentLength(data.length);
667 response.getOutputStream().write(data);
668 }
669
670
671 protected void sendData(HttpServletRequest request,
672 HttpServletResponse response,
673 boolean include,
674 Resource resource,
675 HttpContent content,
676 Enumeration reqRanges)
677 throws IOException
678 {
679 long content_length=resource.length();
680
681
682 OutputStream out =null;
683 try{out = response.getOutputStream();}
684 catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());}
685
686 if ( reqRanges == null || !reqRanges.hasMoreElements())
687 {
688
689 if (include)
690 {
691 resource.writeTo(out,0,content_length);
692 }
693 else
694 {
695
696 if (out instanceof HttpConnection.Output)
697 {
698 if (response instanceof Response)
699 {
700 writeOptionHeaders(((Response)response).getHttpFields());
701 ((HttpConnection.Output)out).sendContent(content);
702 }
703 else if (content.getBuffer()!=null)
704 {
705 writeHeaders(response,content,content_length);
706 ((HttpConnection.Output)out).sendContent(content.getBuffer());
707 }
708 else
709 {
710 writeHeaders(response,content,content_length);
711 resource.writeTo(out,0,content_length);
712 }
713 }
714 else
715 {
716
717 writeHeaders(response,content,content_length);
718 resource.writeTo(out,0,content_length);
719 }
720 }
721 }
722 else
723 {
724
725 List ranges =InclusiveByteRange.satisfiableRanges(reqRanges,content_length);
726
727
728 if (ranges==null || ranges.size()==0)
729 {
730 writeHeaders(response, content, content_length);
731 response.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
732 response.setHeader(HttpHeaders.CONTENT_RANGE,
733 InclusiveByteRange.to416HeaderRangeString(content_length));
734 resource.writeTo(out,0,content_length);
735 return;
736 }
737
738
739
740
741 if ( ranges.size()== 1)
742 {
743 InclusiveByteRange singleSatisfiableRange =
744 (InclusiveByteRange)ranges.get(0);
745 long singleLength = singleSatisfiableRange.getSize(content_length);
746 writeHeaders(response,content,singleLength );
747 response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
748 response.setHeader(HttpHeaders.CONTENT_RANGE,
749 singleSatisfiableRange.toHeaderRangeString(content_length));
750 resource.writeTo(out,singleSatisfiableRange.getFirst(content_length),singleLength);
751 return;
752 }
753
754
755
756
757
758
759 writeHeaders(response,content,-1);
760 String mimetype=content.getContentType().toString();
761 MultiPartOutputStream multi = new MultiPartOutputStream(out);
762 response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
763
764
765
766
767 String ctp;
768 if (request.getHeader(HttpHeaders.REQUEST_RANGE)!=null)
769 ctp = "multipart/x-byteranges; boundary=";
770 else
771 ctp = "multipart/byteranges; boundary=";
772 response.setContentType(ctp+multi.getBoundary());
773
774 InputStream in=resource.getInputStream();
775 long pos=0;
776
777 for (int i=0;i<ranges.size();i++)
778 {
779 InclusiveByteRange ibr = (InclusiveByteRange) ranges.get(i);
780 String header=HttpHeaders.CONTENT_RANGE+": "+
781 ibr.toHeaderRangeString(content_length);
782 multi.startPart(mimetype,new String[]{header});
783
784 long start=ibr.getFirst(content_length);
785 long size=ibr.getSize(content_length);
786 if (in!=null)
787 {
788
789 if (start<pos)
790 {
791 in.close();
792 in=resource.getInputStream();
793 pos=0;
794 }
795 if (pos<start)
796 {
797 in.skip(start-pos);
798 pos=start;
799 }
800 IO.copy(in,multi,size);
801 pos+=size;
802 }
803 else
804
805 (resource).writeTo(multi,start,size);
806
807 }
808 if (in!=null)
809 in.close();
810 multi.close();
811 }
812 return;
813 }
814
815
816 protected void writeHeaders(HttpServletResponse response,HttpContent content,long count)
817 throws IOException
818 {
819 if (content.getContentType()!=null && response.getContentType()==null)
820 response.setContentType(content.getContentType().toString());
821
822 if (response instanceof Response)
823 {
824 Response r=(Response)response;
825 HttpFields fields = r.getHttpFields();
826
827 if (content.getLastModified()!=null)
828 fields.put(HttpHeaders.LAST_MODIFIED_BUFFER,content.getLastModified(),content.getResource().lastModified());
829 else if (content.getResource()!=null)
830 {
831 long lml=content.getResource().lastModified();
832 if (lml!=-1)
833 fields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER,lml);
834 }
835
836 if (count != -1)
837 r.setLongContentLength(count);
838
839 writeOptionHeaders(fields);
840 }
841 else
842 {
843 long lml=content.getResource().lastModified();
844 if (lml>=0)
845 response.setDateHeader(HttpHeaders.LAST_MODIFIED,lml);
846
847 if (count != -1)
848 {
849 if (count<Integer.MAX_VALUE)
850 response.setContentLength((int)count);
851 else
852 response.setHeader(HttpHeaders.CONTENT_LENGTH,TypeUtil.toString(count));
853 }
854
855 writeOptionHeaders(response);
856 }
857 }
858
859
860 protected void writeOptionHeaders(HttpFields fields) throws IOException
861 {
862 if (_acceptRanges)
863 fields.put(HttpHeaders.ACCEPT_RANGES_BUFFER,HttpHeaderValues.BYTES_BUFFER);
864
865 if (_cacheControl!=null)
866 fields.put(HttpHeaders.CACHE_CONTROL_BUFFER,_cacheControl);
867 }
868
869
870 protected void writeOptionHeaders(HttpServletResponse response) throws IOException
871 {
872 if (_acceptRanges)
873 response.setHeader(HttpHeaders.ACCEPT_RANGES,"bytes");
874
875 if (_cacheControl!=null)
876 response.setHeader(HttpHeaders.CACHE_CONTROL,_cacheControl.toString());
877 }
878
879
880
881
882
883 public void destroy()
884 {
885 try
886 {
887 if (_nioCache!=null)
888 _nioCache.stop();
889 if (_bioCache!=null)
890 _bioCache.stop();
891 }
892 catch(Exception e)
893 {
894 Log.warn(Log.EXCEPTION,e);
895 }
896 finally
897 {
898 super.destroy();
899 }
900 }
901
902
903
904
905 private class UnCachedContent implements HttpContent
906 {
907 Resource _resource;
908
909 UnCachedContent(Resource resource)
910 {
911 _resource=resource;
912 }
913
914
915 public Buffer getContentType()
916 {
917 return _mimeTypes.getMimeByExtension(_resource.toString());
918 }
919
920
921 public Buffer getLastModified()
922 {
923 return null;
924 }
925
926
927 public Buffer getBuffer()
928 {
929 return null;
930 }
931
932
933 public long getContentLength()
934 {
935 return _resource.length();
936 }
937
938
939 public InputStream getInputStream() throws IOException
940 {
941 return _resource.getInputStream();
942 }
943
944
945 public Resource getResource()
946 {
947 return _resource;
948 }
949
950
951 public void release()
952 {
953 _resource.release();
954 _resource=null;
955 }
956
957 }
958
959
960
961 class NIOResourceCache extends ResourceCache
962 {
963
964 public NIOResourceCache(MimeTypes mimeTypes)
965 {
966 super(mimeTypes);
967 }
968
969
970 protected void fill(Content content) throws IOException
971 {
972 Buffer buffer=null;
973 Resource resource=content.getResource();
974 long length=resource.length();
975
976 if (_useFileMappedBuffer && resource.getFile()!=null)
977 {
978 buffer = new DirectNIOBuffer(resource.getFile());
979 }
980 else
981 {
982 InputStream is = resource.getInputStream();
983 try
984 {
985 Connector connector = HttpConnection.getCurrentConnection().getConnector();
986 buffer = ((NIOConnector)connector).getUseDirectBuffers()?
987 (NIOBuffer)new DirectNIOBuffer((int)length):
988 (NIOBuffer)new IndirectNIOBuffer((int)length);
989
990 }
991 catch(OutOfMemoryError e)
992 {
993 Log.warn(e.toString());
994 Log.debug(e);
995 buffer = new IndirectNIOBuffer((int) length);
996 }
997 buffer.readFrom(is,(int)length);
998 is.close();
999 }
1000 content.setBuffer(buffer);
1001 }
1002 }
1003 }