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_thread.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/navigation_handle.h"
|
||||
#include "content/public/browser/render_frame_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/common/user_agent.h"
|
||||
#include "ipc/ipc_channel.h"
|
||||
|
@ -62,7 +64,7 @@ const char kChromeUIDevToolsURL[] =
|
|||
"textColor=rgba(0,0,0,1)&"
|
||||
"experiments=true";
|
||||
const char kChromeUIDevToolsRemoteFrontendBase[] =
|
||||
"https://devtools-frontend.appspot.com/";
|
||||
"https://chrome-devtools-frontend.appspot.com/";
|
||||
const char kChromeUIDevToolsRemoteFrontendPath[] = "serve_file";
|
||||
|
||||
const char kDevToolsBoundsPref[] = "electron.devtools.bounds";
|
||||
|
@ -150,29 +152,87 @@ GURL GetDevToolsURL(bool can_dock) {
|
|||
return GURL(url_string);
|
||||
}
|
||||
|
||||
constexpr base::TimeDelta kInitialBackoffDelay =
|
||||
base::TimeDelta::FromMilliseconds(250);
|
||||
constexpr base::TimeDelta kMaxBackoffDelay = base::TimeDelta::FromSeconds(10);
|
||||
|
||||
} // namespace
|
||||
|
||||
class InspectableWebContentsImpl::NetworkResourceLoader
|
||||
: public network::SimpleURLLoaderStreamConsumer {
|
||||
public:
|
||||
NetworkResourceLoader(int stream_id,
|
||||
InspectableWebContentsImpl* bindings,
|
||||
std::unique_ptr<network::SimpleURLLoader> loader,
|
||||
network::mojom::URLLoaderFactory* url_loader_factory,
|
||||
const DispatchCallback& callback)
|
||||
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,
|
||||
const network::ResourceRequest& resource_request,
|
||||
const net::NetworkTrafficAnnotationTag& traffic_annotation,
|
||||
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),
|
||||
bindings_(bindings),
|
||||
loader_(std::move(loader)),
|
||||
callback_(callback) {
|
||||
resource_request_(resource_request),
|
||||
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(
|
||||
&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& operator=(const NetworkResourceLoader&) = delete;
|
||||
|
||||
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,
|
||||
const network::mojom::URLResponseHead& response_head) {
|
||||
response_headers_ = response_head.headers;
|
||||
|
@ -199,21 +259,34 @@ class InspectableWebContentsImpl::NetworkResourceLoader
|
|||
}
|
||||
|
||||
void OnComplete(bool success) override {
|
||||
base::DictionaryValue response;
|
||||
response.SetInteger("statusCode", response_headers_
|
||||
? response_headers_->response_code()
|
||||
: 200);
|
||||
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;
|
||||
response.SetInteger("statusCode", response_headers_
|
||||
? response_headers_->response_code()
|
||||
: 200);
|
||||
|
||||
auto headers = std::make_unique<base::DictionaryValue>();
|
||||
size_t iterator = 0;
|
||||
std::string name;
|
||||
std::string value;
|
||||
while (response_headers_ &&
|
||||
response_headers_->EnumerateHeaderLines(&iterator, &name, &value))
|
||||
headers->SetString(name, value);
|
||||
auto headers = std::make_unique<base::DictionaryValue>();
|
||||
size_t iterator = 0;
|
||||
std::string name;
|
||||
std::string value;
|
||||
while (response_headers_ &&
|
||||
response_headers_->EnumerateHeaderLines(&iterator, &name, &value))
|
||||
headers->SetString(name, value);
|
||||
|
||||
response.Set("headers", std::move(headers));
|
||||
callback_.Run(&response);
|
||||
response.Set("headers", std::move(headers));
|
||||
callback_.Run(&response);
|
||||
}
|
||||
|
||||
bindings_->loaders_.erase(bindings_->loaders_.find(this));
|
||||
}
|
||||
|
@ -222,9 +295,14 @@ class InspectableWebContentsImpl::NetworkResourceLoader
|
|||
|
||||
const int stream_id_;
|
||||
InspectableWebContentsImpl* const bindings_;
|
||||
const network::ResourceRequest resource_request_;
|
||||
const net::NetworkTrafficAnnotationTag traffic_annotation_;
|
||||
std::unique_ptr<network::SimpleURLLoader> loader_;
|
||||
URLLoaderFactoryHolder url_loader_factory_;
|
||||
DispatchCallback callback_;
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers_;
|
||||
base::OneShotTimer timer_;
|
||||
base::TimeDelta retry_delay_;
|
||||
};
|
||||
|
||||
// Implemented separately on each platform.
|
||||
|
@ -528,19 +606,45 @@ void InspectableWebContentsImpl::LoadNetworkResource(
|
|||
return;
|
||||
}
|
||||
|
||||
auto resource_request = std::make_unique<network::ResourceRequest>();
|
||||
resource_request->url = gurl;
|
||||
resource_request->headers.AddHeadersFromString(headers);
|
||||
// Create traffic annotation tag.
|
||||
net::NetworkTrafficAnnotationTag traffic_annotation =
|
||||
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."
|
||||
})");
|
||||
|
||||
auto* partition = content::BrowserContext::GetDefaultStoragePartition(
|
||||
GetDevToolsWebContents()->GetBrowserContext());
|
||||
auto factory = partition->GetURLLoaderFactoryForBrowserProcess();
|
||||
network::ResourceRequest resource_request;
|
||||
resource_request.url = gurl;
|
||||
resource_request.site_for_cookies = gurl;
|
||||
resource_request.headers.AddHeadersFromString(headers);
|
||||
|
||||
auto simple_url_loader = network::SimpleURLLoader::Create(
|
||||
std::move(resource_request), MISSING_TRAFFIC_ANNOTATION);
|
||||
auto resource_loader = std::make_unique<NetworkResourceLoader>(
|
||||
stream_id, this, std::move(simple_url_loader), factory.get(), callback);
|
||||
loaders_.insert(std::move(resource_loader));
|
||||
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(
|
||||
GetDevToolsWebContents()->GetBrowserContext());
|
||||
url_loader_factory = partition->GetURLLoaderFactoryForBrowserProcess();
|
||||
}
|
||||
|
||||
NetworkResourceLoader::Create(stream_id, this, resource_request,
|
||||
traffic_annotation,
|
||||
std::move(url_loader_factory), callback);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::SetIsDocked(const DispatchCallback& callback,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue