There is an asynchronous interface to read the post data in
Httpd_GetPostDataAsync -
What should happen is that Url_ReadPost should be changed to use
that interface. Urk - it ought to happen sooner.
I think the best solution
is to make it a domain-level property as to whether post data is read
before the domain implementation is called. I'll add a switch to
3.2 Url_PrefixInstall that implements this. Then it'll all be
asyncrhonous and transparent to the domain. I've got a bit of spare
time at the moment and will try to get 3.2 out quickly.
If you are implementing a custom domain handler, then it can do it
itself for the moment.
>>>Ted Dunning said:
>
>
> I have found that a poorly behaving client can cause a hang in the
> tcl-httpd. This hang prevents any other connections and results from
> tcl-httpd getting stuck in a very tight loop. This hang should resolve if
> the client closes the connection, but tcl-httpd will not be able to resolve
> the problem itself.
>
> This problem occurs when a post is done with something like the following
> sequence:
>
> set f [socket $server $port]
> puts $f "POST $url HTTP/1.0"
> puts $f "Content-length: [string length $body]"
> puts $f ""
> flush $f
> after 200
> puts $f [string range $body 0 100]
> flush $f
> after $hellFreezesOver
> puts $f [string range $body 101 end]
> flush $f
>
> What happens is that the body is not read using the event loop because the
> data is not ready after the headers are read. Instead, reading the body is
> deferred. Then when Url_DecodeQuery is called, it attempts to read the rest
> of the body by spinning in a loop that looks like this:
>
> while {$Url(postlength) > 0} {
> set Url(postlength) [Httpd_GetPostData $sock query]
> }
>
> Httpd_GetPostData ultimately causes read on a non-blocking socket. After
> reading the first bit of body, this read returns nothing since the client
> doesn't send anything more. Thus, tcl-httpd will spin infinitely by calling
> read repeatedly with no effect. If the client finally sends the data or
> closes the socket, the server will be released. The socket will not,
> however, time out since the after cancel for that socket will never be
> activated.
>
> Older versions of tcl-httpd didn't have this problem since they read the
> body of a transaction greedily in the event loop. If the client never sent
> the data, then there would be no read events on that socket and the cancel
> would eventually be called, clearing out the mess. This design was deemed
> problematic since a page could never send results until they entire body was
> received.
>
> Does anyone have any suggestions for the best remedy here?
>
-- Brent Welch <[EMAIL PROTECTED]>
http://www.ajubasolutions.com
Scriptics changes to Ajuba Solutions
scriptics.com => ajubasolutions.com