mirror of
https://github.com/electron/electron.git
synced 2026-01-09 15:38:08 -05:00
fix: webRequest.onBeforeSendHeaders not being able to modify reserved headers (#49226)
* fix: `webRequest.onBeforeSendHeaders` not being able to modify reserved headers * chore: add unit test for reserved header
This commit is contained in:
@@ -55,9 +55,9 @@ ProxyingURLLoaderFactory::InProgressRequest::InProgressRequest(
|
|||||||
proxied_loader_receiver_(this, std::move(loader_receiver)),
|
proxied_loader_receiver_(this, std::move(loader_receiver)),
|
||||||
target_client_(std::move(client)),
|
target_client_(std::move(client)),
|
||||||
current_response_(network::mojom::URLResponseHead::New()),
|
current_response_(network::mojom::URLResponseHead::New()),
|
||||||
// Always use "extraHeaders" mode to be compatible with old APIs, except
|
// Always use "extraHeaders" mode to be compatible with old APIs.
|
||||||
// when the |request_id_| is zero, which is not supported in Chromium and
|
// A non-zero request ID is required to use the TrustedHeaderClient path
|
||||||
// only happens in Electron when the request is started from net module.
|
// which allows webRequest to modify headers like Proxy-Authorization.
|
||||||
has_any_extra_headers_listeners_(network_service_request_id != 0) {
|
has_any_extra_headers_listeners_(network_service_request_id != 0) {
|
||||||
// If there is a client error, clean up the request.
|
// If there is a client error, clean up the request.
|
||||||
target_client_.set_disconnect_handler(base::BindOnce(
|
target_client_.set_disconnect_handler(base::BindOnce(
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "base/memory/raw_ptr.h"
|
#include "base/memory/raw_ptr.h"
|
||||||
#include "base/notreached.h"
|
#include "base/notreached.h"
|
||||||
#include "base/sequence_checker.h"
|
#include "base/sequence_checker.h"
|
||||||
|
#include "content/public/browser/global_request_id.h"
|
||||||
#include "gin/object_template_builder.h"
|
#include "gin/object_template_builder.h"
|
||||||
#include "mojo/public/cpp/bindings/remote.h"
|
#include "mojo/public/cpp/bindings/remote.h"
|
||||||
#include "mojo/public/cpp/system/data_pipe_producer.h"
|
#include "mojo/public/cpp/system/data_pipe_producer.h"
|
||||||
@@ -375,6 +376,13 @@ void SimpleURLLoaderWrapper::Start() {
|
|||||||
|
|
||||||
loader_->SetAllowHttpErrorResults(true);
|
loader_->SetAllowHttpErrorResults(true);
|
||||||
loader_->SetURLLoaderFactoryOptions(request_options_);
|
loader_->SetURLLoaderFactoryOptions(request_options_);
|
||||||
|
// Set a non-zero request ID so that the request can use the
|
||||||
|
// TrustedHeaderClient code path for webRequest header modifications.
|
||||||
|
// See proxying_url_loader_factory.cc for details.
|
||||||
|
if (electron::IsBrowserProcess()) {
|
||||||
|
loader_->SetRequestID(
|
||||||
|
content::GlobalRequestID::MakeBrowserInitiated().request_id);
|
||||||
|
}
|
||||||
loader_->SetOnResponseStartedCallback(base::BindOnce(
|
loader_->SetOnResponseStartedCallback(base::BindOnce(
|
||||||
&SimpleURLLoaderWrapper::OnResponseStarted, weak_factory_.GetWeakPtr()));
|
&SimpleURLLoaderWrapper::OnResponseStarted, weak_factory_.GetWeakPtr()));
|
||||||
loader_->SetOnRedirectCallback(base::BindRepeating(
|
loader_->SetOnRedirectCallback(base::BindRepeating(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ipcMain, protocol, session, WebContents, webContents } from 'electron/main';
|
import { ipcMain, net, protocol, session, WebContents, webContents } from 'electron/main';
|
||||||
|
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import * as WebSocket from 'ws';
|
import * as WebSocket from 'ws';
|
||||||
@@ -455,6 +455,35 @@ describe('webRequest module', () => {
|
|||||||
}));
|
}));
|
||||||
expect(onSendHeadersCalled).to.be.true();
|
expect(onSendHeadersCalled).to.be.true();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can inject Proxy-Authorization header for net module requests', async () => {
|
||||||
|
// Proxy-Authorization is normally rejected by Chromium's network service
|
||||||
|
// for security reasons. However, for Electron's trusted net module,
|
||||||
|
// webRequest.onBeforeSendHeaders should be able to inject it via the
|
||||||
|
// TrustedHeaderClient code path.
|
||||||
|
const proxyAuthValue = 'Basic test-credentials';
|
||||||
|
let receivedProxyAuth: string | undefined;
|
||||||
|
|
||||||
|
const server = http.createServer((req, res) => {
|
||||||
|
receivedProxyAuth = req.headers['proxy-authorization'];
|
||||||
|
res.end('ok');
|
||||||
|
});
|
||||||
|
const { url: serverUrl } = await listen(server);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ses.webRequest.onBeforeSendHeaders((details, callback) => {
|
||||||
|
const requestHeaders = details.requestHeaders;
|
||||||
|
requestHeaders['Proxy-Authorization'] = proxyAuthValue;
|
||||||
|
callback({ requestHeaders });
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await net.fetch(serverUrl, { bypassCustomProtocolHandlers: true });
|
||||||
|
expect(response.ok).to.be.true();
|
||||||
|
expect(receivedProxyAuth).to.equal(proxyAuthValue);
|
||||||
|
} finally {
|
||||||
|
server.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('webRequest.onSendHeaders', () => {
|
describe('webRequest.onSendHeaders', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user