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