hc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Chris Smith" <ch...@mindiq.com>
Subject Re: Proxy problems
Date Thu, 05 Dec 2002 18:44:26 GMT
Ortwin Gl├╝ck wrote:
> Does the PutMethod actually read any response from the server after the
> request headers are sent? I don't think it currently does (which might
> be the actual problem)!

The behavior currently is this: the request line and headers are sent, and
then HttpClient sits and waits for a 100 response.  It does this forever, so
if the server never sends that 100 response, it will either hang forever and
fail (in the case where I ran into the problem, the squid proxy would close
the response stream after 15 minutes, so it didn't really wait *forever*...
just a long time).  So yes, HttpClient does at least try to read a response.

My attached work-around removes the Expect header and prevents that from
happening, with the result that the PUT will work, but the entire body of
the content gets sent even if there's a problem.  That's the easy solution,
and it works fine.

> Solving this is not easy. Calling a HttpConnection.readLine() would
> cause the thread to block until data is available. If the server does
> not send the status line this thread blocks forever.

That is, indeed, exactly what is happening now with the basic PutMethod.

> If we send the
> request body let's say after 3 seconds then, the server's response would
> get consumed by the readLine(). This is tricky. An architectural change
> is needed to solve this: The HttpConnection could incorporate a tiny
> buffer (<1 KB) for the response so it can peek into it and provide a
> non-blocking read or isInputAvailable() method.

I don't understand this.  What do you mean by the server's response getting
"consumed"?  The current behavior of PutMethod is to read, and at least try
to parse, that status line; or at least, I know that after 15 minutes when
squid closes the connection, the complaint I get from HttpClient is about
not being able to find the HTTP/ at the beginning of that line.

> Comment on your solution:
> Letting the user chose if to send the expect header is no good, because
> the user can not decide this and the decision may prove right in one
> situation and wrong in another.

I agree.  However, the consequences of being wrong in the direction that
HttpClient currently guesses are *far* worse than the consequences of being
wrong by not expecting the 100 response.  I don't think this (not expecting
a 100) is good behavior, but it's better than the alternative.  Of course,
the best behavior by far would be as described in RFC2616, where we expect
the 100, but continue if it's not sent.

> I would rather appreciate the suggested behaviour from RFC 2616, 8.2.3
> which implies a maximum wait time before we send the request body.
> So:
> - always send Expect: 100-Continue
> - wait maybe max. 3 seconds for a 100-Continue
> - send the body

Would it be possible to maintain, as a property of either HttpClient or
HttpState, a flag indicating whether we should wait for a 100 response, and
initialize that to true, but set it to false if the 3 second timeout occurs?
That would be a large improvement, I think.  After all, if the server
doesn't respond to 100-continue the first time, what's the point of trying
again?  I'd hate to see a 3 second delay for every connection when there are
a lot of them in a row.

> You can easily use the TimeoutController from the util package. But as
> stated above this approach is currently not possible.

Okay... I'm not going to put together and submit a patch for the temporary
solution of optionally disabling 100-continue, then.  Instead, I'll look
into the changes to fix things the right way.  I've already got my own
application working, anyway.

The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

View raw message