refactor: Enable network service (Part 1) (#17431)

* Convert InspectableWebContentsImpl::LoadNetworkResource to SimpleURLLoader

https://bugs.chromium.org/p/chromium/issues/detail?id=721408

* Plumb creation of network context with the service
This commit is contained in:
Robo 2019-03-26 06:40:48 +05:30 committed by Cheng Zhao
parent 4ec2f8b67b
commit 6c20c6e668
18 changed files with 469 additions and 172 deletions

View file

@ -12,6 +12,7 @@
#include "atom/browser/ui/inspectable_web_contents_view.h"
#include "atom/browser/ui/inspectable_web_contents_view_delegate.h"
#include "atom/common/platform_util.h"
#include "base/base64.h"
#include "base/guid.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
@ -37,10 +38,9 @@
#include "content/public/browser/storage_partition.h"
#include "content/public/common/user_agent.h"
#include "ipc/ipc_channel.h"
#include "net/base/io_buffer.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_response_writer.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
@ -145,64 +145,83 @@ GURL GetDevToolsURL(bool can_dock) {
return GURL(url_string);
}
// ResponseWriter -------------------------------------------------------------
} // namespace
class ResponseWriter : public net::URLFetcherResponseWriter {
class InspectableWebContentsImpl::NetworkResourceLoader
: public network::SimpleURLLoaderStreamConsumer {
public:
ResponseWriter(base::WeakPtr<InspectableWebContentsImpl> bindings,
int stream_id);
~ResponseWriter() override;
NetworkResourceLoader(int stream_id,
InspectableWebContentsImpl* bindings,
std::unique_ptr<network::SimpleURLLoader> loader,
network::mojom::URLLoaderFactory* url_loader_factory,
const DispatchCallback& callback)
: stream_id_(stream_id),
bindings_(bindings),
loader_(std::move(loader)),
callback_(callback) {
loader_->SetOnResponseStartedCallback(base::BindOnce(
&NetworkResourceLoader::OnResponseStarted, base::Unretained(this)));
loader_->DownloadAsStream(url_loader_factory, this);
}
// URLFetcherResponseWriter overrides:
int Initialize(net::CompletionOnceCallback callback) override;
int Write(net::IOBuffer* buffer,
int num_bytes,
net::CompletionOnceCallback callback) override;
int Finish(int net_error, net::CompletionOnceCallback callback) override;
NetworkResourceLoader(const NetworkResourceLoader&) = delete;
NetworkResourceLoader& operator=(const NetworkResourceLoader&) = delete;
private:
base::WeakPtr<InspectableWebContentsImpl> bindings_;
int stream_id_;
void OnResponseStarted(const GURL& final_url,
const network::ResourceResponseHead& response_head) {
response_headers_ = response_head.headers;
}
DISALLOW_COPY_AND_ASSIGN(ResponseWriter);
void OnDataReceived(base::StringPiece chunk,
base::OnceClosure resume) override {
base::Value chunkValue;
bool encoded = !base::IsStringUTF8(chunk);
if (encoded) {
std::string encoded_string;
base::Base64Encode(chunk, &encoded_string);
chunkValue = base::Value(std::move(encoded_string));
} else {
chunkValue = base::Value(chunk);
}
base::Value id(stream_id_);
base::Value encodedValue(encoded);
bindings_->CallClientFunction("DevToolsAPI.streamWrite", &id, &chunkValue,
&encodedValue);
std::move(resume).Run();
}
void OnComplete(bool success) override {
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);
response.Set("headers", std::move(headers));
callback_.Run(&response);
bindings_->loaders_.erase(bindings_->loaders_.find(this));
}
void OnRetry(base::OnceClosure start_retry) override {}
const int stream_id_;
InspectableWebContentsImpl* const bindings_;
std::unique_ptr<network::SimpleURLLoader> loader_;
DispatchCallback callback_;
scoped_refptr<net::HttpResponseHeaders> response_headers_;
};
ResponseWriter::ResponseWriter(
base::WeakPtr<InspectableWebContentsImpl> bindings,
int stream_id)
: bindings_(bindings), stream_id_(stream_id) {}
ResponseWriter::~ResponseWriter() {}
int ResponseWriter::Initialize(net::CompletionOnceCallback callback) {
return net::OK;
}
int ResponseWriter::Write(net::IOBuffer* buffer,
int num_bytes,
net::CompletionOnceCallback callback) {
std::string chunk = std::string(buffer->data(), num_bytes);
if (!base::IsStringUTF8(chunk))
return num_bytes;
base::Value* id = new base::Value(stream_id_);
base::Value* chunk_value = new base::Value(chunk);
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&InspectableWebContentsImpl::CallClientFunction, bindings_,
"DevToolsAPI.streamWrite", base::Owned(id),
base::Owned(chunk_value), nullptr));
return num_bytes;
}
int ResponseWriter::Finish(int net_error,
net::CompletionOnceCallback callback) {
return net::OK;
}
} // namespace
// Implemented separately on each platform.
InspectableWebContentsView* CreateInspectableContentsView(
InspectableWebContentsImpl* inspectable_web_contents_impl);
@ -495,19 +514,19 @@ void InspectableWebContentsImpl::LoadNetworkResource(
return;
}
auto* browser_context = GetDevToolsWebContents()->GetBrowserContext();
auto resource_request = std::make_unique<network::ResourceRequest>();
resource_request->url = gurl;
resource_request->headers.AddHeadersFromString(headers);
net::URLFetcher* fetcher =
(net::URLFetcher::Create(gurl, net::URLFetcher::GET, this)).release();
pending_requests_[fetcher] = callback;
fetcher->SetRequestContext(
content::BrowserContext::GetDefaultStoragePartition(browser_context)
->GetURLRequestContext());
fetcher->SetExtraRequestHeaders(headers);
fetcher->SaveResponseWithWriter(
std::unique_ptr<net::URLFetcherResponseWriter>(
new ResponseWriter(weak_factory_.GetWeakPtr(), stream_id)));
fetcher->Start();
auto* partition = content::BrowserContext::GetDefaultStoragePartition(
GetDevToolsWebContents()->GetBrowserContext());
auto factory = partition->GetURLLoaderFactoryForBrowserProcess();
auto simple_url_loader = network::SimpleURLLoader::Create(
std::move(resource_request), NO_TRAFFIC_ANNOTATION_YET);
auto resource_loader = std::make_unique<NetworkResourceLoader>(
stream_id, this, std::move(simple_url_loader), factory.get(), callback);
loaders_.insert(std::move(resource_loader));
}
void InspectableWebContentsImpl::SetIsDocked(const DispatchCallback& callback,
@ -752,9 +771,6 @@ void InspectableWebContentsImpl::WebContentsDestroyed() {
Detach();
embedder_message_dispatcher_.reset();
for (const auto& pair : pending_requests_)
delete pair.first;
if (view_ && view_->GetDelegate())
view_->GetDelegate()->DevToolsClosed();
}
@ -874,34 +890,6 @@ void InspectableWebContentsImpl::DidFinishNavigation(
frame->ExecuteJavaScriptForTests(base::UTF8ToUTF16(script));
}
void InspectableWebContentsImpl::OnURLFetchComplete(
const net::URLFetcher* source) {
DCHECK(source);
auto it = pending_requests_.find(source);
DCHECK(it != pending_requests_.end());
base::DictionaryValue response;
net::HttpResponseHeaders* rh = source->GetResponseHeaders();
response.SetInteger("statusCode", rh ? rh->response_code() : 200);
{
auto headers = std::make_unique<base::DictionaryValue>();
size_t iterator = 0;
std::string name;
std::string value;
while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value))
headers->SetString(name, value);
response.Set("headers", std::move(headers));
}
it->second.Run(&response);
pending_requests_.erase(it);
delete source;
}
void InspectableWebContentsImpl::SendMessageAck(int request_id,
const base::Value* arg) {
base::Value id_value(request_id);

View file

@ -8,10 +8,12 @@
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "atom/browser/ui/inspectable_web_contents.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/devtools/devtools_contents_resizing_strategy.h"
#include "chrome/browser/devtools/devtools_embedder_message_dispatcher.h"
@ -19,7 +21,6 @@
#include "content/public/browser/devtools_frontend_host.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "ui/gfx/geometry/rect.h"
class PrefService;
@ -35,8 +36,7 @@ class InspectableWebContentsImpl
public content::DevToolsAgentHostClient,
public content::WebContentsObserver,
public content::WebContentsDelegate,
public DevToolsEmbedderMessageDispatcher::Delegate,
public net::URLFetcherDelegate {
public DevToolsEmbedderMessageDispatcher::Delegate {
public:
static void RegisterPrefs(PrefRegistrySimple* pref_registry);
@ -197,9 +197,6 @@ class InspectableWebContentsImpl
std::unique_ptr<content::FileSelectListener> listener,
const base::FilePath& path) override;
// net::URLFetcherDelegate:
void OnURLFetchComplete(const net::URLFetcher* source) override;
void SendMessageAck(int request_id, const base::Value* arg1);
bool frontend_loaded_;
@ -214,8 +211,6 @@ class InspectableWebContentsImpl
std::string dock_state_;
bool activate_ = true;
using PendingRequestsMap = std::map<const net::URLFetcher*, DispatchCallback>;
PendingRequestsMap pending_requests_;
InspectableWebContentsDelegate* delegate_; // weak references.
PrefService* pref_service_; // weak reference.
@ -231,6 +226,10 @@ class InspectableWebContentsImpl
bool is_guest_;
std::unique_ptr<InspectableWebContentsView> view_;
class NetworkResourceLoader;
std::set<std::unique_ptr<NetworkResourceLoader>, base::UniquePtrComparator>
loaders_;
using ExtensionsAPIs = std::map<std::string, std::string>;
ExtensionsAPIs extensions_api_;