From: Greg W. (JIRA) <ji...@co...> - 2007-03-28 21:57:39
|
[ http://jira.codehaus.org/browse/JETTY-283?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Greg Wilkins resolved JETTY-283. -------------------------------- Resolution: Fixed Raffaele, I have applied your patch and it will be in 6.1.2rc3! Thanks for the diagnosis and doing the patch itself. I made a few minor changes but other than that it was spot on! I am currently restructuring the proxy a little bit, so I apologize in advance for the instability that is about to result. I am making the HttpDestination class inactive, and trying to handling pipelining etc. > Problems with AsyncProxyServlet in jetty/extras/client (wrong processing of "304 Not Modified") > ----------------------------------------------------------------------------------------------- > > Key: JETTY-283 > URL: http://jira.codehaus.org/browse/JETTY-283 > Project: Jetty > Issue Type: Bug > Components: HTTP > Affects Versions: 6.1.2 > Environment: Windows / Java 6 / Firefox 2.0 > Reporter: Raffaele Sena > Assigned To: Greg Wilkins > Attachments: httparser.patch, testproxy.sh > > > I am not sure of where the problem is, but it's related to the Jetty HttpParser, the way AsyncProxyServlet uses continuantions, and the way HttpConnection uses HttpParser. > I was trying to use the AsyncProxyServlet example in jetty/extras/client/ but I am stuck with something that looks like a bug in Jetty HTTPParser or in the way it is used by org.mortbay.jetty.HttpConnection . > I am using Jetty 6.1.2 and I am just running the provided sample. > I have noticed that on some sites requests don't terminate (the browser, configured to go through the proxy, hangs waiting on the page to complete or I get broken images or such). > I have traced the code and the problem seems to be that some responses never complete (actually they do complete but Jetty doesn't generate all the proper events). > The proxy servlet uses continuation and relies on callbacks on some HttpExchange object to keep the state of request and correctly terminate them. > What is happening is that on particular HTTP responses (for example 304 Not Modified) the Jetty engine (HttpParser class) doesn't generate a messageComplete callback (that would get converted to HttpExchange.onResponseComplete, that is what AsyncProxyServlet relies on to complete a request. > I looked at the code and I suspect the parser correctly gets all the headers (and it generates a headerComplete callback) but because there is no Content-Length field it doesn't generate the messageComplete callback, waiting for some possible message body associated to the response. > This is, if I read them well, agains the HTTP/1.1 specifications that state the following: > 4.3 Message Body > ... > For response messages, whether or not a message-body is included with > a message is dependent on both the request method and the response > status code (section 6.1.1). All responses to the HEAD request method > MUST NOT include a message-body, even though the presence of entity- > header fields might lead one to believe they do. All 1xx > (informational), 204 (no content), and 304 (not modified) responses > MUST NOT include a message-body. All other responses do include a > message-body, although it MAY be of zero length. > 4.4 Message Length > ... > 1.Any response message which "MUST NOT" include a message-body (such > as the 1xx, 204, and 304 responses and any response to a HEAD > request) is always terminated by the first empty line after the > header fields, regardless of the entity-header fields present in > the message. > The only thing I am not 100% sure in my particular case is there is the origin server does send an empty line or simply > closes the connection (it does send a "Connection: close" header in the response). > I tried to look at the HttpParser code but it kind of make my head hurt :) I understand what is doing but I am not sure > of why (the state is set to HttpTokens.EOF_CONTENT instead of HttpTokens.NO_CONTENT because there is no content-length header, > but that makes the state machine call only headerComplete and not messageComplete. > Anyway, this is a dump of a request that fails and make the proxy hang: > $ curl -v -H "If-Modified-Since: Mon, 29 Jan 2007 20:43:08 GMT" -H "Connection: keep-alive" http://www.engadget.com/media/style.css > * About to connect() to www.engadget.com port 80 > * Trying 152.163.17.132... connected > * Connected to www.engadget.com (152.163.17.132) port 80 > > GET /media/style.css HTTP/1.1 > > User-Agent: curl/7.15.4 (i686-pc-cygwin) libcurl/7.15.4 OpenSSL/0.9.8d zlib/1.2.3 > > Host: www.engadget.com > > Accept: */* > > If-Modified-Since: Mon, 29 Jan 2007 20:43:08 GMT > > Connection: keep-alive > > > < HTTP/1.1 304 Not Modified > < Date: Fri, 23 Mar 2007 00:09:17 GMT > < Server: Apache/2.2 > < Connection: close > < ETag: "3efd-eccacf00" > < Expires: Fri, 23 Mar 2007 00:10:17 GMT > < Cache-Control: max-age=60 > * Closing connection #0 > If I use curl to send the request through the proxy everything works (probably because curl closes the connection) but if I use > Firefox, configured to proxy via Jetty, and try to access http://www.engadget.com/ the request for the stylesheet never completes. > I tried to modify HttpConnection to call messageComplete when I think the request is complete, but while that seems to help I still never manage to get the full page to load (but I suspect I am checking the wrong info in order to determine if the request should be complete but it's not. -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://jira.codehaus.org/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira |