browser(firefox): properly rewrite intercepted request (#3188)

This commit is contained in:
Dmitry Gozman 2020-07-28 11:32:44 -07:00 committed by GitHub
parent a59220b06d
commit 14c6881904
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 25 deletions

View File

@ -1,2 +1,2 @@
1142 1143
Changed: yurys@chromium.org Mon Jul 27 16:21:29 PDT 2020 Changed: dgozman@gmail.com Mon Jul 27 17:30:53 PDT 2020

View File

@ -215,29 +215,35 @@ class NetworkRequest {
// interception and service workers. // interception and service workers.
// An internal redirect has the same channelId, inherits notificationCallbacks and // An internal redirect has the same channelId, inherits notificationCallbacks and
// listener, and should be used instead of an old channel. // listener, and should be used instead of an old channel.
this._networkObserver._channelToRequest.delete(this.httpChannel); this._networkObserver._channelToRequest.delete(this.httpChannel);
this.httpChannel = newChannel; this.httpChannel = newChannel;
this._networkObserver._channelToRequest.set(this.httpChannel, this); this._networkObserver._channelToRequest.set(this.httpChannel, this);
}
if (this._expectingResumedRequest) { // 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; const { method, headers, postData } = this._expectingResumedRequest;
this._expectingResumedRequest = undefined; this._expectingResumedRequest = undefined;
if (headers) { if (headers) {
// Apply new request headers from interception resume. for (const header of requestHeaders(this.httpChannel))
for (const header of requestHeaders(newChannel)) this.httpChannel.setRequestHeader(header.name, '', false /* merge */);
newChannel.setRequestHeader(header.name, '', false /* merge */);
for (const header of headers) for (const header of headers)
newChannel.setRequestHeader(header.name, header.value, false /* merge */); this.httpChannel.setRequestHeader(header.name, header.value, false /* merge */);
} }
if (method) if (method)
newChannel.requestMethod = method; this.httpChannel.requestMethod = method;
if (postData && newChannel instanceof Ci.nsIUploadChannel) { if (postData && this.httpChannel instanceof Ci.nsIUploadChannel2) {
const synthesized = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream); const synthesized = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
synthesized.data = atob(postData); const body = atob(postData);
newChannel.setUploadStream(synthesized, 'application/octet-stream', -1); 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,10 +652,10 @@ class NetworkObserver {
this._expectedRedirect.delete(channelId); this._expectedRedirect.delete(channelId);
new NetworkRequest(this, httpChannel, redirectedFrom); new NetworkRequest(this, httpChannel, redirectedFrom);
} else { } else {
if (this._channelToRequest.has(httpChannel)) { const redirectedRequest = this._channelToRequest.get(httpChannel);
// This happens for resumed requests. if (redirectedRequest)
return; redirectedRequest._onInternalRedirectReady();
} else
new NetworkRequest(this, httpChannel); new NetworkRequest(this, httpChannel);
} }
} }