electron/shell/browser/net/proxying_url_loader_factory.h
Electron Bot ca75bca667
chore: bump chromium to 90.0.4415.0 (master) (#27694)
* chore: bump chromium in DEPS to 520c02b46668fc608927e0fcd79b6a90885a48bf

* chore: bump chromium in DEPS to 90.0.4414.0

* resolve chromium conflicts

* resolve v8 conflicts

* fix node gn files

* 2673502: Remove RenderViewCreated use from ExtensionHost.

https://chromium-review.googlesource.com/c/chromium/src/+/2673502

* 2676903: [mojo] Remove most legacy Binding classes.

https://chromium-review.googlesource.com/c/chromium/src/+/2676903

* 2644847: Move self-deleting URLLoaderFactory base into //services/network.

https://chromium-review.googlesource.com/c/chromium/src/+/2644847

* 2664006: Remove from mojo::DataPipe.

https://chromium-review.googlesource.com/c/chromium/src/+/2664006

* 2674530: Remove CertVerifierService feature

https://chromium-review.googlesource.com/c/chromium/src/+/2674530

* 2668748: Move OnSSLCertificateError to a new interface.

https://chromium-review.googlesource.com/c/chromium/src/+/2668748

* 2672923: Remove RAPPOR reporting infrastructure.

https://chromium-review.googlesource.com/c/chromium/src/+/2672923

* 2673502: Remove RenderViewCreated use from ExtensionHost.

https://chromium-review.googlesource.com/c/chromium/src/+/2673502

* 2655126: Convert FrameHostMsg_ContextMenu and FrameMsg_ContextMenuClosed|CustomContextMenuAction to Mojo

https://chromium-review.googlesource.com/c/chromium/src/+/2655126

* 2628705: Window Placement: Implement screen.isExtended and change event

https://chromium-review.googlesource.com/c/chromium/src/+/2628705

* 2643161: Refactor storage::kFileSystem*Native*

https://chromium-review.googlesource.com/c/chromium/src/+/2643161

* fix build

* only remove the biggest subdir of //ios

* chore: bump chromium in DEPS to 90.0.4415.0

* update patches

* update sysroots

* 2686147: Remove WebContentsObserver::RenderViewCreated().

https://chromium-review.googlesource.com/c/chromium/src/+/2686147

* 2596429: Fixing how extension's split and spanning modes affect OriginAccessList.

https://chromium-review.googlesource.com/c/chromium/src/+/2596429

* 2686026: [mojo] Delete AssociatedInterfacePtr (replaced by AssociatedRemote)

https://chromium-review.googlesource.com/c/chromium/src/+/2686026

* 2651705: Move ui/base/dragdrop/file_info to ui/base/clipboard

https://chromium-review.googlesource.com/c/chromium/src/+/2651705

* 358217: drawBitmap is deprecated

https://skia-review.googlesource.com/c/skia/+/358217

* fix gn check

* 2678098: Use gen/front_end as input to generate_devtools_grd

https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2678098

* 2674530: Remove CertVerifierService feature

https://chromium-review.googlesource.com/c/chromium/src/+/2674530

* fixup 2664006: Remove from mojo::DataPipe.

  https://chromium-review.googlesource.com/c/chromium/src/+/2664006

* fixup build_add_electron_tracing_category.patch

* 2673415: [base] Prepare CrashReporterClient for string16 switch

https://chromium-review.googlesource.com/c/chromium/src/+/2673415

* 2673413: Add CursorFactoryWin to handle Cursors on Windows

https://chromium-review.googlesource.com/c/chromium/src/+/2673413

* 2668748: Move OnSSLCertificateError to a new interface.

https://chromium-review.googlesource.com/c/chromium/src/+/2668748

* fix mas gn check

* update patch after merge

* Update node for .mjs files

* build: load v8_prof_processor dependencies as ESM

* chore: add patch to fix linux 32bit

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2021-03-04 09:27:05 -08:00

262 lines
11 KiB
C++

// Copyright (c) 2019 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_NET_PROXYING_URL_LOADER_FACTORY_H_
#define SHELL_BROWSER_NET_PROXYING_URL_LOADER_FACTORY_H_
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "base/optional.h"
#include "content/public/browser/content_browser_client.h"
#include "extensions/browser/api/web_request/web_request_info.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "shell/browser/api/electron_api_web_request.h"
#include "shell/browser/net/electron_url_loader_factory.h"
#include "shell/browser/net/web_request_api_interface.h"
namespace electron {
// This class is responsible for following tasks when NetworkService is enabled:
// 1. handling intercepted protocols;
// 2. implementing webRequest module;
//
// For the task #2, the code is referenced from the
// extensions::WebRequestProxyingURLLoaderFactory class.
class ProxyingURLLoaderFactory
: public network::mojom::URLLoaderFactory,
public network::mojom::TrustedURLLoaderHeaderClient {
public:
class InProgressRequest : public network::mojom::URLLoader,
public network::mojom::URLLoaderClient,
public network::mojom::TrustedHeaderClient {
public:
// For usual requests.
InProgressRequest(
ProxyingURLLoaderFactory* factory,
int64_t web_request_id,
int32_t routing_id,
int32_t network_service_request_id,
uint32_t options,
const network::ResourceRequest& request,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
mojo::PendingReceiver<network::mojom::URLLoader> loader_receiver,
mojo::PendingRemote<network::mojom::URLLoaderClient> client);
// For CORS preflights.
InProgressRequest(ProxyingURLLoaderFactory* factory,
uint64_t request_id,
const network::ResourceRequest& request);
~InProgressRequest() override;
void Restart();
// network::mojom::URLLoader:
void FollowRedirect(
const std::vector<std::string>& removed_headers,
const net::HttpRequestHeaders& modified_headers,
const net::HttpRequestHeaders& modified_cors_exempt_headers,
const base::Optional<GURL>& new_url) override;
void SetPriority(net::RequestPriority priority,
int32_t intra_priority_value) override;
void PauseReadingBodyFromNet() override;
void ResumeReadingBodyFromNet() override;
// network::mojom::URLLoaderClient:
void OnReceiveResponse(network::mojom::URLResponseHeadPtr head) override;
void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
network::mojom::URLResponseHeadPtr head) override;
void OnUploadProgress(int64_t current_position,
int64_t total_size,
OnUploadProgressCallback callback) override;
void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override;
void OnComplete(const network::URLLoaderCompletionStatus& status) override;
void OnLoaderCreated(
mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver);
// network::mojom::TrustedHeaderClient:
void OnBeforeSendHeaders(const net::HttpRequestHeaders& headers,
OnBeforeSendHeadersCallback callback) override;
void OnHeadersReceived(const std::string& headers,
const net::IPEndPoint& endpoint,
OnHeadersReceivedCallback callback) override;
private:
// These two methods combined form the implementation of Restart().
void UpdateRequestInfo();
void RestartInternal();
void ContinueToBeforeSendHeaders(int error_code);
void ContinueToSendHeaders(const std::set<std::string>& removed_headers,
const std::set<std::string>& set_headers,
int error_code);
void ContinueToStartRequest(int error_code);
void ContinueToHandleOverrideHeaders(int error_code);
void ContinueToResponseStarted(int error_code);
void ContinueToBeforeRedirect(const net::RedirectInfo& redirect_info,
int error_code);
void HandleBeforeRequestRedirect();
void HandleResponseOrRedirectHeaders(
net::CompletionOnceCallback continuation);
void OnRequestError(const network::URLLoaderCompletionStatus& status);
ProxyingURLLoaderFactory* factory_;
network::ResourceRequest request_;
const base::Optional<url::Origin> original_initiator_;
const uint64_t request_id_ = 0;
const int32_t routing_id_ = 0;
const int32_t network_service_request_id_ = 0;
const uint32_t options_ = 0;
const net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
mojo::Receiver<network::mojom::URLLoader> proxied_loader_receiver_;
mojo::Remote<network::mojom::URLLoaderClient> target_client_;
base::Optional<extensions::WebRequestInfo> info_;
network::mojom::URLResponseHeadPtr current_response_;
scoped_refptr<net::HttpResponseHeaders> override_headers_;
GURL redirect_url_;
mojo::Receiver<network::mojom::URLLoaderClient> proxied_client_receiver_{
this};
network::mojom::URLLoaderPtr target_loader_;
const bool for_cors_preflight_ = false;
// If |has_any_extra_headers_listeners_| is set to true, the request will be
// sent with the network::mojom::kURLLoadOptionUseHeaderClient option, and
// we expect events to come through the
// network::mojom::TrustedURLLoaderHeaderClient binding on the factory. This
// is only set to true if there is a listener that needs to view or modify
// headers set in the network process.
bool has_any_extra_headers_listeners_ = false;
bool current_request_uses_header_client_ = false;
OnBeforeSendHeadersCallback on_before_send_headers_callback_;
OnHeadersReceivedCallback on_headers_received_callback_;
mojo::Receiver<network::mojom::TrustedHeaderClient> header_client_receiver_{
this};
// If |has_any_extra_headers_listeners_| is set to false and a redirect is
// in progress, this stores the parameters to FollowRedirect that came from
// the client. That way we can combine it with any other changes that
// extensions made to headers in their callbacks.
struct FollowRedirectParams {
FollowRedirectParams();
~FollowRedirectParams();
std::vector<std::string> removed_headers;
net::HttpRequestHeaders modified_headers;
net::HttpRequestHeaders modified_cors_exempt_headers;
base::Optional<GURL> new_url;
DISALLOW_COPY_AND_ASSIGN(FollowRedirectParams);
};
std::unique_ptr<FollowRedirectParams> pending_follow_redirect_params_;
base::WeakPtrFactory<InProgressRequest> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(InProgressRequest);
};
ProxyingURLLoaderFactory(
WebRequestAPI* web_request_api,
const HandlersMap& intercepted_handlers,
int render_process_id,
uint64_t* request_id_generator,
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data,
base::Optional<int64_t> navigation_id,
network::mojom::URLLoaderFactoryRequest loader_request,
mojo::PendingRemote<network::mojom::URLLoaderFactory>
target_factory_remote,
mojo::PendingReceiver<network::mojom::TrustedURLLoaderHeaderClient>
header_client_receiver,
content::ContentBrowserClient::URLLoaderFactoryType loader_factory_type);
~ProxyingURLLoaderFactory() override;
// network::mojom::URLLoaderFactory:
void CreateLoaderAndStart(
mojo::PendingReceiver<network::mojom::URLLoader> loader,
int32_t routing_id,
int32_t request_id,
uint32_t options,
const network::ResourceRequest& request,
mojo::PendingRemote<network::mojom::URLLoaderClient> client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
override;
void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory>
loader_receiver) override;
// network::mojom::TrustedURLLoaderHeaderClient:
void OnLoaderCreated(
int32_t request_id,
mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver)
override;
void OnLoaderForCorsPreflightCreated(
const network::ResourceRequest& request,
mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver)
override;
WebRequestAPI* web_request_api() { return web_request_api_; }
bool IsForServiceWorkerScript() const;
private:
void OnTargetFactoryError();
void OnProxyBindingError();
void RemoveRequest(int32_t network_service_request_id, uint64_t request_id);
void MaybeDeleteThis();
bool ShouldIgnoreConnectionsLimit(const network::ResourceRequest& request);
// Passed from api::WebRequest.
WebRequestAPI* web_request_api_;
// This is passed from api::Protocol.
//
// The Protocol instance lives through the lifetime of BrowserContext,
// which is guaranteed to cover the lifetime of URLLoaderFactory, so the
// reference is guaranteed to be valid.
//
// In this way we can avoid using code from api namespace in this file.
const HandlersMap& intercepted_handlers_;
const int render_process_id_;
uint64_t* request_id_generator_; // managed by ElectronBrowserClient
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data_;
base::Optional<int64_t> navigation_id_;
mojo::ReceiverSet<network::mojom::URLLoaderFactory> proxy_receivers_;
mojo::Remote<network::mojom::URLLoaderFactory> target_factory_;
mojo::Receiver<network::mojom::TrustedURLLoaderHeaderClient>
url_loader_header_client_receiver_{this};
const content::ContentBrowserClient::URLLoaderFactoryType
loader_factory_type_;
// Mapping from our own internally generated request ID to an
// InProgressRequest instance.
std::map<uint64_t, std::unique_ptr<InProgressRequest>> requests_;
// A mapping from the network stack's notion of request ID to our own
// internally generated request ID for the same request.
std::map<int32_t, uint64_t> network_request_id_to_web_request_id_;
std::vector<std::string> ignore_connections_limit_domains_;
DISALLOW_COPY_AND_ASSIGN(ProxyingURLLoaderFactory);
};
} // namespace electron
#endif // SHELL_BROWSER_NET_PROXYING_URL_LOADER_FACTORY_H_