📄 internalniooutputbuffer.java
字号:
// ------------------------------------------------ HTTP/1.1 Output Methods
/**
* Send an acknoledgement.
*/
public void sendAck()
throws IOException {
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);
}
}
private synchronized void writeToSocket(ByteBuffer bytebuffer, boolean flip) throws IOException {
//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(selector)) break;
}while ( true );
}finally {
if ( selector != null ) getSelectorPool().put(selector);
}
socket.getBufHandler().getWriteBuffer().clear();
this.total = 0;
}
/**
* Send the response status line.
*/
public void sendStatus() {
// 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;
}
/**
* Send a header.
*
* @param name Header name
* @param value Header value
*/
public void sendHeader(MessageBytes name, MessageBytes value) {
write(name);
buf[pos++] = Constants.COLON;
buf[pos++] = Constants.SP;
write(value);
buf[pos++] = Constants.CR;
buf[pos++] = Constants.LF;
}
/**
* Send a header.
*
* @param name Header name
* @param value Header value
*/
public void sendHeader(ByteChunk name, ByteChunk value) {
write(name);
buf[pos++] = Constants.COLON;
buf[pos++] = Constants.SP;
write(value);
buf[pos++] = Constants.CR;
buf[pos++] = Constants.LF;
}
/**
* Send a header.
*
* @param name Header name
* @param value Header value
*/
public void sendHeader(String name, String value) {
write(name);
buf[pos++] = Constants.COLON;
buf[pos++] = Constants.SP;
write(value);
buf[pos++] = Constants.CR;
buf[pos++] = Constants.LF;
}
/**
* End the header block.
*/
public void endHeaders() {
buf[pos++] = Constants.CR;
buf[pos++] = Constants.LF;
}
// --------------------------------------------------- OutputBuffer Methods
/**
* Write the contents of a byte chunk.
*
* @param chunk byte chunk
* @return number of bytes written
* @throws IOException an undelying I/O error occured
*/
public int doWrite(ByteChunk chunk, Response res)
throws IOException {
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);
}
// ------------------------------------------------------ Protected Methods
/**
* Commit the response.
*
* @throws IOException an undelying I/O error occured
*/
protected void commit()
throws IOException {
// The response is now committed
committed = true;
response.setCommitted(true);
if (pos > 0) {
// Sending the response header buffer
addToBB(buf, 0, pos);
}
}
int total = 0;
private void addToBB(byte[] buf, int offset, int length) throws IOException {
if (socket.getBufHandler().getWriteBuffer().remaining() < length) {
flushBuffer();
}
socket.getBufHandler().getWriteBuffer().put(buf, offset, length);
total += length;
}
/**
* 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.
*
* @param mb data to be written
*/
protected void write(MessageBytes mb) {
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());
}
}
/**
* 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.
*
* @param bc data to be written
*/
protected void write(ByteChunk bc) {
// Writing the byte chunk to the output buffer
int length = bc.getLength();
System.arraycopy(bc.getBytes(), bc.getStart(), buf, pos, length);
pos = pos + length;
}
/**
* 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.
*
* @param cc data to be written
*/
protected void write(CharChunk cc) {
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;
}
}
/**
* 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.
*
* @param b data to be written
*/
public void write(byte[] b) {
// Writing the byte chunk to the output buffer
System.arraycopy(b, 0, buf, pos, b.length);
pos = pos + b.length;
}
/**
* 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.
*
* @param s data to be written
*/
protected void write(String s) {
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;
}
}
/**
* 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.
*
* @param i data to be written
*/
protected void write(int i) {
write(String.valueOf(i));
}
/**
* Callback to write data from the buffer.
*/
protected void flushBuffer()
throws IOException {
//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);
}
}
// ----------------------------------- OutputStreamOutputBuffer Inner Class
/**
* This class is an output buffer which will write data to an output
* stream.
*/
protected class SocketOutputBuffer
implements OutputBuffer {
/**
* Write chunk.
*/
public int doWrite(ByteChunk chunk, Response res)
throws IOException {
int len = chunk.getLength();
int start = chunk.getStart();
byte[] b = chunk.getBuffer();
while (len > 0) {
int thisTime = len;
if (socket.getBufHandler().getWriteBuffer().position() == socket.getBufHandler().getWriteBuffer().capacity()) {
flushBuffer();
}
if (thisTime > socket.getBufHandler().getWriteBuffer().capacity() - socket.getBufHandler().getWriteBuffer().position()) {
thisTime = socket.getBufHandler().getWriteBuffer().capacity() - socket.getBufHandler().getWriteBuffer().position();
}
addToBB(b,start,thisTime);
len = len - thisTime;
start = start + thisTime;
}
return chunk.getLength();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -