responsestream.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 811 行 · 第 1/2 页
JAVA
811 行
} else if (isFinished) writeHeaders(getBufferLength()); else writeHeaders(-1); int bufferStart = _bufferStartOffset; int bufferOffset = _next.getBufferOffset(); // server/05e2 if (length == 0 && ! isFinished && bufferStart == bufferOffset) return; long contentLengthHeader = _response.getContentLengthHeader(); // Can't write beyond the content length if (0 < contentLengthHeader && contentLengthHeader < length + _contentLength) { if (lengthException(buf, offset, length, contentLengthHeader)) return; length = (int) (contentLengthHeader - _contentLength); } if (_next != null && ! _isHead) { if (length > 0 && log.isLoggable(Level.FINE)) { log.fine(dbgId() + "write-chunk(" + length + ")"); } if (! _chunkedEncoding) { byte []nextBuffer = _next.getBuffer(); int nextOffset = _next.getBufferOffset(); if (nextOffset + length < nextBuffer.length) { System.arraycopy(buf, offset, nextBuffer, nextOffset, length); _next.setBufferOffset(nextOffset + length); } else { _isCommitted = true; _next.write(buf, offset, length); if (log.isLoggable(Level.FINE)) log.fine(dbgId() + "write-data(" + _tailChunkedLength + ")"); } if (_cacheStream != null) writeCache(buf, offset, length); } else { byte []buffer = _next.getBuffer(); int writeLength = length; if (bufferStart == 0 && writeLength > 0) { bufferStart = bufferOffset + 8; bufferOffset = bufferStart; } while (writeLength > 0) { int sublen = buffer.length - bufferOffset; if (writeLength < sublen) sublen = writeLength; System.arraycopy(buf, offset, buffer, bufferOffset, sublen); writeLength -= sublen; offset += sublen; bufferOffset += sublen; if (writeLength > 0) { int delta = bufferOffset - bufferStart; writeChunk(buffer, bufferStart, delta); _isCommitted = true; buffer = _next.nextBuffer(bufferOffset); if (log.isLoggable(Level.FINE)) log.fine(dbgId() + "write-chunk(" + bufferOffset + ")"); bufferStart = _next.getBufferOffset() + 8; bufferOffset = bufferStart; } } _next.setBufferOffset(bufferOffset); _bufferStartOffset = bufferStart; } } if (! _isDisconnected) _contentLength += length; } catch (ClientDisconnectException e) { // server/183c _response.killCache(); if (_response.isIgnoreClientDisconnect()) _isDisconnected = true; else { throw e; } } } private boolean lengthException(byte []buf, int offset, int length, long contentLengthHeader) { if (_isDisconnected || _isHead || _isClosed) { } else if (contentLengthHeader < _contentLength) { CauchoRequest request = _response.getRequest(); ServletContext app = request.getWebApp(); Exception exn = new IllegalStateException(L.l("{0}: tried to write {1} bytes with content-length {2}.", request.getRequestURL(), "" + (length + _contentLength), "" + contentLengthHeader)); if (app != null) app.log(exn.getMessage(), exn); else exn.printStackTrace(); return false; } for (int i = (int) (offset + contentLengthHeader - _contentLength); i < offset + length; i++) { int ch = buf[i]; if (ch != '\r' && ch != '\n' && ch != ' ' && ch != '\t') { CauchoRequest request = _response.getRequest(); ServletContext app = request.getWebApp(); String graph = ""; if (Character.isLetterOrDigit((char) ch)) graph = "'" + (char) ch + "', "; Exception exn = new IllegalStateException(L.l("{0}: tried to write {1} bytes with content-length {2} (At {3}char={4}).", request.getRequestURL(), "" + (length + _contentLength), "" + contentLengthHeader, graph, "" + ch)); if (app != null) app.log(exn.toString(), exn); else exn.printStackTrace(); break; } } length = (int) (contentLengthHeader - _contentLength); return (length <= 0); } public void flushBuffer() throws IOException { super.flushBuffer(); _isCommitted = true; } /** * Flushes the buffered response to the output stream. */ public void flush() throws IOException { try { _disableAutoFlush = false; _isCommitted = true; if (_allowFlush && ! _isClosed) { flushBuffer(); if (_chunkedEncoding) { int bufferStart = _bufferStartOffset; _bufferStartOffset = 0; if (bufferStart > 0) { int bufferOffset = _next.getBufferOffset(); if (bufferStart != bufferOffset) { writeChunk(_next.getBuffer(), bufferStart, bufferOffset - bufferStart); } else _next.setBufferOffset(bufferStart - 8); } } else { // jsp/01cf _bufferStartOffset = 0; } if (_next != null) _next.flush(); } } catch (ClientDisconnectException e) { if (_response.isIgnoreClientDisconnect()) _isDisconnected = true; else throw e; } } /** * Flushes the buffered response to the output stream. */ public void flushByte() throws IOException { flush(); } /** * Flushes the buffered response to the writer. */ public void flushChar() throws IOException { flush(); } /** * Flushes the buffered response to the output stream. */ /* public void flushBuffer() throws IOException { super.flushBuffer(); // jsp/15la // _isCommitted = true; } */ /** * Complete the request. */ public void finish() throws IOException { boolean isClosed = _isClosed; if (_next == null || isClosed) { _isClosed = true; return; } _disableAutoFlush = false; flushCharBuffer(); _isFinished = true; _allowFlush = true; flushBuffer(); int bufferStart = _bufferStartOffset; _bufferStartOffset = 0; _isClosed = true; // flushBuffer can force 304 and then a cache write which would // complete the finish. if (isClosed || _next == null) { return; } try { if (_chunkedEncoding) { int bufferOffset = _next.getBufferOffset(); if (bufferStart > 0 && bufferOffset != bufferStart) { byte []buffer = _next.getBuffer(); writeChunk(buffer, bufferStart, bufferOffset - bufferStart); } else { // server/05b3 _next.setBufferOffset(0); } _isCommitted = true; ArrayList<String> footerKeys = _response._footerKeys; if (footerKeys.size() == 0) _next.write(_tailChunked, 0, _tailChunkedLength); else { ArrayList<String> footerValues = _response._footerValues; _next.print("\r\n0\r\n"); for (int i = 0; i < footerKeys.size(); i++) { _next.print(footerKeys.get(i)); _next.print(": "); _next.print(footerValues.get(i)); _next.print("\r\n"); } _next.print("\r\n"); } if (log.isLoggable(Level.FINE)) log.fine(dbgId() + "write-chunk(" + _tailChunkedLength + ")"); } CauchoRequest req = _response.getRequest(); if (! req.allowKeepalive()) { if (log.isLoggable(Level.FINE)) { log.fine(dbgId() + "close stream"); } _next.close(); } /* else if (flush) { //_next.flush(); _next.flushBuffer(); } */ } catch (ClientDisconnectException e) { if (_response.isIgnoreClientDisconnect()) _isDisconnected = true; else throw e; } } /** * Fills the chunk header. */ private void writeChunk(byte []buffer, int start, int length) throws IOException { buffer[start - 8] = (byte) '\r'; buffer[start - 7] = (byte) '\n'; buffer[start - 6] = hexDigit(length >> 12); buffer[start - 5] = hexDigit(length >> 8); buffer[start - 4] = hexDigit(length >> 4); buffer[start - 3] = hexDigit(length); buffer[start - 2] = (byte) '\r'; buffer[start - 1] = (byte) '\n'; if (_cacheStream != null) writeCache(buffer, start, length); } /** * Returns the hex digit for the value. */ private static byte hexDigit(int value) { value &= 0xf; if (value <= 9) return (byte) ('0' + value); else return (byte) ('a' + value - 10); } private void writeCache(byte []buf, int offset, int length) throws IOException { if (length == 0) return; if (_cacheMaxLength < _contentLength) { _cacheStream = null; _response.killCache(); } else { _cacheStream.write(buf, offset, length); } } private String dbgId() { Object request = _response.getRequest(); if (request instanceof AbstractHttpRequest) { AbstractHttpRequest req = (AbstractHttpRequest) request; return req.dbgId(); } else return "inc"; } /** * Closes the stream. */ public void close() throws IOException { finish(); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?