📄 defaultservlet.java
字号:
HttpServletResponse response, boolean include, Resource resource, HttpContent content, Enumeration reqRanges) throws IOException { long content_length=resource.length(); // Get the output stream (or writer) OutputStream out =null; try{out = response.getOutputStream();} catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());} if ( reqRanges == null || !reqRanges.hasMoreElements()) { // if there were no ranges, send entire entity if (include) { resource.writeTo(out,0,content_length); } else { // See if a direct methods can be used? if (out instanceof HttpConnection.Output) { if (response instanceof Response) { writeOptionHeaders(((Response)response).getHttpFields()); ((HttpConnection.Output)out).sendContent(content); } else { writeHeaders(response,content,content_length); ((HttpConnection.Output)out).sendContent(content.getBuffer()); } } else { // Write content normally writeHeaders(response,content,content_length); resource.writeTo(out,0,content_length); } } } else { // Parse the satisfiable ranges List ranges =InclusiveByteRange.satisfiableRanges(reqRanges,content_length); // if there are no satisfiable ranges, send 416 response if (ranges==null || ranges.size()==0) { writeHeaders(response, content, content_length); response.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); response.setHeader(HttpHeaders.CONTENT_RANGE, InclusiveByteRange.to416HeaderRangeString(content_length)); resource.writeTo(out,0,content_length); return; } // if there is only a single valid range (must be satisfiable // since were here now), send that range with a 216 response if ( ranges.size()== 1) { InclusiveByteRange singleSatisfiableRange = (InclusiveByteRange)ranges.get(0); long singleLength = singleSatisfiableRange.getSize(content_length); writeHeaders(response,content,singleLength ); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); response.setHeader(HttpHeaders.CONTENT_RANGE, singleSatisfiableRange.toHeaderRangeString(content_length)); resource.writeTo(out,singleSatisfiableRange.getFirst(content_length),singleLength); return; } // multiple non-overlapping valid ranges cause a multipart // 216 response which does not require an overall // content-length header // writeHeaders(response,content,-1); String mimetype=content.getContentType().toString(); MultiPartOutputStream multi = new MultiPartOutputStream(out); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // If the request has a "Request-Range" header then we need to // send an old style multipart/x-byteranges Content-Type. This // keeps Netscape and acrobat happy. This is what Apache does. String ctp; if (request.getHeader(HttpHeaders.REQUEST_RANGE)!=null) ctp = "multipart/x-byteranges; boundary="; else ctp = "multipart/byteranges; boundary="; response.setContentType(ctp+multi.getBoundary()); InputStream in=resource.getInputStream(); long pos=0; for (int i=0;i<ranges.size();i++) { InclusiveByteRange ibr = (InclusiveByteRange) ranges.get(i); String header=HttpHeaders.CONTENT_RANGE+": "+ ibr.toHeaderRangeString(content_length); multi.startPart(mimetype,new String[]{header}); long start=ibr.getFirst(content_length); long size=ibr.getSize(content_length); if (in!=null) { // Handle non cached resource if (start<pos) { in.close(); in=resource.getInputStream(); pos=0; } if (pos<start) { in.skip(start-pos); pos=start; } IO.copy(in,multi,size); pos+=size; } else // Handle cached resource (resource).writeTo(multi,start,size); } if (in!=null) in.close(); multi.close(); } return; } /* ------------------------------------------------------------ */ protected void writeHeaders(HttpServletResponse response,HttpContent content,long count) throws IOException { if (content.getContentType()!=null && response.getContentType()==null) response.setContentType(content.getContentType().toString()); if (response instanceof Response) { Response r=(Response)response; HttpFields fields = r.getHttpFields(); if (content.getLastModified()!=null) fields.put(HttpHeaders.LAST_MODIFIED_BUFFER,content.getLastModified(),content.getResource().lastModified()); else if (content.getResource()!=null) { long lml=content.getResource().lastModified(); if (lml!=-1) fields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER,lml); } if (count != -1) r.setLongContentLength(count); writeOptionHeaders(fields); } else { long lml=content.getResource().lastModified(); if (lml>=0) response.setDateHeader(HttpHeaders.LAST_MODIFIED,lml); if (count != -1) { if (count<Integer.MAX_VALUE) response.setContentLength((int)count); else response.setHeader(HttpHeaders.CONTENT_LENGTH,TypeUtil.toString(count)); } writeOptionHeaders(response); } } /* ------------------------------------------------------------ */ protected void writeOptionHeaders(HttpFields fields) throws IOException { if (_acceptRanges) fields.put(HttpHeaders.ACCEPT_RANGES_BUFFER,HttpHeaderValues.BYTES_BUFFER); if (_cacheControl!=null) fields.put(HttpHeaders.CACHE_CONTROL_BUFFER,_cacheControl); } /* ------------------------------------------------------------ */ protected void writeOptionHeaders(HttpServletResponse response) throws IOException { if (_acceptRanges) response.setHeader(HttpHeaders.ACCEPT_RANGES,"bytes"); if (_cacheControl!=null) response.setHeader(HttpHeaders.CACHE_CONTROL,_cacheControl.toString()); } /* ------------------------------------------------------------ */ /* * @see javax.servlet.Servlet#destroy() */ public void destroy() { try { if (_nioCache!=null) _nioCache.stop(); if (_bioCache!=null) _bioCache.stop(); } catch(Exception e) { Log.warn(Log.EXCEPTION,e); } finally { super.destroy(); } } /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ private class UnCachedContent implements HttpContent { Resource _resource; UnCachedContent(Resource resource) { _resource=resource; } /* ------------------------------------------------------------ */ public Buffer getContentType() { return _mimeTypes.getMimeByExtension(_resource.toString()); } /* ------------------------------------------------------------ */ public Buffer getLastModified() { return null; } /* ------------------------------------------------------------ */ public Buffer getBuffer() { return null; } /* ------------------------------------------------------------ */ public long getContentLength() { return _resource.length(); } /* ------------------------------------------------------------ */ public InputStream getInputStream() throws IOException { return _resource.getInputStream(); } /* ------------------------------------------------------------ */ public Resource getResource() { return _resource; } /* ------------------------------------------------------------ */ public void release() { _resource.release(); _resource=null; } } /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ class NIOResourceCache extends ResourceCache { /* ------------------------------------------------------------ */ public NIOResourceCache(MimeTypes mimeTypes) { super(mimeTypes); } /* ------------------------------------------------------------ */ protected void fill(Content content) throws IOException { Buffer buffer=null; Resource resource=content.getResource(); long length=resource.length(); if (_useFileMappedBuffer && resource.getFile()!=null) { buffer = new DirectNIOBuffer(resource.getFile()); } else { InputStream is = resource.getInputStream(); try { Connector connector = HttpConnection.getCurrentConnection().getConnector(); buffer = ((NIOConnector)connector).getUseDirectBuffers()? (NIOBuffer)new DirectNIOBuffer((int)length): (NIOBuffer)new IndirectNIOBuffer((int)length); } catch(OutOfMemoryError e) { Log.warn(e.toString()); Log.debug(e); buffer = new IndirectNIOBuffer((int) length); } buffer.readFrom(is,(int)length); is.close(); } content.setBuffer(buffer); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -