Fields Summary |
---|
int | bbufLimit |
protected static org.apache.tomcat.util.res.StringManager | smThe string manager for this package. |
protected org.apache.coyote.Response | responseAssociated Coyote response. |
protected org.apache.tomcat.util.http.MimeHeaders | headersHeaders of the associated request. |
protected boolean | committedCommitted flag. |
protected boolean | finishedFinished flag. |
protected byte[] | bufPointer to the current write buffer. |
protected int | posPosition in the buffer. |
protected org.apache.tomcat.util.net.NioChannel | socketUnderlying socket. |
protected org.apache.tomcat.util.net.NioSelectorPool | poolSelector pool, for blocking reads and blocking writes |
protected org.apache.coyote.OutputBuffer | outputStreamOutputBufferUnderlying output buffer. |
protected OutputFilter[] | filterLibraryFilter library.
Note: Filter[0] is always the "chunked" filter. |
protected OutputFilter[] | activeFiltersActive filter (which is actually the top of the pipeline). |
protected int | lastActiveFilterIndex of the last active filter. |
protected long | writeTimeoutWrite time out in milliseconds |
int | total |
Methods Summary |
---|
public void | addActiveFilter(OutputFilter filter)Add an output filter to the filter library.
if (lastActiveFilter == -1) {
filter.setBuffer(outputStreamOutputBuffer);
} else {
for (int i = 0; i <= lastActiveFilter; i++) {
if (activeFilters[i] == filter)
return;
}
filter.setBuffer(activeFilters[lastActiveFilter]);
}
activeFilters[++lastActiveFilter] = filter;
filter.setResponse(response);
|
public void | addFilter(OutputFilter filter)Add an output filter to the filter library.
OutputFilter[] newFilterLibrary =
new OutputFilter[filterLibrary.length + 1];
for (int i = 0; i < filterLibrary.length; i++) {
newFilterLibrary[i] = filterLibrary[i];
}
newFilterLibrary[filterLibrary.length] = filter;
filterLibrary = newFilterLibrary;
activeFilters = new OutputFilter[filterLibrary.length];
|
private synchronized void | addToBB(byte[] buf, int offset, int length)
while (socket.getBufHandler().getWriteBuffer().remaining() < length) {
flushBuffer();
}
socket.getBufHandler().getWriteBuffer().put(buf, offset, length);
total += length;
NioEndpoint.KeyAttachment ka = (NioEndpoint.KeyAttachment)socket.getAttachment(false);
if ( ka!= null ) ka.access();//prevent timeouts for just doing client writes
|
public void | clearFilters()Clear filters.
filterLibrary = new OutputFilter[0];
lastActiveFilter = -1;
|
protected void | commit()Commit the response.
// The response is now committed
committed = true;
response.setCommitted(true);
if (pos > 0) {
// Sending the response header buffer
addToBB(buf, 0, pos);
}
|
public int | doWrite(org.apache.tomcat.util.buf.ByteChunk chunk, org.apache.coyote.Response res)Write the contents of a byte chunk.
if (!committed) {
// Send the connector a request for commit. The connector should
// then validate the headers, send them (using sendHeaders) and
// set the filters accordingly.
response.action(ActionCode.ACTION_COMMIT, null);
}
if (lastActiveFilter == -1)
return outputStreamOutputBuffer.doWrite(chunk, res);
else
return activeFilters[lastActiveFilter].doWrite(chunk, res);
|
public void | endHeaders()End the header block.
buf[pos++] = Constants.CR;
buf[pos++] = Constants.LF;
|
public void | endRequest()End request.
if (!committed) {
// Send the connector a request for commit. The connector should
// then validate the headers, send them (using sendHeader) and
// set the filters accordingly.
response.action(ActionCode.ACTION_COMMIT, null);
}
if (finished)
return;
if (lastActiveFilter != -1)
activeFilters[lastActiveFilter].end();
flushBuffer();
finished = true;
|
public void | flush()Flush the response.
if (!committed) {
// Send the connector a request for commit. The connector should
// then validate the headers, send them (using sendHeader) and
// set the filters accordingly.
response.action(ActionCode.ACTION_COMMIT, null);
}
// Flush the current buffer
flushBuffer();
|
protected void | flushBuffer()Callback to write data from the buffer.
//prevent timeout for async,
SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());
if (key != null) {
NioEndpoint.KeyAttachment attach = (NioEndpoint.KeyAttachment) key.attachment();
attach.access();
}
//write to the socket, if there is anything to write
if (socket.getBufHandler().getWriteBuffer().position() > 0) {
writeToSocket(socket.getBufHandler().getWriteBuffer(),true);
}
|
public OutputFilter[] | getFilters()Get filters.
return filterLibrary;
|
public org.apache.tomcat.util.net.NioSelectorPool | getSelectorPool()
return pool;
|
public org.apache.tomcat.util.net.NioChannel | getSocket()Get the underlying socket input stream.
return socket;
|
public long | getWriteTimeout()
return writeTimeout;
|
public void | nextRequest()End processing of current HTTP request.
Note: All bytes of the current request should have been already
consumed. This method only resets all the pointers so that we are ready
to parse the next HTTP request.
// Recycle Request object
response.recycle();
// Recycle filters
for (int i = 0; i <= lastActiveFilter; i++) {
activeFilters[i].recycle();
}
// Reset pointers
pos = 0;
lastActiveFilter = -1;
committed = false;
finished = false;
|
public void | recycle()Recycle the output buffer. This should be called when closing the
connection.
// Recycle Request object
response.recycle();
socket.getBufHandler().getWriteBuffer().clear();
socket = null;
pos = 0;
lastActiveFilter = -1;
committed = false;
finished = false;
|
public void | reset()Reset current response.
if (committed)
throw new IllegalStateException(/*FIXME:Put an error message*/);
// Recycle Request object
response.recycle();
|
public void | sendAck()Send an acknoledgement.
if (!committed) {
//Socket.send(socket, Constants.ACK_BYTES, 0, Constants.ACK_BYTES.length) < 0
ByteBuffer buf = ByteBuffer.wrap(Constants.ACK_BYTES,0,Constants.ACK_BYTES.length);
writeToSocket(buf,false);
}
|
public void | sendHeader(org.apache.tomcat.util.buf.MessageBytes name, org.apache.tomcat.util.buf.MessageBytes value)Send a header.
write(name);
buf[pos++] = Constants.COLON;
buf[pos++] = Constants.SP;
write(value);
buf[pos++] = Constants.CR;
buf[pos++] = Constants.LF;
|
public void | sendHeader(org.apache.tomcat.util.buf.ByteChunk name, org.apache.tomcat.util.buf.ByteChunk value)Send a header.
write(name);
buf[pos++] = Constants.COLON;
buf[pos++] = Constants.SP;
write(value);
buf[pos++] = Constants.CR;
buf[pos++] = Constants.LF;
|
public void | sendHeader(java.lang.String name, java.lang.String value)Send a header.
write(name);
buf[pos++] = Constants.COLON;
buf[pos++] = Constants.SP;
write(value);
buf[pos++] = Constants.CR;
buf[pos++] = Constants.LF;
|
public void | sendStatus()Send the response status line.
// Write protocol name
write(Constants.HTTP_11_BYTES);
buf[pos++] = Constants.SP;
// Write status code
int status = response.getStatus();
switch (status) {
case 200:
write(Constants._200_BYTES);
break;
case 400:
write(Constants._400_BYTES);
break;
case 404:
write(Constants._404_BYTES);
break;
default:
write(status);
}
buf[pos++] = Constants.SP;
// Write message
String message = response.getMessage();
if (message == null) {
write(HttpMessages.getMessage(status));
} else {
write(message);
}
// End the response status line
buf[pos++] = Constants.CR;
buf[pos++] = Constants.LF;
|
public void | setSelectorPool(org.apache.tomcat.util.net.NioSelectorPool pool)
this.pool = pool;
|
public void | setSocket(org.apache.tomcat.util.net.NioChannel socket)Set the underlying socket.
// ------------------------------------------------------------- Properties
this.socket = socket;
|
public void | setSocketBuffer(int socketBufferSize)Set the socket buffer size.
// FIXME: Remove
|
public void | setWriteTimeout(long writeTimeout)
this.writeTimeout = writeTimeout;
|
protected void | write(org.apache.tomcat.util.buf.MessageBytes mb)This method will write the contents of the specyfied message bytes
buffer to the output stream, without filtering. This method is meant to
be used to write the response header.
if (mb.getType() == MessageBytes.T_BYTES) {
ByteChunk bc = mb.getByteChunk();
write(bc);
} else if (mb.getType() == MessageBytes.T_CHARS) {
CharChunk cc = mb.getCharChunk();
write(cc);
} else {
write(mb.toString());
}
|
protected void | write(org.apache.tomcat.util.buf.ByteChunk bc)This method will write the contents of the specyfied message bytes
buffer to the output stream, without filtering. This method is meant to
be used to write the response header.
// Writing the byte chunk to the output buffer
int length = bc.getLength();
System.arraycopy(bc.getBytes(), bc.getStart(), buf, pos, length);
pos = pos + length;
|
protected void | write(org.apache.tomcat.util.buf.CharChunk cc)This method will write the contents of the specyfied char
buffer to the output stream, without filtering. This method is meant to
be used to write the response header.
int start = cc.getStart();
int end = cc.getEnd();
char[] cbuf = cc.getBuffer();
for (int i = start; i < end; i++) {
char c = cbuf[i];
// Note: This is clearly incorrect for many strings,
// but is the only consistent approach within the current
// servlet framework. It must suffice until servlet output
// streams properly encode their output.
if ((c <= 31) && (c != 9)) {
c = ' ";
} else if (c == 127) {
c = ' ";
}
buf[pos++] = (byte) c;
}
|
public void | write(byte[] b)This method will write the contents of the specyfied byte
buffer to the output stream, without filtering. This method is meant to
be used to write the response header.
// Writing the byte chunk to the output buffer
System.arraycopy(b, 0, buf, pos, b.length);
pos = pos + b.length;
|
protected void | write(java.lang.String s)This method will write the contents of the specyfied String to the
output stream, without filtering. This method is meant to be used to
write the response header.
if (s == null)
return;
// From the Tomcat 3.3 HTTP/1.0 connector
int len = s.length();
for (int i = 0; i < len; i++) {
char c = s.charAt (i);
// Note: This is clearly incorrect for many strings,
// but is the only consistent approach within the current
// servlet framework. It must suffice until servlet output
// streams properly encode their output.
if ((c <= 31) && (c != 9)) {
c = ' ";
} else if (c == 127) {
c = ' ";
}
buf[pos++] = (byte) c;
}
|
protected void | write(int i)This method will print the specified integer to the output stream,
without filtering. This method is meant to be used to write the
response header.
write(String.valueOf(i));
|
private synchronized void | writeToSocket(java.nio.ByteBuffer bytebuffer, boolean flip)
//int limit = bytebuffer.position();
if ( flip ) bytebuffer.flip();
int written = 0;
Selector selector = null;
try {
selector = getSelectorPool().get();
} catch ( IOException x ) {
//ignore
}
try {
written = getSelectorPool().write(bytebuffer, socket, selector, writeTimeout);
//make sure we are flushed
do {
if (socket.flush(true,selector,writeTimeout)) break;
}while ( true );
}finally {
if ( selector != null ) getSelectorPool().put(selector);
}
socket.getBufHandler().getWriteBuffer().clear();
this.total = 0;
|