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/