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


Reply via email to