Author: fhanik
Date: Tue May 29 14:53:52 2007
New Revision: 542666
URL: http://svn.apache.org/viewvc?view=rev&rev=542666
Log:
implement non blocking reading of the request line
Modified:
tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java
tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?view=diff&rev=542666&r1=542665&r2=542666
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Tue May
29 14:53:52 2007
@@ -792,14 +792,6 @@
RequestInfo rp = request.getRequestProcessor();
rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);
- // Set the remote address
- remoteAddr = null;
- remoteHost = null;
- localAddr = null;
- localName = null;
- remotePort = -1;
- localPort = -1;
-
// Setting up the socket
this.socket = socket;
inputBuffer.setSocket(socket);
@@ -829,17 +821,17 @@
socket.getIOChannel().socket().setSoTimeout((int)soTimeout);
inputBuffer.readTimeout = soTimeout;
}
- if (!inputBuffer.parseRequestLine(keptAlive &&
(endpoint.getCurrentThreadsBusy() >= limit))) {
- // This means that no data is available right now
- // (long keepalive), so that the processor should be
recycled
- // and the method should return true
+ if (!inputBuffer.parseRequestLine(keptAlive)) {
+ //no data available yet, since we might have read part
+ //of the request line, we can't recycle the processor
openSocket = true;
- // Add the socket to the poller
- socket.getPoller().add(socket);
+ recycle = false;
break;
}
keptAlive = true;
if ( !inputBuffer.parseHeaders() ) {
+ //we've read part of the request, don't recycle it
+ //instead associate it with the socket
openSocket = true;
recycle = false;
break;
@@ -992,6 +984,12 @@
this.socket = null;
this.cometClose = false;
this.comet = false;
+ remoteAddr = null;
+ remoteHost = null;
+ localAddr = null;
+ localName = null;
+ remotePort = -1;
+ localPort = -1;
}
Modified: tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java?view=diff&rev=542666&r1=542665&r2=542666
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java Tue
May 29 14:53:52 2007
@@ -72,6 +72,9 @@
parsingHeader = true;
parsingRequestLine = true;
+ parsingRequestLinePhase = 0;
+ parsingRequestLineEol = false;
+ parsingRequestLineStart = 0;
headerParsePos = HeaderParsePosition.HEADER_START;
headerData.recycle();
swallowInput = true;
@@ -115,6 +118,9 @@
*/
protected boolean parsingHeader;
protected boolean parsingRequestLine;
+ protected int parsingRequestLinePhase = 0;
+ protected boolean parsingRequestLineEol = false;
+ protected int parsingRequestLineStart = 0;
protected HeaderParsePosition headerParsePos;
@@ -305,6 +311,9 @@
parsingHeader = true;
headerParsePos = HeaderParsePosition.HEADER_START;
parsingRequestLine = true;
+ parsingRequestLinePhase = 0;
+ parsingRequestLineEol = false;
+ parsingRequestLineStart = 0;
headerData.recycle();
swallowInput = true;
@@ -346,6 +355,9 @@
parsingHeader = true;
headerParsePos = HeaderParsePosition.HEADER_START;
parsingRequestLine = true;
+ parsingRequestLinePhase = 0;
+ parsingRequestLineEol = false;
+ parsingRequestLineStart = 0;
headerData.recycle();
swallowInput = true;
@@ -384,160 +396,148 @@
//check state
if ( !parsingRequestLine ) return true;
-
- int start = 0;
-
//
// Skipping blank lines
//
-
- byte chr = 0;
- do {
-
- // Read new bytes if needed
+ if ( parsingRequestLinePhase == 0 ) {
+ byte chr = 0;
+ do {
+
+ // Read new bytes if needed
+ if (pos >= lastValid) {
+ if (useAvailableData) {
+ return false;
+ }
+ if (readTimeout == -1) {
+ if (!fill(false,true)) //request line parsing
+ throw new
EOFException(sm.getString("iib.eof.error"));
+ } else {
+ // Do a simple read with a short timeout
+ if ( !readSocket(true, false) ) return false;
+ }
+ }
+ chr = buf[pos++];
+ } while ((chr == Constants.CR) || (chr == Constants.LF));
+ pos--;
+ parsingRequestLineStart = pos;
+ parsingRequestLinePhase = 1;
+ }
+ if ( parsingRequestLinePhase == 1 ) {
+ // Mark the current buffer position
+
if (pos >= lastValid) {
if (useAvailableData) {
return false;
}
if (readTimeout == -1) {
- if (!fill(false,true)) //request line parsing
- throw new EOFException(sm.getString("iib.eof.error"));
+ if (!fill(false,false)) //request line parsing
+ return false;
} else {
// Do a simple read with a short timeout
if ( !readSocket(true, false) ) return false;
}
}
-
- chr = buf[pos++];
-
- } while ((chr == Constants.CR) || (chr == Constants.LF));
-
- pos--;
-
- // Mark the current buffer position
- start = pos;
-
- if (pos >= lastValid) {
- if (useAvailableData) {
- return false;
- }
- if (readTimeout == -1) {
- if (!fill(false,false)) //request line parsing
- return false;
- } else {
- // Do a simple read with a short timeout
- if ( !readSocket(true, false) ) return false;
- }
+ parsingRequestLinePhase = 2;
}
-
- //
- // Reading the method name
- // Method name is always US-ASCII
- //
-
- boolean space = false;
-
- while (!space) {
-
- // Read new bytes if needed
- if (pos >= lastValid) {
- if (!fill(true,false)) //request line parsing
- return false;
- }
-
- if (buf[pos] == Constants.SP) {
- space = true;
- request.method().setBytes(buf, start, pos - start);
+ if ( parsingRequestLinePhase == 2 ) {
+ //
+ // Reading the method name
+ // Method name is always US-ASCII
+ //
+ boolean space = false;
+ while (!space) {
+ // Read new bytes if needed
+ if (pos >= lastValid) {
+ if (!fill(true, false)) //request line parsing
+ return false;
+ }
+ if (buf[pos] == Constants.SP) {
+ space = true;
+ request.method().setBytes(buf, parsingRequestLineStart,
pos - parsingRequestLineStart);
+ }
+ pos++;
}
-
- pos++;
-
+ parsingRequestLineStart = pos;
+ parsingRequestLinePhase = 3;
}
-
- // Mark the current buffer position
- start = pos;
- int end = 0;
- int questionPos = -1;
-
- //
- // Reading the URI
- //
-
- space = false;
- boolean eol = false;
-
- while (!space) {
-
- // Read new bytes if needed
- if (pos >= lastValid) {
- if (!fill(true,false)) //request line parsing
- return false;
+ if ( parsingRequestLinePhase == 3 ) {
+ // Mark the current buffer position
+
+ int end = 0;
+ int questionPos = -1;
+ //
+ // Reading the URI
+ //
+ boolean space = false;
+ while (!space) {
+ // Read new bytes if needed
+ if (pos >= lastValid) {
+ if (!fill(true,false)) //request line parsing
+ return false;
+ }
+ if (buf[pos] == Constants.SP) {
+ space = true;
+ end = pos;
+ } else if ((buf[pos] == Constants.CR)
+ || (buf[pos] == Constants.LF)) {
+ // HTTP/0.9 style request
+ parsingRequestLineEol = true;
+ space = true;
+ end = pos;
+ } else if ((buf[pos] == Constants.QUESTION)
+ && (questionPos == -1)) {
+ questionPos = pos;
+ }
+ pos++;
}
-
- if (buf[pos] == Constants.SP) {
- space = true;
- end = pos;
- } else if ((buf[pos] == Constants.CR)
- || (buf[pos] == Constants.LF)) {
- // HTTP/0.9 style request
- eol = true;
- space = true;
- end = pos;
- } else if ((buf[pos] == Constants.QUESTION)
- && (questionPos == -1)) {
- questionPos = pos;
+ request.unparsedURI().setBytes(buf, parsingRequestLineStart, end -
parsingRequestLineStart);
+ if (questionPos >= 0) {
+ request.queryString().setBytes(buf, questionPos + 1,
+ end - questionPos - 1);
+ request.requestURI().setBytes(buf, parsingRequestLineStart,
questionPos - parsingRequestLineStart);
+ } else {
+ request.requestURI().setBytes(buf, parsingRequestLineStart,
end - parsingRequestLineStart);
}
-
- pos++;
-
+ parsingRequestLineStart = pos;
+ parsingRequestLinePhase = 4;
}
-
- request.unparsedURI().setBytes(buf, start, end - start);
- if (questionPos >= 0) {
- request.queryString().setBytes(buf, questionPos + 1,
- end - questionPos - 1);
- request.requestURI().setBytes(buf, start, questionPos - start);
- } else {
- request.requestURI().setBytes(buf, start, end - start);
- }
-
- // Mark the current buffer position
- start = pos;
- end = 0;
-
- //
- // Reading the protocol
- // Protocol is always US-ASCII
- //
-
- while (!eol) {
-
- // Read new bytes if needed
- if (pos >= lastValid) {
- if (!fill(true,false)) //reques line parsing
- return false;
- }
-
- if (buf[pos] == Constants.CR) {
- end = pos;
- } else if (buf[pos] == Constants.LF) {
- if (end == 0)
+ if ( parsingRequestLinePhase == 4 ) {
+ // Mark the current buffer position
+
+ end = 0;
+ //
+ // Reading the protocol
+ // Protocol is always US-ASCII
+ //
+ while (!parsingRequestLineEol) {
+ // Read new bytes if needed
+ if (pos >= lastValid) {
+ if (!fill(true, false)) //reques line parsing
+ return false;
+ }
+
+ if (buf[pos] == Constants.CR) {
end = pos;
- eol = true;
+ } else if (buf[pos] == Constants.LF) {
+ if (end == 0)
+ end = pos;
+ parsingRequestLineEol = true;
+ }
+ pos++;
}
-
- pos++;
-
- }
-
- if ((end - start) > 0) {
- request.protocol().setBytes(buf, start, end - start);
- } else {
- request.protocol().setString("");
+
+ if ( (end - parsingRequestLineStart) > 0) {
+ request.protocol().setBytes(buf, parsingRequestLineStart, end
- parsingRequestLineStart);
+ } else {
+ request.protocol().setString("");
+ }
+ parsingRequestLine = false;
+ parsingRequestLinePhase = 0;
+ parsingRequestLineEol = false;
+ parsingRequestLineStart = 0;
+ return true;
}
- parsingRequestLine = false;
- return true;
-
+ throw new IllegalStateException("Invalid request line parse
phase:"+parsingRequestLinePhase);
}
private void expand(int newsize) {
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?view=diff&rev=542666&r1=542665&r2=542666
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Tue May 29
14:53:52 2007
@@ -1461,6 +1461,7 @@
while (iterator != null && iterator.hasNext()) {
SelectionKey sk = (SelectionKey) iterator.next();
KeyAttachment attachment =
(KeyAttachment)sk.attachment();
+ attachment.access();
iterator.remove();
processKey(sk, attachment);
}//while
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]