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:
parent
c0c5ebb271
commit
00964b98b9
3 changed files with 62 additions and 13 deletions
|
@ -121,7 +121,8 @@ network::ResourceResponseHead ToResponseHead(const mate::Dictionary& dict) {
|
|||
}
|
||||
// Some apps are passing content-type via headers, which is not accepted
|
||||
// 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();
|
||||
has_content_type = true;
|
||||
}
|
||||
|
@ -176,7 +177,7 @@ void AtomURLLoaderFactory::CreateLoaderAndStart(
|
|||
request,
|
||||
base::BindOnce(&AtomURLLoaderFactory::StartLoading, std::move(loader),
|
||||
routing_id, request_id, options, request,
|
||||
std::move(client), traffic_annotation, type_));
|
||||
std::move(client), traffic_annotation, nullptr, type_));
|
||||
}
|
||||
|
||||
void AtomURLLoaderFactory::Clone(
|
||||
|
@ -193,6 +194,7 @@ void AtomURLLoaderFactory::StartLoading(
|
|||
const network::ResourceRequest& request,
|
||||
network::mojom::URLLoaderClientPtr client,
|
||||
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
|
||||
network::mojom::URLLoaderFactory* proxy_factory,
|
||||
ProtocolType type,
|
||||
mate::Arguments* args) {
|
||||
// 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.
|
||||
if (dict.IsEmpty() && ResponseMustBeObject(type)) {
|
||||
client->OnComplete(
|
||||
|
@ -225,21 +264,23 @@ void AtomURLLoaderFactory::StartLoading(
|
|||
|
||||
switch (type) {
|
||||
case ProtocolType::kBuffer:
|
||||
StartLoadingBuffer(std::move(client), dict);
|
||||
StartLoadingBuffer(std::move(client), std::move(head), dict);
|
||||
break;
|
||||
case ProtocolType::kString:
|
||||
StartLoadingString(std::move(client), dict, args->isolate(), response);
|
||||
StartLoadingString(std::move(client), std::move(head), dict,
|
||||
args->isolate(), response);
|
||||
break;
|
||||
case ProtocolType::kFile:
|
||||
StartLoadingFile(std::move(loader), request, std::move(client), dict,
|
||||
args->isolate(), response);
|
||||
StartLoadingFile(std::move(loader), request, std::move(client),
|
||||
std::move(head), dict, args->isolate(), response);
|
||||
break;
|
||||
case ProtocolType::kHttp:
|
||||
StartLoadingHttp(std::move(loader), routing_id, request_id, options,
|
||||
request, std::move(client), traffic_annotation, dict);
|
||||
break;
|
||||
case ProtocolType::kStream:
|
||||
StartLoadingStream(std::move(loader), std::move(client), dict);
|
||||
StartLoadingStream(std::move(loader), std::move(client), std::move(head),
|
||||
dict);
|
||||
break;
|
||||
case ProtocolType::kFree:
|
||||
ProtocolType type;
|
||||
|
@ -248,7 +289,8 @@ void AtomURLLoaderFactory::StartLoading(
|
|||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -256,6 +298,7 @@ void AtomURLLoaderFactory::StartLoading(
|
|||
// static
|
||||
void AtomURLLoaderFactory::StartLoadingBuffer(
|
||||
network::mojom::URLLoaderClientPtr client,
|
||||
network::ResourceResponseHead head,
|
||||
const mate::Dictionary& dict) {
|
||||
v8::Local<v8::Value> buffer = dict.GetHandle();
|
||||
dict.Get("data", &buffer);
|
||||
|
@ -265,13 +308,14 @@ void AtomURLLoaderFactory::StartLoadingBuffer(
|
|||
}
|
||||
|
||||
SendContents(
|
||||
std::move(client), ToResponseHead(dict),
|
||||
std::move(client), std::move(head),
|
||||
std::string(node::Buffer::Data(buffer), node::Buffer::Length(buffer)));
|
||||
}
|
||||
|
||||
// static
|
||||
void AtomURLLoaderFactory::StartLoadingString(
|
||||
network::mojom::URLLoaderClientPtr client,
|
||||
network::ResourceResponseHead head,
|
||||
const mate::Dictionary& dict,
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> response) {
|
||||
|
@ -281,7 +325,7 @@ void AtomURLLoaderFactory::StartLoadingString(
|
|||
else if (!dict.IsEmpty())
|
||||
dict.Get("data", &contents);
|
||||
|
||||
SendContents(std::move(client), ToResponseHead(dict), std::move(contents));
|
||||
SendContents(std::move(client), std::move(head), std::move(contents));
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -289,6 +333,7 @@ void AtomURLLoaderFactory::StartLoadingFile(
|
|||
network::mojom::URLLoaderRequest loader,
|
||||
network::ResourceRequest request,
|
||||
network::mojom::URLLoaderClientPtr client,
|
||||
network::ResourceResponseHead head,
|
||||
const mate::Dictionary& dict,
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> response) {
|
||||
|
@ -305,7 +350,6 @@ void AtomURLLoaderFactory::StartLoadingFile(
|
|||
return;
|
||||
}
|
||||
|
||||
network::ResourceResponseHead head = ToResponseHead(dict);
|
||||
head.headers->AddHeader(kCORSHeader);
|
||||
asar::CreateAsarURLLoader(request, std::move(loader), std::move(client),
|
||||
head.headers);
|
||||
|
@ -357,8 +401,8 @@ void AtomURLLoaderFactory::StartLoadingHttp(
|
|||
void AtomURLLoaderFactory::StartLoadingStream(
|
||||
network::mojom::URLLoaderRequest loader,
|
||||
network::mojom::URLLoaderClientPtr client,
|
||||
network::ResourceResponseHead head,
|
||||
const mate::Dictionary& dict) {
|
||||
network::ResourceResponseHead head = ToResponseHead(dict);
|
||||
v8::Local<v8::Value> stream;
|
||||
if (!dict.Get("data", &stream)) {
|
||||
// Assume the opts is already a stream.
|
||||
|
|
|
@ -59,19 +59,23 @@ class AtomURLLoaderFactory : public network::mojom::URLLoaderFactory {
|
|||
const network::ResourceRequest& request,
|
||||
network::mojom::URLLoaderClientPtr client,
|
||||
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
|
||||
network::mojom::URLLoaderFactory* proxy_factory,
|
||||
ProtocolType type,
|
||||
mate::Arguments* args);
|
||||
|
||||
private:
|
||||
static void StartLoadingBuffer(network::mojom::URLLoaderClientPtr client,
|
||||
network::ResourceResponseHead head,
|
||||
const mate::Dictionary& dict);
|
||||
static void StartLoadingString(network::mojom::URLLoaderClientPtr client,
|
||||
network::ResourceResponseHead head,
|
||||
const mate::Dictionary& dict,
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> response);
|
||||
static void StartLoadingFile(network::mojom::URLLoaderRequest loader,
|
||||
network::ResourceRequest request,
|
||||
network::mojom::URLLoaderClientPtr client,
|
||||
network::ResourceResponseHead head,
|
||||
const mate::Dictionary& dict,
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> response);
|
||||
|
@ -86,6 +90,7 @@ class AtomURLLoaderFactory : public network::mojom::URLLoaderFactory {
|
|||
const mate::Dictionary& dict);
|
||||
static void StartLoadingStream(network::mojom::URLLoaderRequest loader,
|
||||
network::mojom::URLLoaderClientPtr client,
|
||||
network::ResourceResponseHead head,
|
||||
const mate::Dictionary& dict);
|
||||
|
||||
// Helper to send string as response.
|
||||
|
|
|
@ -43,7 +43,7 @@ void ProxyingURLLoaderFactory::CreateLoaderAndStart(
|
|||
request, base::BindOnce(&AtomURLLoaderFactory::StartLoading,
|
||||
std::move(loader), routing_id, request_id,
|
||||
options, request, std::move(client),
|
||||
traffic_annotation, it->second.first));
|
||||
traffic_annotation, this, it->second.first));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue