feat: migrate protocol module to NetworkService (Part 10) (#18464)

* Explicitly call OnReceiveRedirect for redirections

* Better way for detecting redirection

* Create new loader for redirections
This commit is contained in:
Cheng Zhao 2019-05-28 15:08:50 +09:00 committed by GitHub
parent c0c5ebb271
commit 00964b98b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 13 deletions

View file

@ -121,7 +121,8 @@ network::ResourceResponseHead ToResponseHead(const mate::Dictionary& dict) {
} }
// Some apps are passing content-type via headers, which is not accepted // Some apps are passing content-type via headers, which is not accepted
// in NetworkService. // in NetworkService.
if (iter.first == "content-type" && iter.second.is_string()) { if (base::ToLowerASCII(iter.first) == "content-type" &&
iter.second.is_string()) {
head.mime_type = iter.second.GetString(); head.mime_type = iter.second.GetString();
has_content_type = true; has_content_type = true;
} }
@ -176,7 +177,7 @@ void AtomURLLoaderFactory::CreateLoaderAndStart(
request, request,
base::BindOnce(&AtomURLLoaderFactory::StartLoading, std::move(loader), base::BindOnce(&AtomURLLoaderFactory::StartLoading, std::move(loader),
routing_id, request_id, options, request, routing_id, request_id, options, request,
std::move(client), traffic_annotation, type_)); std::move(client), traffic_annotation, nullptr, type_));
} }
void AtomURLLoaderFactory::Clone( void AtomURLLoaderFactory::Clone(
@ -193,6 +194,7 @@ void AtomURLLoaderFactory::StartLoading(
const network::ResourceRequest& request, const network::ResourceRequest& request,
network::mojom::URLLoaderClientPtr client, network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
network::mojom::URLLoaderFactory* proxy_factory,
ProtocolType type, ProtocolType type,
mate::Arguments* args) { mate::Arguments* args) {
// Send network error when there is no argument passed. // Send network error when there is no argument passed.
@ -216,6 +218,43 @@ void AtomURLLoaderFactory::StartLoading(
} }
} }
network::ResourceResponseHead head = ToResponseHead(dict);
// Handle redirection.
//
// Note that with NetworkService, sending the "Location" header no longer
// automatically redirects the request, we have explicitly create a new loader
// to implement redirection. This is also what Chromium does with WebRequest
// API in WebRequestProxyingURLLoaderFactory.
std::string location;
if (head.headers->IsRedirect(&location)) {
network::ResourceRequest new_request = request;
new_request.url = GURL(location);
// When the redirection comes from an intercepted scheme (which has
// |proxy_factory| passed), we askes the proxy factory to create a loader
// for new URL, otherwise we call |StartLoadingHttp|, which creates
// loader with default factory.
//
// Note that when handling requests for intercepted scheme, creating loader
// with default factory (i.e. calling StartLoadingHttp) would bypass the
// ProxyingURLLoaderFactory, we have to explicitly use the proxy factory to
// create loader so it is possible to have handlers of intercepted scheme
// getting called recursively, which is a behavior expected in protocol
// module.
//
// I'm not sure whether this is an intended behavior in Chromium.
if (proxy_factory) {
proxy_factory->CreateLoaderAndStart(
std::move(loader), routing_id, request_id, options, new_request,
std::move(client), traffic_annotation);
} else {
StartLoadingHttp(std::move(loader), routing_id, request_id, options,
new_request, std::move(client), traffic_annotation,
mate::Dictionary::CreateEmpty(args->isolate()));
}
return;
}
// Some protocol accepts non-object responses. // Some protocol accepts non-object responses.
if (dict.IsEmpty() && ResponseMustBeObject(type)) { if (dict.IsEmpty() && ResponseMustBeObject(type)) {
client->OnComplete( client->OnComplete(
@ -225,21 +264,23 @@ void AtomURLLoaderFactory::StartLoading(
switch (type) { switch (type) {
case ProtocolType::kBuffer: case ProtocolType::kBuffer:
StartLoadingBuffer(std::move(client), dict); StartLoadingBuffer(std::move(client), std::move(head), dict);
break; break;
case ProtocolType::kString: case ProtocolType::kString:
StartLoadingString(std::move(client), dict, args->isolate(), response); StartLoadingString(std::move(client), std::move(head), dict,
args->isolate(), response);
break; break;
case ProtocolType::kFile: case ProtocolType::kFile:
StartLoadingFile(std::move(loader), request, std::move(client), dict, StartLoadingFile(std::move(loader), request, std::move(client),
args->isolate(), response); std::move(head), dict, args->isolate(), response);
break; break;
case ProtocolType::kHttp: case ProtocolType::kHttp:
StartLoadingHttp(std::move(loader), routing_id, request_id, options, StartLoadingHttp(std::move(loader), routing_id, request_id, options,
request, std::move(client), traffic_annotation, dict); request, std::move(client), traffic_annotation, dict);
break; break;
case ProtocolType::kStream: case ProtocolType::kStream:
StartLoadingStream(std::move(loader), std::move(client), dict); StartLoadingStream(std::move(loader), std::move(client), std::move(head),
dict);
break; break;
case ProtocolType::kFree: case ProtocolType::kFree:
ProtocolType type; ProtocolType type;
@ -248,7 +289,8 @@ void AtomURLLoaderFactory::StartLoading(
return; return;
} }
StartLoading(std::move(loader), routing_id, request_id, options, request, StartLoading(std::move(loader), routing_id, request_id, options, request,
std::move(client), traffic_annotation, type, args); std::move(client), traffic_annotation, proxy_factory, type,
args);
break; break;
} }
} }
@ -256,6 +298,7 @@ void AtomURLLoaderFactory::StartLoading(
// static // static
void AtomURLLoaderFactory::StartLoadingBuffer( void AtomURLLoaderFactory::StartLoadingBuffer(
network::mojom::URLLoaderClientPtr client, network::mojom::URLLoaderClientPtr client,
network::ResourceResponseHead head,
const mate::Dictionary& dict) { const mate::Dictionary& dict) {
v8::Local<v8::Value> buffer = dict.GetHandle(); v8::Local<v8::Value> buffer = dict.GetHandle();
dict.Get("data", &buffer); dict.Get("data", &buffer);
@ -265,13 +308,14 @@ void AtomURLLoaderFactory::StartLoadingBuffer(
} }
SendContents( SendContents(
std::move(client), ToResponseHead(dict), std::move(client), std::move(head),
std::string(node::Buffer::Data(buffer), node::Buffer::Length(buffer))); std::string(node::Buffer::Data(buffer), node::Buffer::Length(buffer)));
} }
// static // static
void AtomURLLoaderFactory::StartLoadingString( void AtomURLLoaderFactory::StartLoadingString(
network::mojom::URLLoaderClientPtr client, network::mojom::URLLoaderClientPtr client,
network::ResourceResponseHead head,
const mate::Dictionary& dict, const mate::Dictionary& dict,
v8::Isolate* isolate, v8::Isolate* isolate,
v8::Local<v8::Value> response) { v8::Local<v8::Value> response) {
@ -281,7 +325,7 @@ void AtomURLLoaderFactory::StartLoadingString(
else if (!dict.IsEmpty()) else if (!dict.IsEmpty())
dict.Get("data", &contents); dict.Get("data", &contents);
SendContents(std::move(client), ToResponseHead(dict), std::move(contents)); SendContents(std::move(client), std::move(head), std::move(contents));
} }
// static // static
@ -289,6 +333,7 @@ void AtomURLLoaderFactory::StartLoadingFile(
network::mojom::URLLoaderRequest loader, network::mojom::URLLoaderRequest loader,
network::ResourceRequest request, network::ResourceRequest request,
network::mojom::URLLoaderClientPtr client, network::mojom::URLLoaderClientPtr client,
network::ResourceResponseHead head,
const mate::Dictionary& dict, const mate::Dictionary& dict,
v8::Isolate* isolate, v8::Isolate* isolate,
v8::Local<v8::Value> response) { v8::Local<v8::Value> response) {
@ -305,7 +350,6 @@ void AtomURLLoaderFactory::StartLoadingFile(
return; return;
} }
network::ResourceResponseHead head = ToResponseHead(dict);
head.headers->AddHeader(kCORSHeader); head.headers->AddHeader(kCORSHeader);
asar::CreateAsarURLLoader(request, std::move(loader), std::move(client), asar::CreateAsarURLLoader(request, std::move(loader), std::move(client),
head.headers); head.headers);
@ -357,8 +401,8 @@ void AtomURLLoaderFactory::StartLoadingHttp(
void AtomURLLoaderFactory::StartLoadingStream( void AtomURLLoaderFactory::StartLoadingStream(
network::mojom::URLLoaderRequest loader, network::mojom::URLLoaderRequest loader,
network::mojom::URLLoaderClientPtr client, network::mojom::URLLoaderClientPtr client,
network::ResourceResponseHead head,
const mate::Dictionary& dict) { const mate::Dictionary& dict) {
network::ResourceResponseHead head = ToResponseHead(dict);
v8::Local<v8::Value> stream; v8::Local<v8::Value> stream;
if (!dict.Get("data", &stream)) { if (!dict.Get("data", &stream)) {
// Assume the opts is already a stream. // Assume the opts is already a stream.

View file

@ -59,19 +59,23 @@ class AtomURLLoaderFactory : public network::mojom::URLLoaderFactory {
const network::ResourceRequest& request, const network::ResourceRequest& request,
network::mojom::URLLoaderClientPtr client, network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
network::mojom::URLLoaderFactory* proxy_factory,
ProtocolType type, ProtocolType type,
mate::Arguments* args); mate::Arguments* args);
private: private:
static void StartLoadingBuffer(network::mojom::URLLoaderClientPtr client, static void StartLoadingBuffer(network::mojom::URLLoaderClientPtr client,
network::ResourceResponseHead head,
const mate::Dictionary& dict); const mate::Dictionary& dict);
static void StartLoadingString(network::mojom::URLLoaderClientPtr client, static void StartLoadingString(network::mojom::URLLoaderClientPtr client,
network::ResourceResponseHead head,
const mate::Dictionary& dict, const mate::Dictionary& dict,
v8::Isolate* isolate, v8::Isolate* isolate,
v8::Local<v8::Value> response); v8::Local<v8::Value> response);
static void StartLoadingFile(network::mojom::URLLoaderRequest loader, static void StartLoadingFile(network::mojom::URLLoaderRequest loader,
network::ResourceRequest request, network::ResourceRequest request,
network::mojom::URLLoaderClientPtr client, network::mojom::URLLoaderClientPtr client,
network::ResourceResponseHead head,
const mate::Dictionary& dict, const mate::Dictionary& dict,
v8::Isolate* isolate, v8::Isolate* isolate,
v8::Local<v8::Value> response); v8::Local<v8::Value> response);
@ -86,6 +90,7 @@ class AtomURLLoaderFactory : public network::mojom::URLLoaderFactory {
const mate::Dictionary& dict); const mate::Dictionary& dict);
static void StartLoadingStream(network::mojom::URLLoaderRequest loader, static void StartLoadingStream(network::mojom::URLLoaderRequest loader,
network::mojom::URLLoaderClientPtr client, network::mojom::URLLoaderClientPtr client,
network::ResourceResponseHead head,
const mate::Dictionary& dict); const mate::Dictionary& dict);
// Helper to send string as response. // Helper to send string as response.

View file

@ -43,7 +43,7 @@ void ProxyingURLLoaderFactory::CreateLoaderAndStart(
request, base::BindOnce(&AtomURLLoaderFactory::StartLoading, request, base::BindOnce(&AtomURLLoaderFactory::StartLoading,
std::move(loader), routing_id, request_id, std::move(loader), routing_id, request_id,
options, request, std::move(client), options, request, std::move(client),
traffic_annotation, it->second.first)); traffic_annotation, this, it->second.first));
return; return;
} }