browser(firefox): fix uploads of large files in Firefox (#6547)

- to read post data of requests, we have to read stream
- to restore the stream later on, we have to rewind it back
- however, if the stream is large enough, it cannot be rewound back

This patch starts cloning post data streams if possible to avoid
back-rewinding them later on.

References #4704
This commit is contained in:
Andrey Lushnikov 2021-05-12 16:27:53 -07:00 committed by GitHub
parent 1a39843df5
commit d02472a9e0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 20 additions and 8 deletions

View file

@ -1,2 +1,2 @@
1250
Changed: yurys@chromium.org Wed 12 May 2021 08:53:32 AM PDT
1251
Changed: lushnikov@chromium.org Wed 12 May 2021 04:13:18 PM PDT

View file

@ -740,11 +740,17 @@ function getSecurityDetails(httpChannel) {
function readRequestPostData(httpChannel) {
if (!(httpChannel instanceof Ci.nsIUploadChannel))
return undefined;
const iStream = httpChannel.uploadStream;
let iStream = httpChannel.uploadStream;
if (!iStream)
return undefined;
const isSeekableStream = iStream instanceof Ci.nsISeekableStream;
// For some reason, we cannot rewind back big streams,
// so instead we should clone them.
const isCloneable = iStream instanceof Ci.nsICloneableInputStream;
if (isCloneable)
iStream = iStream.clone();
let prevOffset;
if (isSeekableStream) {
prevOffset = iStream.tell();
@ -767,7 +773,7 @@ function readRequestPostData(httpChannel) {
// Seek locks the file, so seek to the beginning only if necko hasn't
// read it yet, since necko doesn't seek to 0 before reading (at lest
// not till 459384 is fixed).
if (isSeekableStream && prevOffset == 0)
if (isSeekableStream && prevOffset == 0 && !isCloneable)
iStream.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
return result;
}

View file

@ -1,2 +1,2 @@
1260
Changed: yurys@chromium.org Wed 12 May 2021 08:49:17 AM PDT
1261
Changed: lushnikov@chromium.org Wed 12 May 2021 04:12:52 PM PDT

View file

@ -740,11 +740,17 @@ function getSecurityDetails(httpChannel) {
function readRequestPostData(httpChannel) {
if (!(httpChannel instanceof Ci.nsIUploadChannel))
return undefined;
const iStream = httpChannel.uploadStream;
let iStream = httpChannel.uploadStream;
if (!iStream)
return undefined;
const isSeekableStream = iStream instanceof Ci.nsISeekableStream;
// For some reason, we cannot rewind back big streams,
// so instead we should clone them.
const isCloneable = iStream instanceof Ci.nsICloneableInputStream;
if (isCloneable)
iStream = iStream.clone();
let prevOffset;
if (isSeekableStream) {
prevOffset = iStream.tell();
@ -767,7 +773,7 @@ function readRequestPostData(httpChannel) {
// Seek locks the file, so seek to the beginning only if necko hasn't
// read it yet, since necko doesn't seek to 0 before reading (at lest
// not till 459384 is fixed).
if (isSeekableStream && prevOffset == 0)
if (isSeekableStream && prevOffset == 0 && !isCloneable)
iStream.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
return result;
}