1) volafile client code opens XHR... Starts sending
2) 120 seconds go by...
3) Server, like we know from issue #127, closes the connection by sending an RST and then cutting the connection, hard.
4) Chrome uses the linked hurrdurr logic and instead of reporting the error back to the volafile frontend code simply opts to resend the request.
5) Stuff gets resend
6) Another 120 seconds pass-by...
7) Second RST for the resend data
8) Chrome logic finally thinks: ahue, connection is borked (via https://code.google.com/p/chromium/codesearch#chromium/src/net/http/http_network_transaction.cc&l=1569 )
9) volafile client code is notified of error finally
10) Queries uploadStatus
11) Sends new request, this time with startAt according to uploadStatus
12) If transfer finished in time, GOOD, otherwise go to 2)
Result
Every 120s chrome will once resend the data from the previous 120s
Let's assume a client can push 10MB in 120 seconds and wants to transfer 29MB total:
1) 0-10MB, RST (120s elapsed)
2) 0-10MB resend, RST (120s elapsed)
3) uploadStatus, 10MB-20MB, RST (120s elapsed)
4) 10MB-20MB resend, RST
5) uploadStatus, 20MB-29MB
Total bytes actually transferred: 10 + 10 + 10 + 10 + 9 = 49MB instead of 29MB.
Conclusion
toppest of cucks, Dolos approved with Seal of The Croatian Auxo
But why is there an open keep-alive connection always?
Easy: the XHR performs an OPTIONS preflight to check for CORS stuff, the server answers the preflight request without a Connection: close which then defaults to keep-alivedungoofed
The user's browser might have open keep-alive connections anyway if it requested a preview or file previously, so just special-casing the OPTIONS preflight is not enough!
The fix would be to avoid keep-alive connections altogether (Connection: close)
either by disabling all keep-alive connections in the dl*.volafile.io servers.
or by using different sub-domains for uploads that have keep-alive disabled
There is no way around disabling keep-alive for connections that otherwise might get later reused for uploads. Funnay, innit?
Chrome
Turns out Chrome will actually try to resend posts (under certain circumstances), incl. when receiving a
RST
: https://code.google.com/p/chromium/codesearch#chromium/src/net/http/http_network_transaction.cc&l=1432So what happens? (STR)
1) volafile client code opens XHR... Starts sending 2) 120 seconds go by... 3) Server, like we know from issue #127, closes the connection by sending an
RST
and then cutting the connection, hard. 4) Chrome uses the linked hurrdurr logic and instead of reporting the error back to the volafile frontend code simply opts to resend the request. 5) Stuff gets resend 6) Another 120 seconds pass-by... 7) SecondRST
for the resend data 8) Chrome logic finally thinks: ahue, connection is borked (via https://code.google.com/p/chromium/codesearch#chromium/src/net/http/http_network_transaction.cc&l=1569 ) 9) volafile client code is notified of error finally 10) QueriesuploadStatus
11) Sends new request, this time withstartAt
according touploadStatus
12) If transfer finished in time, GOOD, otherwise go to 2)Result
Every 120s chrome will once resend the data from the previous 120s
Let's assume a client can push 10MB in 120 seconds and wants to transfer 29MB total: 1) 0-10MB, RST (120s elapsed) 2) 0-10MB resend, RST (120s elapsed) 3) uploadStatus, 10MB-20MB, RST (120s elapsed) 4) 10MB-20MB resend, RST 5) uploadStatus, 20MB-29MB
Total bytes actually transferred: 10 + 10 + 10 + 10 + 9 = 49MB instead of 29MB.
Conclusion
toppest of cucks, Dolos approved with Seal of The Croatian Auxo
And now for how to fix this....
https://code.google.com/p/chromium/codesearch#chromium/src/net/http/http_network_transaction.cc&l=1569 This "resend request without telling the user" logic only kicks in when the connection is not reused, i.e. there is an open keep-alive connection.
But why is there an open keep-alive connection always? Easy: the XHR performs an
OPTIONS
preflight to check for CORS stuff, the server answers the preflight request without aConnection: close
which then defaults tokeep-alive
dungoofed The user's browser might have open keep-alive connections anyway if it requested a preview or file previously, so just special-casing theOPTIONS
preflight is not enough!The fix would be to avoid keep-alive connections altogether (
Connection: close
)dl*.volafile.io
servers.There is no way around disabling keep-alive for connections that otherwise might get later reused for uploads. Funnay, innit?
Firefox?
Same shit: https://hg.mozilla.org/mozilla-central/annotate/324c50cbc40a/netwerk/protocol/http/nsHttpTransaction.cpp#l929 Fix should be the same: do not
keep-alive
, ever!MSIE?
Apparently they had the same resend logic, but disabled it in some hotfix for some reason.
Ball is in your corner now, @laino cc @Robertcop @MorkWMerth