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
421 if (content==null)
422 content=new UnCachedContent(resource);
423
424 if (included.booleanValue() || passConditionalHeaders(request,response, resource,content))
425 {
426 if (gzip)
427 {
428 response.setHeader(HttpHeaders.CONTENT_ENCODING,"gzip");
429 String mt=_context.getMimeType(pathInContext);
430 if (mt!=null)
431 response.setContentType(mt);
432 }
433 sendData(request,response,included.booleanValue(),resource,content,reqRanges);
434 }
435 }
436 else
437 {
438 String welcome=null;
439
440 if (!endsWithSlash || (pathInContext.length()==1 && request.getAttribute("org.mortbay.jetty.nullPathInfo")!=null))
441 {
442 StringBuffer buf=request.getRequestURL();
443 int param=buf.lastIndexOf(";");
444 if (param<0)
445 buf.append('/');
446 else
447 buf.insert(param,'/');
448 String q=request.getQueryString();
449 if (q!=null&&q.length()!=0)
450 {
451 buf.append('?');
452 buf.append(q);
453 }
454 response.setContentLength(0);
455 response.sendRedirect(response.encodeRedirectURL(buf.toString()));
456 }
457
458 else if (null!=(welcome=getWelcomeFile(resource)))
459 {
460 String ipath=URIUtil.addPaths(pathInContext,welcome);
461 if (_redirectWelcome)
462 {
463
464 response.setContentLength(0);
465 String q=request.getQueryString();
466 if (q!=null&&q.length()!=0)
467 response.sendRedirect(URIUtil.addPaths( _context.getContextPath(),ipath)+"?"+q);
468 else
469 response.sendRedirect(URIUtil.addPaths( _context.getContextPath(),ipath));
470 }
471 else
472 {
473
474 RequestDispatcher dispatcher=request.getRequestDispatcher(ipath);
475 if (dispatcher!=null)
476 {
477 if (included.booleanValue())
478 dispatcher.include(request,response);
479 else
480 {
481 request.setAttribute("org.mortbay.jetty.welcome",ipath);
482 dispatcher.forward(request,response);
483 }
484 }
485 }
486 }
487 else
488 {
489 content=new UnCachedContent(resource);
490 if (included.booleanValue() || passConditionalHeaders(request,response, resource,content))
491 sendDirectory(request,response,resource,pathInContext.length()>1);
492 }
493 }
494 }
495 catch(IllegalArgumentException e)
496 {
497 Log.warn(Log.EXCEPTION,e);
498 if(!response.isCommitted())
499 response.sendError(500, e.getMessage());
500 }
501 finally
502 {
503 if (content!=null)
504 content.release();
505 else if (resource!=null)
506 resource.release();
507 }
508
509 }
510
511
512 protected void doPost(HttpServletRequest request, HttpServletResponse response)
513 throws ServletException, IOException
514 {
515 doGet(request,response);
516 }
517
518
519
520
521
522 protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
523 {
524 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
525 }
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540 private String getWelcomeFile(Resource resource) throws MalformedURLException, IOException
541 {
542 if (!resource.isDirectory() || _welcomes==null)
543 return null;
544
545 for (int i=0;i<_welcomes.length;i++)
546 {
547 Resource welcome=resource.addPath(_welcomes[i]);
548 if (welcome.exists())
549 return _welcomes[i];
550 }
551
552 if (_welcomeServlets)
553 {
554 ServletHandler servletHandler = (ServletHandler)_context.getContextHandler().getChildHandlerByClass(ServletHandler.class);
555 for (int i=0;i<_welcomes.length;i++)
556 {
557 if (servletHandler.matchesPath(_welcomes[i]))
558 return _welcomes[i];
559 }
560 }
561
562 return null;
563 }
564
565
566
567
568 protected boolean passConditionalHeaders(HttpServletRequest request,HttpServletResponse response, Resource resource, HttpContent content)
569 throws IOException
570 {
571 try
572 {
573 if (!request.getMethod().equals(HttpMethods.HEAD) )
574 {
575 String ifms=request.getHeader(HttpHeaders.IF_MODIFIED_SINCE);
576 if (ifms!=null)
577 {
578 if (content!=null)
579 {
580 Buffer mdlm=content.getLastModified();
581 if (mdlm!=null)
582 {
583 if (ifms.equals(mdlm.toString()))
584 {
585 response.reset();
586 response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
587 response.flushBuffer();
588 return false;
589 }
590 }
591 }
592
593 long ifmsl=request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
594 if (ifmsl!=-1)
595 {
596 if (resource.lastModified()/1000 <= ifmsl/1000)
597 {
598 response.reset();
599 response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
600 response.flushBuffer();
601 return false;
602 }
603 }
604 }
605
606
607 long date=request.getDateHeader(HttpHeaders.IF_UNMODIFIED_SINCE);
608
609 if (date!=-1)
610 {
611 if (resource.lastModified()/1000 > date/1000)
612 {
613 response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
614 return false;
615 }
616 }
617
618 }
619 }
620 catch(IllegalArgumentException iae)
621 {
622 if(!response.isCommitted())
623 response.sendError(400, iae.getMessage());
624 throw iae;
625 }
626 return true;
627 }
628
629
630
631 protected void sendDirectory(HttpServletRequest request,
632 HttpServletResponse response,
633 Resource resource,
634 boolean parent)
635 throws IOException
636 {
637 if (!_dirAllowed)
638 {
639 response.sendError(HttpServletResponse.SC_FORBIDDEN);
640 return;
641 }
642
643 byte[] data=null;
644 String base = URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH);
645 String dir = resource.getListHTML(base,parent);
646 if (dir==null)
647 {
648 response.sendError(HttpServletResponse.SC_FORBIDDEN,
649 "No directory");
650 return;
651 }
652
653 data=dir.getBytes("UTF-8");
654 response.setContentType("text/html; charset=UTF-8");
655 response.setContentLength(data.length);
656 response.getOutputStream().write(data);
657 }
658
659
660 protected void sendData(HttpServletRequest request,
661 HttpServletResponse response,
662 boolean include,
663 Resource resource,
664 HttpContent content,
665 Enumeration reqRanges)
666 throws IOException
667 {
668 long content_length=resource.length();
669
670
671 OutputStream out =null;
672 try{out = response.getOutputStream();}
673 catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());}
674
675 if ( reqRanges == null || !reqRanges.hasMoreElements())
676 {
677
678 if (include)
679 {
680 resource.writeTo(out,0,content_length);
681 }
682 else
683 {
684
685 if (out instanceof HttpConnection.Output)
686 {
687 if (response instanceof Response)
688 {
689 writeOptionHeaders(((Response)response).getHttpFields());
690 ((HttpConnection.Output)out).sendContent(content);
691 }
692 else
693 {
694 writeHeaders(response,content,content_length);
695 ((HttpConnection.Output)out).sendContent(content.getBuffer());
696 }
697 }
698 else
699 {
700
701 writeHeaders(response,content,content_length);
702 resource.writeTo(out,0,content_length);
703 }
704 }
705 }
706 else
707 {
708
709 List ranges =InclusiveByteRange.satisfiableRanges(reqRanges,content_length);
710
711
712 if (ranges==null || ranges.size()==0)
713 {
714 writeHeaders(response, content, content_length);
715 response.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
716 response.setHeader(HttpHeaders.CONTENT_RANGE,
717 InclusiveByteRange.to416HeaderRangeString(content_length));
718 resource.writeTo(out,0,content_length);
719 return;
720 }
721
722
723
724
725 if ( ranges.size()== 1)
726 {
727 InclusiveByteRange singleSatisfiableRange =
728 (InclusiveByteRange)ranges.get(0);
729 long singleLength = singleSatisfiableRange.getSize(content_length);
730 writeHeaders(response,content,singleLength );
731 response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
732 response.setHeader(HttpHeaders.CONTENT_RANGE,
733 singleSatisfiableRange.toHeaderRangeString(content_length));
734 resource.writeTo(out,singleSatisfiableRange.getFirst(content_length),singleLength);
735 return;
736 }
737
738
739
740
741
742
743 writeHeaders(response,content,-1);
744 String mimetype=content.getContentType().toString();
745 MultiPartOutputStream multi = new MultiPartOutputStream(out);
746 response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
747
748
749
750
751 String ctp;
752 if (request.getHeader(HttpHeaders.REQUEST_RANGE)!=null)
753 ctp = "multipart/x-byteranges; boundary=";
754 else
755 ctp = "multipart/byteranges; boundary=";
756 response.setContentType(ctp+multi.getBoundary());
757
758 InputStream in=resource.getInputStream();
759 long pos=0;
760
761 for (int i=0;i<ranges.size();i++)
762 {
763 InclusiveByteRange ibr = (InclusiveByteRange) ranges.get(i);
764 String header=HttpHeaders.CONTENT_RANGE+": "+
765 ibr.toHeaderRangeString(content_length);
766 multi.startPart(mimetype,new String[]{header});
767
768 long start=ibr.getFirst(content_length);
769 long size=ibr.getSize(content_length);
770 if (in!=null)
771 {
772
773 if (start<pos)
774 {
775 in.close();
776 in=resource.getInputStream();
777 pos=0;
778 }
779 if (pos<start)
780 {
781 in.skip(start-pos);
782 pos=start;
783 }
784 IO.copy(in,multi,size);
785 pos+=size;
786 }
787 else
788
789 (resource).writeTo(multi,start,size);
790
791 }
792 if (in!=null)
793 in.close();
794 multi.close();
795 }
796 return;
797 }
798
799
800 protected void writeHeaders(HttpServletResponse response,HttpContent content,long count)
801 throws IOException
802 {
803 if (content.getContentType()!=null && response.getContentType()==null)
804 response.setContentType(content.getContentType().toString());
805
806 if (response instanceof Response)
807 {
808 Response r=(Response)response;
809 HttpFields fields = r.getHttpFields();
810
811 if (content.getLastModified()!=null)
812 fields.put(HttpHeaders.LAST_MODIFIED_BUFFER,content.getLastModified(),content.getResource().lastModified());
813 else if (content.getResource()!=null)
814 {
815 long lml=content.getResource().lastModified();
816 if (lml!=-1)
817 fields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER,lml);
818 }
819
820 if (count != -1)
821 r.setLongContentLength(count);
822
823 writeOptionHeaders(fields);
824 }
825 else
826 {
827 long lml=content.getResource().lastModified();
828 if (lml>=0)
829 response.setDateHeader(HttpHeaders.LAST_MODIFIED,lml);
830
831 if (count != -1)
832 {
833 if (count<Integer.MAX_VALUE)
834 response.setContentLength((int)count);
835 else
836 response.setHeader(HttpHeaders.CONTENT_LENGTH,TypeUtil.toString(count));
837 }
838
839 writeOptionHeaders(response);
840 }
841 }
842
843
844 protected void writeOptionHeaders(HttpFields fields) throws IOException
845 {
846 if (_acceptRanges)
847 fields.put(HttpHeaders.ACCEPT_RANGES_BUFFER,HttpHeaderValues.BYTES_BUFFER);
848
849 if (_cacheControl!=null)
850 fields.put(HttpHeaders.CACHE_CONTROL_BUFFER,_cacheControl);
851 }
852
853
854 protected void writeOptionHeaders(HttpServletResponse response) throws IOException
855 {
856 if (_acceptRanges)
857 response.setHeader(HttpHeaders.ACCEPT_RANGES,"bytes");
858
859 if (_cacheControl!=null)
860 response.setHeader(HttpHeaders.CACHE_CONTROL,_cacheControl.toString());
861 }
862
863
864
865
866
867 public void destroy()
868 {
869 try
870 {
871 if (_nioCache!=null)
872 _nioCache.stop();
873 if (_bioCache!=null)
874 _bioCache.stop();
875 }
876 catch(Exception e)
877 {
878 Log.warn(Log.EXCEPTION,e);
879 }
880 finally
881 {
882 super.destroy();
883 }
884 }
885
886
887
888
889 private class UnCachedContent implements HttpContent
890 {
891 Resource _resource;
892
893 UnCachedContent(Resource resource)
894 {
895 _resource=resource;
896 }
897
898
899 public Buffer getContentType()
900 {
901 return _mimeTypes.getMimeByExtension(_resource.toString());
902 }
903
904
905 public Buffer getLastModified()
906 {
907 return null;
908 }
909
910
911 public Buffer getBuffer()
912 {
913 return null;
914 }
915
916
917 public long getContentLength()
918 {
919 return _resource.length();
920 }
921
922
923 public InputStream getInputStream() throws IOException
924 {
925 return _resource.getInputStream();
926 }
927
928
929 public Resource getResource()
930 {
931 return _resource;
932 }
933
934
935 public void release()
936 {
937 _resource.release();
938 _resource=null;
939 }
940
941 }
942
943
944
945 class NIOResourceCache extends ResourceCache
946 {
947
948 public NIOResourceCache(MimeTypes mimeTypes)
949 {
950 super(mimeTypes);
951 }
952
953
954 protected void fill(Content content) throws IOException
955 {
956 Buffer buffer=null;
957 Resource resource=content.getResource();
958 long length=resource.length();
959
960 if (_useFileMappedBuffer && resource.getFile()!=null)
961 {
962 buffer = new DirectNIOBuffer(resource.getFile());
963 }
964 else
965 {
966 InputStream is = resource.getInputStream();
967 try
968 {
969 Connector connector = HttpConnection.getCurrentConnection().getConnector();
970 buffer = ((NIOConnector)connector).getUseDirectBuffers()?
971 (NIOBuffer)new DirectNIOBuffer((int)length):
972 (NIOBuffer)new IndirectNIOBuffer((int)length);
973
974 }
975 catch(OutOfMemoryError e)
976 {
977 Log.warn(e.toString());
978 Log.debug(e);
979 buffer = new IndirectNIOBuffer((int) length);
980 }
981 buffer.readFrom(is,(int)length);
982 is.close();
983 }
984 content.setBuffer(buffer);
985 }
986 }
987 }