libmicrohttpd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libmicrohttpd] hung up sockets cause endless loop


From: Pawel Veselov
Subject: Re: [libmicrohttpd] hung up sockets cause endless loop
Date: Tue, 24 Jun 2014 00:42:43 -0700


Hi Christian,

On Mon, Jun 23, 2014 at 11:11 PM, Christian Grothoff <address@hidden> wrote:
Hi Pawel,

Let's start with the usual question: which MHD version? There was
somewhat recently a fix with respect to HTTPS-clients.

0.9.27, and it's plain HTTP.
 
Also, if you just return MHD_YES and never provide a response, then
how do you expect MHD to terminate?  You'd either need to set a timeout
for the request or return MHD_NO for MHD to shutdown a connection.  So
this sounds more like an issue on your end than on MHD's side.  Note
that if MHD calls you a second time with "*upload_data_size == 0",
that's a signal that the client won't send more data. So then you must
either suspend the connection, provide a response or return MHD_NO,
otherwise you WILL by design end up in a loop (ok, depending a bit on
threading model).

I think I was a bit freaking out here. That's actually a working code, and something
just happened to throw it into that loop.

Generally, throughout my handler code, a response can be created (usually an error), and a connection property is set then, and a response is queued, and MHD_YES is returned. If the handler is called again on the same request, and that connection property is already set, I simply set *upload_data_size to 0 and return MHD_YES (so to not queue more than one response to the same request). So, it was looping on that, but may be I have a code hole somewhere that did set the connection property, but did not queue a response. There is special treatment for the *upload_data_size being 0 the second time for POST requests, and a response (usually not error) is queued.

I walked through the code, and haven't found the hole so far. I found instances where I queue a response, but not set the connection property (could have queued multiple responses), and also found that I don't set *upload_data_size to 0 on error responses, I fixed both, and will now have to see if this reproduces again.
 

Thank you,
  Pawel.


Happy hacking!

Christian

On 06/24/2014 06:05 AM, Pawel Veselov wrote:
> Hi.
>
> I have this problem with my handler being called endlessly if the socket
> was closed in some (I guess), unfriendly way on the remote side.
>
> My logic, in general, is to always set *upload_data_size to 0, and return
> MHD_YES. In this case, I see myself being called over and over again. There
> are at least 3 active context (I print its %p)
>
> The strace shows this in the loop (the write is the output from my handler,
> *upload_data_size is always 0 at the time of the callback)
>
> 907   poll([{fd=5, events=POLLIN}, {fd=16, events=0}, {fd=15, events=0},
> {fd=14, events=0}], 4, 4294967295) = 1 ([{fd=15, revents=POLLERR|POLLHUP}])
> 907   write(2, "HTTP POST /r/0/0, 0 bytes, (nil)"..., 52) = 52
> 907   write(2, "Skipping input chunk 0, because "..., 58) = 58
> 907   write(2, "HTTP POST /r/0/0, 0 bytes, (nil)"..., 52) = 52
> 907   write(2, "Skipping input chunk 0, because "..., 58) = 58
> 907   write(2, "HTTP POST /r/0/0, 0 bytes, (nil)"..., 52) = 52
> 907   write(2, "Skipping input chunk 0, because "..., 58) = 58
>
> Am I missing checking on some property, and returning MHD_NO as a result?
>
> Thank you,
>   Pawel.
>




--
With best of best regards
Pawel S. Veselov

reply via email to

[Prev in Thread] Current Thread [Next in Thread]