if (closed) { return;
} if (suspended) { return;
}
// If there are chars, flush all of them to the byte buffer now as bytes are used to // calculate the content-length (if everything fits into the byte buffer, of course). if (cb.remaining() > 0) {
flushCharBuffer();
}
if ((!coyoteResponse.isCommitted()) && (coyoteResponse.getContentLengthLong() == -1)) { // If this didn't cause a commit of the response, the final content // length can be calculated. if (!coyoteResponse.isCommitted()) {
coyoteResponse.setContentLength(bb.remaining());
}
}
// The request should have been completely read by the time the response // is closed. Further reads of the input a) are pointless and b) really // confuse AJP (bug 50189) so close the input buffer to prevent them.
Request req = (Request) coyoteResponse.getRequest().getNote(CoyoteAdapter.ADAPTER_NOTES);
req.inputBuffer.close();
if (realFlush) {
coyoteResponse.action(ActionCode.CLIENT_FLUSH, null); // If some exception occurred earlier, or if some IOE occurred // here, notify the servlet with an IOE if (coyoteResponse.isExceptionPresent()) { thrownew ClientAbortException(coyoteResponse.getErrorException());
}
}
// If we really have something to write if (buf.remaining() > 0) { // real write to the adapter try {
coyoteResponse.doWrite(buf);
} catch (CloseNowException e) { // Catch this sub-class as it requires specific handling. // Examples where this exception is thrown: // - HTTP/2 stream timeout // Prevent further output for this response
closed = true; throw e;
} catch (IOException e) { // An IOException on a write is almost always due to // the remote client aborting the request. Wrap this // so that it can be handled better by the error dispatcher.
coyoteResponse.setErrorException(e); thrownew ClientAbortException(e);
}
}
}
publicvoid write(byte b[], int off, int len) throws IOException {
while (from.remaining() > 0) {
conv.convert(from, bb); if (bb.remaining() == 0) { // Break out of the loop if more chars are needed to produce any output break;
} if (from.remaining() > 0) {
flushByteBuffer();
} elseif (conv.isUndeflow() && bb.limit() > bb.capacity() - 4) { // Handle an edge case. There are no more chars to write at the // moment but there is a leftover character in the converter // which must be part of a surrogate pair. The byte buffer does // not have enough space left to output the bytes for this pair // once it is complete )it will require 4 bytes) so flush now to // prevent the bytes for the leftover char and the rest of the // surrogate pair yet to be written from being lost. // See TestOutputBuffer#testUtf8SurrogateBody()
flushByteBuffer();
}
}
}
@Override publicvoid write(int c) throws IOException {
if (charset == null) { if (coyoteResponse.getCharacterEncoding() != null) { // setCharacterEncoding() was called with an invalid character set // Trigger an UnsupportedEncodingException
charset = B2CConverter.getCharset(coyoteResponse.getCharacterEncoding());
}
charset = org.apache.coyote.Constants.DEFAULT_BODY_CHARSET;
}
/** *Adddatatothebuffer. * *@paramsrcBytesarray *@paramoffOffset *@paramlenLength * *@throwsIOExceptionWritingoverflowdatatotheoutputchannelfailed
*/ publicvoid append(byte src[], int off, int len) throws IOException { if (bb.remaining() == 0) {
appendByteArray(src, off, len);
} else { int n = transfer(src, off, len, bb);
len = len - n;
off = off + n; if (len > 0 && isFull(bb)) {
flushByteBuffer();
appendByteArray(src, off, len);
}
}
}
/** *Adddatatothebuffer. * *@paramsrcChararray *@paramoffOffset *@paramlenLength * *@throwsIOExceptionWritingoverflowdatatotheoutputchannelfailed
*/ publicvoid append(char src[], int off, int len) throws IOException { // if we have limit and we're below if (len <= cb.capacity() - cb.limit()) {
transfer(src, off, len, cb); return;
}
// Optimization: // If len-avail < length ( i.e. after we fill the buffer with // what we can, the remaining will fit in the buffer ) we'll just // copy the first part, flush, then copy the second part - 1 write // and still have some space for more. We'll still have 2 writes, but // we write more on the first. if (len + cb.limit() < 2 * cb.capacity()) { /* *Iftherequestlengthexceedsthesizeoftheoutputbuffer,flushtheoutputbufferandthenwritethe *datadirectly.Wecan'tavoid2writes,butwecanwritemoreonthesecond
*/ int n = transfer(src, off, len, cb);
flushCharBuffer();
transfer(src, off + n, len - n, cb);
} else { // long write - flush the buffer and write the rest // directly from source
flushCharBuffer();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.