fix: webRequest module should work with file:// protocol (9-x-y) (#22919)

* fix: webRequest module should work with file:// protocol

* test: do not trigger unhandled promise rejections
This commit is contained in:
Cheng Zhao
2020-04-02 05:36:24 +09:00
committed by GitHub
parent 050844dc38
commit f255d47073
6 changed files with 102 additions and 9 deletions

View File

@@ -12,6 +12,7 @@
#include "content/public/browser/child_process_security_policy.h"
#include "shell/browser/browser.h"
#include "shell/browser/electron_browser_context.h"
#include "shell/browser/net/asar/asar_url_loader.h"
#include "shell/common/gin_converters/callback_converter.h"
#include "shell/common/gin_converters/net_converter.h"
#include "shell/common/gin_helper/dictionary.h"
@@ -40,6 +41,34 @@ struct CustomScheme {
SchemeOptions options;
};
// Provide support for accessing asar archives in file:// protocol.
class AsarURLLoaderFactory : public network::mojom::URLLoaderFactory {
public:
AsarURLLoaderFactory() {}
private:
// 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 {
asar::CreateAsarURLLoader(request, std::move(loader), std::move(client),
new net::HttpResponseHeaders(""));
}
void Clone(
mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) override {
receivers_.Add(this, std::move(loader));
}
mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
};
} // namespace
namespace gin {
@@ -169,7 +198,25 @@ Protocol::Protocol(v8::Isolate* isolate,
Protocol::~Protocol() = default;
void Protocol::RegisterURLLoaderFactories(
URLLoaderFactoryType type,
content::ContentBrowserClient::NonNetworkURLLoaderFactoryMap* factories) {
// Override the default FileURLLoaderFactory to support asar archives.
if (type == URLLoaderFactoryType::kNavigation) {
// Always allow navigating to file:// URLs.
//
// Note that Chromium calls |emplace| to create the default file factory
// after this call, so it won't override our asar factory.
DCHECK(!base::Contains(*factories, url::kFileScheme));
factories->emplace(url::kFileScheme,
std::make_unique<AsarURLLoaderFactory>());
} else if (type == URLLoaderFactoryType::kDocumentSubResource) {
// Only support requesting file:// subresource URLs when Chromium does so,
// it is usually supported under file:// or about:blank documents.
auto file_factory = factories->find(url::kFileScheme);
if (file_factory != factories->end())
file_factory->second = std::make_unique<AsarURLLoaderFactory>();
}
for (const auto& it : handlers_) {
factories->emplace(it.first, std::make_unique<ElectronURLLoaderFactory>(
it.second.first, it.second.second));

View File

@@ -43,8 +43,12 @@ class Protocol : public gin_helper::TrackableObject<Protocol> {
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
using URLLoaderFactoryType =
content::ContentBrowserClient::URLLoaderFactoryType;
// Used by ElectronBrowserClient for creating URLLoaderFactory.
void RegisterURLLoaderFactories(
URLLoaderFactoryType type,
content::ContentBrowserClient::NonNetworkURLLoaderFactoryMap* factories);
const HandlersMap& intercept_handlers() const { return intercept_handlers_; }

View File

@@ -292,11 +292,12 @@ int WebRequest::OnHeadersReceived(
const net::HttpResponseHeaders* original_response_headers,
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
GURL* allowed_unsafe_redirect_url) {
const std::string& status_line =
original_response_headers ? original_response_headers->GetStatusLine()
: std::string();
return HandleResponseEvent(
kOnHeadersReceived, info, std::move(callback),
std::make_pair(override_response_headers,
original_response_headers->GetStatusLine()),
request);
std::make_pair(override_response_headers, status_line), request);
}
void WebRequest::OnSendHeaders(extensions::WebRequestInfo* info,