From d02472a9e097b2c01f41baa4d73f3840564018ac Mon Sep 17 00:00:00 2001 From: Andrey Lushnikov Date: Wed, 12 May 2021 16:27:53 -0700 Subject: [PATCH] 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 --- browser_patches/firefox-stable/BUILD_NUMBER | 4 ++-- .../firefox-stable/juggler/NetworkObserver.js | 10 ++++++++-- browser_patches/firefox/BUILD_NUMBER | 4 ++-- browser_patches/firefox/juggler/NetworkObserver.js | 10 ++++++++-- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/browser_patches/firefox-stable/BUILD_NUMBER b/browser_patches/firefox-stable/BUILD_NUMBER index 3f78fcb7c2..ebdca68403 100644 --- a/browser_patches/firefox-stable/BUILD_NUMBER +++ b/browser_patches/firefox-stable/BUILD_NUMBER @@ -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 diff --git a/browser_patches/firefox-stable/juggler/NetworkObserver.js b/browser_patches/firefox-stable/juggler/NetworkObserver.js index b97ddc9074..12a3bf355f 100644 --- a/browser_patches/firefox-stable/juggler/NetworkObserver.js +++ b/browser_patches/firefox-stable/juggler/NetworkObserver.js @@ -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; } diff --git a/browser_patches/firefox/BUILD_NUMBER b/browser_patches/firefox/BUILD_NUMBER index 151a0d91ec..83f8b0fc0a 100644 --- a/browser_patches/firefox/BUILD_NUMBER +++ b/browser_patches/firefox/BUILD_NUMBER @@ -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 diff --git a/browser_patches/firefox/juggler/NetworkObserver.js b/browser_patches/firefox/juggler/NetworkObserver.js index b97ddc9074..12a3bf355f 100644 --- a/browser_patches/firefox/juggler/NetworkObserver.js +++ b/browser_patches/firefox/juggler/NetworkObserver.js @@ -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; }