On 25.07.2008, at 03:18, Damien Katz wrote:
Looks like I found a fix for the bug, though I'm not 100% sure what the actual bug is. The fix was to change mochiweb to send the HTTP chunk in a single gen_tcp:send/2 call. Previously it sent the length in one call, then the data followed by data in another call.

My theory of the bug is the Safari HTTP client is getting the chunked end marker in 2 packets. It gets the 0 length + CRLF line in a one packet and when it asks for the CRLF in the next packet its not there yet, so it just skips it (for reasons yet unknown). But the CRLF is still coming, and then when the client goes ahead and makes the next request and tries to get the next response and it instead gets that previous CRLF it had skipped. Because it gets a weird unexpected response, it retries the request.

This fix is to put the whole chunk in one gen_tcp:send/2 call, which I think forces it into a single TCP packet and therefore CRLF is always available immediately. The fix is simple and I think it also be more efficient for most use cases. However I think there might still be a flaw in Safari here that could bite. I also think the idempotence work for document creation is still necessary.

I want to take this fix along with the recent replication and compaction bug fixes and create a 0.8.1.

So this is a patch to the mochiweb source, right? Like this:

Index: src/mochiweb/mochiweb_response.erl
===================================================================
--- src/mochiweb/mochiweb_response.erl  (revision 678916)
+++ src/mochiweb/mochiweb_response.erl  (working copy)
@@ -50,8 +50,7 @@
     case Request:get(version) of
         Version when Version >= {1, 1} ->
             Length = iolist_size(Data),
-            send(io_lib:format("~.16b\r\n", [Length])),
-            send([Data, <<"\r\n">>]);
+ send([io_lib:format("~.16b\r\n", [Length]), Data, <<"\r \n">>]);
         _ ->
             send(Data)
     end.

?

Cheers,
--
Christopher Lenz
  cmlenz at gmx.de
  http://www.cmlenz.net/

Reply via email to