From f6096f1e5bbdd9224aa47fe53898ced232b3ea14 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Mon, 27 Jul 2020 17:31:18 -0700 Subject: [PATCH] browser(firefox): properly rewrite intercepted request --- browser_patches/firefox/BUILD_NUMBER | 4 +- .../firefox/juggler/NetworkObserver.js | 54 ++++++++++--------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/browser_patches/firefox/BUILD_NUMBER b/browser_patches/firefox/BUILD_NUMBER index ab823b015d8ce..5adcf1e8328b6 100644 --- a/browser_patches/firefox/BUILD_NUMBER +++ b/browser_patches/firefox/BUILD_NUMBER @@ -1,2 +1,2 @@ -1142 -Changed: yurys@chromium.org Mon Jul 27 16:21:29 PDT 2020 +1143 +Changed: dgozman@gmail.com Mon Jul 27 17:30:53 PDT 2020 diff --git a/browser_patches/firefox/juggler/NetworkObserver.js b/browser_patches/firefox/juggler/NetworkObserver.js index a4f59a570ef29..43d28c6f31c20 100644 --- a/browser_patches/firefox/juggler/NetworkObserver.js +++ b/browser_patches/firefox/juggler/NetworkObserver.js @@ -215,29 +215,35 @@ class NetworkRequest { // interception and service workers. // An internal redirect has the same channelId, inherits notificationCallbacks and // listener, and should be used instead of an old channel. - this._networkObserver._channelToRequest.delete(this.httpChannel); this.httpChannel = newChannel; this._networkObserver._channelToRequest.set(this.httpChannel, this); + } - if (this._expectingResumedRequest) { - const { method, headers, postData } = this._expectingResumedRequest; - this._expectingResumedRequest = undefined; - - if (headers) { - // Apply new request headers from interception resume. - for (const header of requestHeaders(newChannel)) - newChannel.setRequestHeader(header.name, '', false /* merge */); - for (const header of headers) - newChannel.setRequestHeader(header.name, header.value, false /* merge */); - } - if (method) - newChannel.requestMethod = method; - if (postData && newChannel instanceof Ci.nsIUploadChannel) { - const synthesized = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream); - synthesized.data = atob(postData); - newChannel.setUploadStream(synthesized, 'application/octet-stream', -1); - } + // Instrumentation called by NetworkObserver. + _onInternalRedirectReady() { + // Resumed request is first internally redirected to a new request, + // and then the new request is ready to be updated. + if (!this._expectingResumedRequest) + return; + const { method, headers, postData } = this._expectingResumedRequest; + this._expectingResumedRequest = undefined; + + if (headers) { + for (const header of requestHeaders(this.httpChannel)) + this.httpChannel.setRequestHeader(header.name, '', false /* merge */); + for (const header of headers) + this.httpChannel.setRequestHeader(header.name, header.value, false /* merge */); + } + if (method) + this.httpChannel.requestMethod = method; + if (postData && this.httpChannel instanceof Ci.nsIUploadChannel2) { + const synthesized = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream); + const body = atob(postData); + synthesized.setData(body, body.length); + // Clear content-length, so that upload stream resets it. + this.httpChannel.setRequestHeader('content-length', '', false /* merge */); + this.httpChannel.explicitSetUploadStream(synthesized, 'application/octet-stream', -1, this.httpChannel.requestMethod, false); } } @@ -646,11 +652,11 @@ class NetworkObserver { this._expectedRedirect.delete(channelId); new NetworkRequest(this, httpChannel, redirectedFrom); } else { - if (this._channelToRequest.has(httpChannel)) { - // This happens for resumed requests. - return; - } - new NetworkRequest(this, httpChannel); + const redirectedRequest = this._channelToRequest.get(httpChannel); + if (redirectedRequest) + redirectedRequest._onInternalRedirectReady(); + else + new NetworkRequest(this, httpChannel); } }