fix: sourcemaps not loading with network service (#21473)
Backports1525270
Backports1852212
This commit is contained in:
parent
aa4b36a03d
commit
63e600f655
1 changed files with 137 additions and 33 deletions
|
@ -27,10 +27,12 @@
|
||||||
#include "content/public/browser/browser_task_traits.h"
|
#include "content/public/browser/browser_task_traits.h"
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "content/public/browser/file_select_listener.h"
|
#include "content/public/browser/file_select_listener.h"
|
||||||
|
#include "content/public/browser/file_url_loader.h"
|
||||||
#include "content/public/browser/host_zoom_map.h"
|
#include "content/public/browser/host_zoom_map.h"
|
||||||
#include "content/public/browser/navigation_handle.h"
|
#include "content/public/browser/navigation_handle.h"
|
||||||
#include "content/public/browser/render_frame_host.h"
|
#include "content/public/browser/render_frame_host.h"
|
||||||
#include "content/public/browser/render_view_host.h"
|
#include "content/public/browser/render_view_host.h"
|
||||||
|
#include "content/public/browser/shared_cors_origin_access_list.h"
|
||||||
#include "content/public/browser/storage_partition.h"
|
#include "content/public/browser/storage_partition.h"
|
||||||
#include "content/public/common/user_agent.h"
|
#include "content/public/common/user_agent.h"
|
||||||
#include "ipc/ipc_channel.h"
|
#include "ipc/ipc_channel.h"
|
||||||
|
@ -62,7 +64,7 @@ const char kChromeUIDevToolsURL[] =
|
||||||
"textColor=rgba(0,0,0,1)&"
|
"textColor=rgba(0,0,0,1)&"
|
||||||
"experiments=true";
|
"experiments=true";
|
||||||
const char kChromeUIDevToolsRemoteFrontendBase[] =
|
const char kChromeUIDevToolsRemoteFrontendBase[] =
|
||||||
"https://devtools-frontend.appspot.com/";
|
"https://chrome-devtools-frontend.appspot.com/";
|
||||||
const char kChromeUIDevToolsRemoteFrontendPath[] = "serve_file";
|
const char kChromeUIDevToolsRemoteFrontendPath[] = "serve_file";
|
||||||
|
|
||||||
const char kDevToolsBoundsPref[] = "electron.devtools.bounds";
|
const char kDevToolsBoundsPref[] = "electron.devtools.bounds";
|
||||||
|
@ -150,29 +152,87 @@ GURL GetDevToolsURL(bool can_dock) {
|
||||||
return GURL(url_string);
|
return GURL(url_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr base::TimeDelta kInitialBackoffDelay =
|
||||||
|
base::TimeDelta::FromMilliseconds(250);
|
||||||
|
constexpr base::TimeDelta kMaxBackoffDelay = base::TimeDelta::FromSeconds(10);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class InspectableWebContentsImpl::NetworkResourceLoader
|
class InspectableWebContentsImpl::NetworkResourceLoader
|
||||||
: public network::SimpleURLLoaderStreamConsumer {
|
: public network::SimpleURLLoaderStreamConsumer {
|
||||||
public:
|
public:
|
||||||
NetworkResourceLoader(int stream_id,
|
class URLLoaderFactoryHolder {
|
||||||
|
public:
|
||||||
|
network::mojom::URLLoaderFactory* get() {
|
||||||
|
return ptr_.get() ? ptr_.get() : refptr_.get();
|
||||||
|
}
|
||||||
|
void operator=(std::unique_ptr<network::mojom::URLLoaderFactory>&& ptr) {
|
||||||
|
ptr_ = std::move(ptr);
|
||||||
|
}
|
||||||
|
void operator=(scoped_refptr<network::SharedURLLoaderFactory>&& refptr) {
|
||||||
|
refptr_ = std::move(refptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<network::mojom::URLLoaderFactory> ptr_;
|
||||||
|
scoped_refptr<network::SharedURLLoaderFactory> refptr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Create(int stream_id,
|
||||||
InspectableWebContentsImpl* bindings,
|
InspectableWebContentsImpl* bindings,
|
||||||
std::unique_ptr<network::SimpleURLLoader> loader,
|
const network::ResourceRequest& resource_request,
|
||||||
network::mojom::URLLoaderFactory* url_loader_factory,
|
const net::NetworkTrafficAnnotationTag& traffic_annotation,
|
||||||
const DispatchCallback& callback)
|
URLLoaderFactoryHolder url_loader_factory,
|
||||||
|
const DispatchCallback& callback,
|
||||||
|
base::TimeDelta retry_delay = base::TimeDelta()) {
|
||||||
|
auto resource_loader =
|
||||||
|
std::make_unique<InspectableWebContentsImpl::NetworkResourceLoader>(
|
||||||
|
stream_id, bindings, resource_request, traffic_annotation,
|
||||||
|
std::move(url_loader_factory), callback, retry_delay);
|
||||||
|
bindings->loaders_.insert(std::move(resource_loader));
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkResourceLoader(
|
||||||
|
int stream_id,
|
||||||
|
InspectableWebContentsImpl* bindings,
|
||||||
|
const network::ResourceRequest& resource_request,
|
||||||
|
const net::NetworkTrafficAnnotationTag& traffic_annotation,
|
||||||
|
URLLoaderFactoryHolder url_loader_factory,
|
||||||
|
const DispatchCallback& callback,
|
||||||
|
base::TimeDelta delay)
|
||||||
: stream_id_(stream_id),
|
: stream_id_(stream_id),
|
||||||
bindings_(bindings),
|
bindings_(bindings),
|
||||||
loader_(std::move(loader)),
|
resource_request_(resource_request),
|
||||||
callback_(callback) {
|
traffic_annotation_(traffic_annotation),
|
||||||
|
loader_(network::SimpleURLLoader::Create(
|
||||||
|
std::make_unique<network::ResourceRequest>(resource_request),
|
||||||
|
traffic_annotation)),
|
||||||
|
url_loader_factory_(std::move(url_loader_factory)),
|
||||||
|
callback_(callback),
|
||||||
|
retry_delay_(delay) {
|
||||||
loader_->SetOnResponseStartedCallback(base::BindOnce(
|
loader_->SetOnResponseStartedCallback(base::BindOnce(
|
||||||
&NetworkResourceLoader::OnResponseStarted, base::Unretained(this)));
|
&NetworkResourceLoader::OnResponseStarted, base::Unretained(this)));
|
||||||
loader_->DownloadAsStream(url_loader_factory, this);
|
timer_.Start(FROM_HERE, delay,
|
||||||
|
base::BindRepeating(&NetworkResourceLoader::DownloadAsStream,
|
||||||
|
base::Unretained(this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkResourceLoader(const NetworkResourceLoader&) = delete;
|
NetworkResourceLoader(const NetworkResourceLoader&) = delete;
|
||||||
NetworkResourceLoader& operator=(const NetworkResourceLoader&) = delete;
|
NetworkResourceLoader& operator=(const NetworkResourceLoader&) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void DownloadAsStream() {
|
||||||
|
loader_->DownloadAsStream(url_loader_factory_.get(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
base::TimeDelta GetNextExponentialBackoffDelay(const base::TimeDelta& delta) {
|
||||||
|
if (delta.is_zero()) {
|
||||||
|
return kInitialBackoffDelay;
|
||||||
|
} else {
|
||||||
|
return delta * 1.3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OnResponseStarted(const GURL& final_url,
|
void OnResponseStarted(const GURL& final_url,
|
||||||
const network::mojom::URLResponseHead& response_head) {
|
const network::mojom::URLResponseHead& response_head) {
|
||||||
response_headers_ = response_head.headers;
|
response_headers_ = response_head.headers;
|
||||||
|
@ -199,6 +259,18 @@ class InspectableWebContentsImpl::NetworkResourceLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnComplete(bool success) override {
|
void OnComplete(bool success) override {
|
||||||
|
if (!success && loader_->NetError() == net::ERR_INSUFFICIENT_RESOURCES &&
|
||||||
|
retry_delay_ < kMaxBackoffDelay) {
|
||||||
|
const base::TimeDelta delay =
|
||||||
|
GetNextExponentialBackoffDelay(retry_delay_);
|
||||||
|
LOG(WARNING) << "InspectableWebContentsImpl::NetworkResourceLoader id = "
|
||||||
|
<< stream_id_
|
||||||
|
<< " failed with insufficient resources, retrying in "
|
||||||
|
<< delay << "." << std::endl;
|
||||||
|
NetworkResourceLoader::Create(
|
||||||
|
stream_id_, bindings_, resource_request_, traffic_annotation_,
|
||||||
|
std::move(url_loader_factory_), callback_, delay);
|
||||||
|
} else {
|
||||||
base::DictionaryValue response;
|
base::DictionaryValue response;
|
||||||
response.SetInteger("statusCode", response_headers_
|
response.SetInteger("statusCode", response_headers_
|
||||||
? response_headers_->response_code()
|
? response_headers_->response_code()
|
||||||
|
@ -214,6 +286,7 @@ class InspectableWebContentsImpl::NetworkResourceLoader
|
||||||
|
|
||||||
response.Set("headers", std::move(headers));
|
response.Set("headers", std::move(headers));
|
||||||
callback_.Run(&response);
|
callback_.Run(&response);
|
||||||
|
}
|
||||||
|
|
||||||
bindings_->loaders_.erase(bindings_->loaders_.find(this));
|
bindings_->loaders_.erase(bindings_->loaders_.find(this));
|
||||||
}
|
}
|
||||||
|
@ -222,9 +295,14 @@ class InspectableWebContentsImpl::NetworkResourceLoader
|
||||||
|
|
||||||
const int stream_id_;
|
const int stream_id_;
|
||||||
InspectableWebContentsImpl* const bindings_;
|
InspectableWebContentsImpl* const bindings_;
|
||||||
|
const network::ResourceRequest resource_request_;
|
||||||
|
const net::NetworkTrafficAnnotationTag traffic_annotation_;
|
||||||
std::unique_ptr<network::SimpleURLLoader> loader_;
|
std::unique_ptr<network::SimpleURLLoader> loader_;
|
||||||
|
URLLoaderFactoryHolder url_loader_factory_;
|
||||||
DispatchCallback callback_;
|
DispatchCallback callback_;
|
||||||
scoped_refptr<net::HttpResponseHeaders> response_headers_;
|
scoped_refptr<net::HttpResponseHeaders> response_headers_;
|
||||||
|
base::OneShotTimer timer_;
|
||||||
|
base::TimeDelta retry_delay_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implemented separately on each platform.
|
// Implemented separately on each platform.
|
||||||
|
@ -528,19 +606,45 @@ void InspectableWebContentsImpl::LoadNetworkResource(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resource_request = std::make_unique<network::ResourceRequest>();
|
// Create traffic annotation tag.
|
||||||
resource_request->url = gurl;
|
net::NetworkTrafficAnnotationTag traffic_annotation =
|
||||||
resource_request->headers.AddHeadersFromString(headers);
|
net::DefineNetworkTrafficAnnotation("devtools_network_resource", R"(
|
||||||
|
semantics {
|
||||||
|
sender: "Developer Tools"
|
||||||
|
description:
|
||||||
|
"When user opens Developer Tools, the browser may fetch additional "
|
||||||
|
"resources from the network to enrich the debugging experience "
|
||||||
|
"(e.g. source map resources)."
|
||||||
|
trigger: "User opens Developer Tools to debug a web page."
|
||||||
|
data: "Any resources requested by Developer Tools."
|
||||||
|
destination: WEBSITE
|
||||||
|
}
|
||||||
|
policy {
|
||||||
|
cookies_allowed: YES
|
||||||
|
cookies_store: "user"
|
||||||
|
setting:
|
||||||
|
"It's not possible to disable this feature from settings."
|
||||||
|
})");
|
||||||
|
|
||||||
|
network::ResourceRequest resource_request;
|
||||||
|
resource_request.url = gurl;
|
||||||
|
resource_request.site_for_cookies = gurl;
|
||||||
|
resource_request.headers.AddHeadersFromString(headers);
|
||||||
|
|
||||||
|
NetworkResourceLoader::URLLoaderFactoryHolder url_loader_factory;
|
||||||
|
if (gurl.SchemeIsFile()) {
|
||||||
|
url_loader_factory = content::CreateFileURLLoaderFactory(
|
||||||
|
base::FilePath() /* profile_path */,
|
||||||
|
nullptr /* shared_cors_origin_access_list */);
|
||||||
|
} else {
|
||||||
auto* partition = content::BrowserContext::GetDefaultStoragePartition(
|
auto* partition = content::BrowserContext::GetDefaultStoragePartition(
|
||||||
GetDevToolsWebContents()->GetBrowserContext());
|
GetDevToolsWebContents()->GetBrowserContext());
|
||||||
auto factory = partition->GetURLLoaderFactoryForBrowserProcess();
|
url_loader_factory = partition->GetURLLoaderFactoryForBrowserProcess();
|
||||||
|
}
|
||||||
|
|
||||||
auto simple_url_loader = network::SimpleURLLoader::Create(
|
NetworkResourceLoader::Create(stream_id, this, resource_request,
|
||||||
std::move(resource_request), MISSING_TRAFFIC_ANNOTATION);
|
traffic_annotation,
|
||||||
auto resource_loader = std::make_unique<NetworkResourceLoader>(
|
std::move(url_loader_factory), callback);
|
||||||
stream_id, this, std::move(simple_url_loader), factory.get(), callback);
|
|
||||||
loaders_.insert(std::move(resource_loader));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectableWebContentsImpl::SetIsDocked(const DispatchCallback& callback,
|
void InspectableWebContentsImpl::SetIsDocked(const DispatchCallback& callback,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue