Error with file upload on slow network
cloudhead opened this issue · comments
I'm testing the file upload functionality with an intentionally crippled network, and getting some timeouts after long file uploads (> 1 min). Here's the setup:
Cap network bandwidth to 600Kbit/s and add 50ms latency:
sudo ipfw pipe 1 config bw 600Kbit/s delay 50ms
sudo ipfw add 1 pipe 1 src-port 8080
sudo ipfw add 2 pipe 1 dst-port 8080
Here's the error I get after about 1.5 minutes of a 900K file:
18:46:41.773 [error] module: misultin_http
line: 392
error reading body: timeout
18:46:41.777 [error] module: misultin_http
line: 363
request timeout, sending error
Misultin version is 0.9-dev
(current master I think)
Any ideas why it's timing out? I'm tracking the file progress, and it seems like it's being uploaded...
Note: everything seems to work fine without the artificial network delay, and everything but file uploads work fine with the delay. I'm just worried this could happen when the site is live.
hi,
have you tried starting misultin with the recv_timeout
option? This allows you to specify the maximum allowed timeout, and it defaults to 30000 ms.
you may consider increasing this timeout, or even setting it to infinity
(definitely not recommended).
also: how are you trying to upload the file? chunked encoding?
please let me know and we can go on from there.
r.
I haven't tried, are you saying it considers the file upload as a single operation? In that case it'll timeout if the file takes longer than 30s to upload, even if it has received data 1 second ago, correct?
I will try now with infinity
, just to see if that's the issue.
I'm uploading the file via a form with multipart/form-data
, but asynchronously, using FormData—the initial request looks like this:
PUT http://127.0.0.1:8080/upload HTTP/1.1
Origin: http://127.0.0.1:8080
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryghgPGhJfvWWxzxsj
Accept: text/plain
Referer: http://127.0.0.1:8080/
------WebKitFormBoundaryghgPGhJfvWWxzxsj
Content-Disposition: form-data; name="file"; filename="artwork.tiff"
Content-Type: image/tiff
------WebKitFormBoundaryghgPGhJfvWWxzxsj--
I'm not aware of the possibility of using chunked transfer-encoding when doing file uploads.
Will post back soon.
Ok, so setting recv_timeout
to 600000
solved the issue (infinity
doesn't seem to work, it asks for an integer timeout).
It seems like it's a compromise though, because it is receiving data, but the timeout is not considering that—it views it as an "atomic" request/response, instead of a stream. Unless I'm mistaken, it should timeout only if it hasn't received any data in recv_timeout
ms.
Am I missing anything? anything we can do?
Hi,
sorry for the infinity
suggestion: I actually had this disabled some time ago and it now only accepts integers, which I believed (and still do) to be the sane and safe approach.
The timeout is defined as per the gen_tpc:recv/3 function specs. The code in misultin that is issuing the timeout is here.
I'd believe too that Timeout relates to the maximum allowed time for a socket to not receive any data, however just in case I've posted a question to the Erlang Questions mailing list.
FYI, you can do chunked transfer-encoding file upload in misultin, server-side example here.
r.
Hmm I see.. but are you sure it isn't an internal erlang message which is timing out in this case? Like here: https://github.com/ostinelli/misultin/blob/master/src/misultin_http.erl#L202 for example?
I see how I can do chunked-encoding server-side, but my understanding is that it can only be used for http responses, not requests.. is that not correct? Or do you mean a chunked response might help here?
Yes. The {active, once}
parameter is used at that point, plus the log you posted is pretty self-explanatory to where this is happening.
I've received a reply in the mailing list. This is very interesting, and I'll provide a patch asap. I'll ping you to test it with your configuration too, and see if that solves it.
As far as your other question, the example I've linked demonstrates how to read chunked encoding from requests. This is useful to provide upload streaming functionalities, for instance.
r.
Very interesting indeed, it seems like with that fine-grained control, there can be a solution! I'll be awaiting your patch.
About the chunked-encoding, the thing is I don't think it is possible to force it from the browser.
I've tested some patches. these solve this issue, however introduce unnecessary complexity / slowness for 'normal' connections.
currently the only solution i can see is increase the timeout, which is an option already provided. if you have any input do not hesitate.