Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(721)

Unified Diff: content/browser/webui/url_data_manager_backend.cc

Issue 2860903006: Handle webuis when using the network service. (Closed)
Patch Set: merge Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/webui/url_data_manager_backend.cc
diff --git a/content/browser/webui/url_data_manager_backend.cc b/content/browser/webui/url_data_manager_backend.cc
index ff6ccb12de770736b0fd74837e3a3561450040f9..861261846dd40bea82ad27dd6746a429dbb738f8 100644
--- a/content/browser/webui/url_data_manager_backend.cc
+++ b/content/browser/webui/url_data_manager_backend.cc
@@ -45,7 +45,6 @@
#include "net/base/net_errors.h"
#include "net/filter/gzip_source_stream.h"
#include "net/filter/source_stream.h"
-#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/log/net_log_util.h"
#include "net/url_request/url_request.h"
@@ -71,34 +70,6 @@ bool SchemeIsInSchemes(const std::string& scheme,
return std::find(schemes.begin(), schemes.end(), scheme) != schemes.end();
}
-// Returns whether |url| passes some sanity checks and is a valid GURL.
-bool CheckURLIsValid(const GURL& url) {
- std::vector<std::string> additional_schemes;
- DCHECK(url.SchemeIs(kChromeDevToolsScheme) || url.SchemeIs(kChromeUIScheme) ||
- (GetContentClient()->browser()->GetAdditionalWebUISchemes(
- &additional_schemes),
- SchemeIsInSchemes(url.scheme(), additional_schemes)));
-
- if (!url.is_valid()) {
- NOTREACHED();
- return false;
- }
-
- return true;
-}
-
-// Parse |url| to get the path which will be used to resolve the request. The
-// path is the remaining portion after the scheme and hostname.
-void URLToRequestPath(const GURL& url, std::string* path) {
- const std::string& spec = url.possibly_invalid_spec();
- const url::Parsed& parsed = url.parsed_for_possibly_invalid_spec();
- // + 1 to skip the slash at the beginning of the path.
- int offset = parsed.CountCharactersBefore(url::Parsed::PATH, false) + 1;
-
- if (offset < static_cast<int>(spec.size()))
- path->assign(spec.substr(offset));
-}
-
// Returns a value of 'Origin:' header for the |request| if the header is set.
// Otherwise returns an empty string.
std::string GetOriginHeaderValue(const net::URLRequest* request) {
@@ -134,11 +105,9 @@ void CopyData(const scoped_refptr<net::IOBuffer>& buf,
// calls back once the data is available.
class URLRequestChromeJob : public net::URLRequestJob {
public:
- // |is_incognito| set when job is generated from an incognito profile.
URLRequestChromeJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
- URLDataManagerBackend* backend,
- bool is_incognito);
+ URLDataManagerBackend* backend);
// net::URLRequestJob implementation.
void Start() override;
@@ -155,58 +124,6 @@ class URLRequestChromeJob : public net::URLRequestJob {
// for us. |bytes| may be null, indicating an error.
void DataAvailable(base::RefCountedMemory* bytes);
- // Returns a weak pointer to the job.
- base::WeakPtr<URLRequestChromeJob> AsWeakPtr();
-
- void set_mime_type(const std::string& mime_type) {
- mime_type_ = mime_type;
- }
-
- void set_allow_caching(bool allow_caching) {
- allow_caching_ = allow_caching;
- }
-
- void set_add_content_security_policy(bool add_content_security_policy) {
- add_content_security_policy_ = add_content_security_policy;
- }
-
- void set_content_security_policy_object_source(
- const std::string& data) {
- content_security_policy_object_source_ = data;
- }
-
- void set_content_security_policy_script_source(
- const std::string& data) {
- content_security_policy_script_source_ = data;
- }
-
- void set_content_security_policy_child_source(
- const std::string& data) {
- content_security_policy_child_source_ = data;
- }
-
- void set_content_security_policy_style_source(
- const std::string& data) {
- content_security_policy_style_source_ = data;
- }
-
- void set_content_security_policy_image_source(
- const std::string& data) {
- content_security_policy_image_source_ = data;
- }
-
- void set_deny_xframe_options(bool deny_xframe_options) {
- deny_xframe_options_ = deny_xframe_options;
- }
-
- void set_send_content_type_header(bool send_content_type_header) {
- send_content_type_header_ = send_content_type_header;
- }
-
- void set_access_control_allow_origin(const std::string& value) {
- access_control_allow_origin_ = value;
- }
-
void set_is_gzipped(bool is_gzipped) {
is_gzipped_ = is_gzipped;
}
@@ -215,11 +132,6 @@ class URLRequestChromeJob : public net::URLRequestJob {
replacements_ = replacements;
}
- // Returns true when job was generated from an incognito profile.
- bool is_incognito() const {
- return is_incognito_;
- }
-
private:
~URLRequestChromeJob() override;
@@ -255,32 +167,6 @@ class URLRequestChromeJob : public net::URLRequestJob {
int pending_buf_size_;
std::string mime_type_;
- // If true, set a header in the response to prevent it from being cached.
- bool allow_caching_;
-
- // If true, set the Content Security Policy (CSP) header.
- bool add_content_security_policy_;
-
- // These are used with the CSP.
- std::string content_security_policy_script_source_;
- std::string content_security_policy_object_source_;
- std::string content_security_policy_child_source_;
- std::string content_security_policy_style_source_;
- std::string content_security_policy_image_source_;
-
- // If true, sets the "X-Frame-Options: DENY" header.
- bool deny_xframe_options_;
-
- // If true, sets the "Content-Type: <mime-type>" header.
- bool send_content_type_header_;
-
- // If not empty, "Access-Control-Allow-Origin:" is set to the value of this
- // string.
- std::string access_control_allow_origin_;
-
- // True when job is generated from an incognito profile.
- const bool is_incognito_;
-
// True when gzip encoding should be used. NOTE: this requires the original
// resources in resources.pak use compress="gzip".
bool is_gzipped_;
@@ -298,17 +184,11 @@ class URLRequestChromeJob : public net::URLRequestJob {
URLRequestChromeJob::URLRequestChromeJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
- URLDataManagerBackend* backend,
- bool is_incognito)
+ URLDataManagerBackend* backend)
: net::URLRequestJob(request, network_delegate),
data_offset_(0),
data_available_status_(net::OK),
pending_buf_size_(0),
- allow_caching_(true),
- add_content_security_policy_(true),
- deny_xframe_options_(true),
- send_content_type_header_(false),
- is_incognito_(is_incognito),
is_gzipped_(false),
replacements_(nullptr),
backend_(backend),
@@ -359,43 +239,11 @@ bool URLRequestChromeJob::GetMimeType(std::string* mime_type) const {
void URLRequestChromeJob::GetResponseInfo(net::HttpResponseInfo* info) {
DCHECK(!info->headers.get());
- // Set the headers so that requests serviced by ChromeURLDataManager return a
- // status code of 200. Without this they return a 0, which makes the status
- // indistiguishable from other error types. Instant relies on getting a 200.
- info->headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
-
- // Determine the least-privileged content security policy header, if any,
- // that is compatible with a given WebUI URL, and append it to the existing
- // response headers.
- if (add_content_security_policy_) {
- std::string base = kChromeURLContentSecurityPolicyHeaderBase;
- base.append(content_security_policy_script_source_);
- base.append(content_security_policy_object_source_);
- base.append(content_security_policy_child_source_);
- base.append(content_security_policy_style_source_);
- base.append(content_security_policy_image_source_);
- info->headers->AddHeader(base);
- }
-
- if (deny_xframe_options_)
- info->headers->AddHeader(kChromeURLXFrameOptionsHeader);
-
- if (!allow_caching_)
- info->headers->AddHeader("Cache-Control: no-cache");
-
- if (send_content_type_header_ && !mime_type_.empty()) {
- std::string content_type =
- base::StringPrintf("%s:%s", net::HttpRequestHeaders::kContentType,
- mime_type_.c_str());
- info->headers->AddHeader(content_type);
- }
-
- if (!access_control_allow_origin_.empty()) {
- info->headers->AddHeader("Access-Control-Allow-Origin: " +
- access_control_allow_origin_);
- info->headers->AddHeader("Vary: Origin");
- }
-
+ URLDataSourceImpl* source = backend_->GetDataSourceFromURL(request()->url());
+ std::string path;
+ URLDataManagerBackend::URLToRequestPath(request()->url(), &path);
+ info->headers = URLDataManagerBackend::GetHeaders(
+ source, path, GetOriginHeaderValue(request()));
if (is_gzipped_)
info->headers->AddHeader("Content-Encoding: gzip");
}
@@ -410,7 +258,7 @@ std::unique_ptr<net::SourceStream> URLRequestChromeJob::SetUpSourceStream() {
}
if (replacements_) {
- source_stream = content::I18nSourceStream::Create(
+ source_stream = I18nSourceStream::Create(
std::move(source_stream), net::SourceStream::TYPE_NONE, replacements_);
}
@@ -418,7 +266,7 @@ std::unique_ptr<net::SourceStream> URLRequestChromeJob::SetUpSourceStream() {
}
void URLRequestChromeJob::MimeTypeAvailable(const std::string& mime_type) {
- set_mime_type(mime_type);
+ mime_type_ = mime_type;
NotifyHeadersComplete();
}
@@ -441,10 +289,6 @@ void URLRequestChromeJob::DataAvailable(base::RefCountedMemory* bytes) {
}
}
-base::WeakPtr<URLRequestChromeJob> URLRequestChromeJob::AsWeakPtr() {
- return weak_factory_.GetWeakPtr();
-}
-
int URLRequestChromeJob::ReadRawData(net::IOBuffer* buf, int buf_size) {
DCHECK(!pending_buf_.get());
@@ -477,8 +321,8 @@ int URLRequestChromeJob::PostReadTask(scoped_refptr<net::IOBuffer> buf,
FROM_HERE, {base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::Bind(&CopyData, base::RetainedRef(buf), buf_size, data_,
data_offset_),
- base::Bind(&URLRequestChromeJob::ReadRawDataComplete, AsWeakPtr(),
- buf_size));
+ base::Bind(&URLRequestChromeJob::ReadRawDataComplete,
+ weak_factory_.GetWeakPtr(), buf_size));
data_offset_ += buf_size;
return net::ERR_IO_PENDING;
@@ -531,12 +375,9 @@ bool IsValidNetworkErrorCode(int error_code) {
class ChromeProtocolHandler
: public net::URLRequestJobFactory::ProtocolHandler {
public:
- // |is_incognito| should be set for incognito profiles.
ChromeProtocolHandler(ResourceContext* resource_context,
- bool is_incognito,
ChromeBlobStorageContext* blob_storage_context)
: resource_context_(resource_context),
- is_incognito_(is_incognito),
blob_storage_context_(blob_storage_context) {}
~ChromeProtocolHandler() override {}
@@ -590,7 +431,7 @@ class ChromeProtocolHandler
// Fall back to using a custom handler
return new URLRequestChromeJob(
request, network_delegate,
- GetURLDataManagerForResourceContext(resource_context_), is_incognito_);
+ GetURLDataManagerForResourceContext(resource_context_));
}
bool IsSafeRedirectTarget(const GURL& location) const override {
@@ -601,8 +442,6 @@ class ChromeProtocolHandler
// These members are owned by ProfileIOData, which owns this ProtocolHandler.
ResourceContext* const resource_context_;
- // True when generated from an incognito profile.
- const bool is_incognito_;
ChromeBlobStorageContext* blob_storage_context_;
DISALLOW_COPY_AND_ASSIGN(ChromeProtocolHandler);
@@ -628,10 +467,9 @@ URLDataManagerBackend::~URLDataManagerBackend() {
std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>
URLDataManagerBackend::CreateProtocolHandler(
ResourceContext* resource_context,
- bool is_incognito,
ChromeBlobStorageContext* blob_storage_context) {
DCHECK(resource_context);
- return base::MakeUnique<ChromeProtocolHandler>(resource_context, is_incognito,
+ return base::MakeUnique<ChromeProtocolHandler>(resource_context,
blob_storage_context);
}
@@ -672,6 +510,7 @@ bool URLDataManagerBackend::HasPendingJob(
bool URLDataManagerBackend::StartRequest(const net::URLRequest* request,
URLRequestChromeJob* job) {
+ // NOTE: this duplicates code in web_ui_url_loader_factory.cc's URLLoaderImpl.
if (!CheckURLIsValid(request->url()))
return false;
@@ -679,8 +518,7 @@ bool URLDataManagerBackend::StartRequest(const net::URLRequest* request,
if (!source)
return false;
- const content::ResourceRequestInfo* info =
- content::ResourceRequestInfo::ForRequest(request);
+ const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
if (!source->source()->ShouldServiceRequest(
request->url(), info ? info->GetContext() : nullptr,
info ? info->GetChildID() : -1)) {
@@ -694,23 +532,6 @@ bool URLDataManagerBackend::StartRequest(const net::URLRequest* request,
RequestID request_id = next_request_id_++;
pending_requests_.insert(std::make_pair(request_id, job));
- job->set_allow_caching(source->source()->AllowCaching());
- job->set_add_content_security_policy(
- source->source()->ShouldAddContentSecurityPolicy());
- job->set_content_security_policy_script_source(
- source->source()->GetContentSecurityPolicyScriptSrc());
- job->set_content_security_policy_object_source(
- source->source()->GetContentSecurityPolicyObjectSrc());
- job->set_content_security_policy_child_source(
- source->source()->GetContentSecurityPolicyChildSrc());
- job->set_content_security_policy_style_source(
- source->source()->GetContentSecurityPolicyStyleSrc());
- job->set_content_security_policy_image_source(
- source->source()->GetContentSecurityPolicyImgSrc());
- job->set_deny_xframe_options(
- source->source()->ShouldDenyXFrameOptions());
- job->set_send_content_type_header(
- source->source()->ShouldServeMimeTypeAsContentTypeHeader());
job->set_is_gzipped(source->source()->IsGzipped(path));
// TODO(dschuyler): improve filtering of which resource to run template
@@ -719,15 +540,6 @@ bool URLDataManagerBackend::StartRequest(const net::URLRequest* request,
if (mime_type == "text/html")
job->SetReplacements(source->GetReplacements());
- std::string origin = GetOriginHeaderValue(request);
- if (!origin.empty()) {
- std::string header =
- source->source()->GetAccessControlAllowOriginForOrigin(origin);
- DCHECK(header.empty() || header == origin || header == "*" ||
- header == "null");
- job->set_access_control_allow_origin(header);
- }
-
// Also notifies that the headers are complete.
job->MimeTypeAvailable(mime_type);
@@ -810,13 +622,90 @@ void URLDataManagerBackend::DataAvailable(RequestID request_id,
}
}
+scoped_refptr<net::HttpResponseHeaders> URLDataManagerBackend::GetHeaders(
+ URLDataSourceImpl* source_impl,
+ const std::string& path,
+ const std::string& origin) {
+ // Set the headers so that requests serviced by ChromeURLDataManager return a
+ // status code of 200. Without this they return a 0, which makes the status
+ // indistiguishable from other error types. Instant relies on getting a 200.
+ scoped_refptr<net::HttpResponseHeaders> headers(
+ new net::HttpResponseHeaders("HTTP/1.1 200 OK"));
+ if (!source_impl)
+ return headers;
+
+ URLDataSource* source = source_impl->source();
+ // Determine the least-privileged content security policy header, if any,
+ // that is compatible with a given WebUI URL, and append it to the existing
+ // response headers.
+ if (source->ShouldAddContentSecurityPolicy()) {
+ std::string base = kChromeURLContentSecurityPolicyHeaderBase;
+ base.append(source->GetContentSecurityPolicyScriptSrc());
+ base.append(source->GetContentSecurityPolicyObjectSrc());
+ base.append(source->GetContentSecurityPolicyChildSrc());
+ base.append(source->GetContentSecurityPolicyStyleSrc());
+ base.append(source->GetContentSecurityPolicyImgSrc());
+ headers->AddHeader(base);
+ }
+
+ if (source->ShouldDenyXFrameOptions())
+ headers->AddHeader(kChromeURLXFrameOptionsHeader);
+
+ if (!source->AllowCaching())
+ headers->AddHeader("Cache-Control: no-cache");
+
+ std::string mime_type = source->GetMimeType(path);
+ if (source->ShouldServeMimeTypeAsContentTypeHeader() && !mime_type.empty()) {
+ std::string content_type = base::StringPrintf(
+ "%s:%s", net::HttpRequestHeaders::kContentType, mime_type.c_str());
+ headers->AddHeader(content_type);
+ }
+
+ if (!origin.empty()) {
+ std::string header = source->GetAccessControlAllowOriginForOrigin(origin);
+ DCHECK(header.empty() || header == origin || header == "*" ||
+ header == "null");
+ if (!header.empty()) {
+ headers->AddHeader("Access-Control-Allow-Origin: " + header);
+ headers->AddHeader("Vary: Origin");
+ }
+ }
+
+ return headers;
+}
+
+bool URLDataManagerBackend::CheckURLIsValid(const GURL& url) {
+ std::vector<std::string> additional_schemes;
+ DCHECK(url.SchemeIs(kChromeDevToolsScheme) || url.SchemeIs(kChromeUIScheme) ||
+ (GetContentClient()->browser()->GetAdditionalWebUISchemes(
+ &additional_schemes),
+ SchemeIsInSchemes(url.scheme(), additional_schemes)));
+
+ if (!url.is_valid()) {
+ NOTREACHED();
+ return false;
+ }
+
+ return true;
+}
+
+void URLDataManagerBackend::URLToRequestPath(const GURL& url,
+ std::string* path) {
+ const std::string& spec = url.possibly_invalid_spec();
+ const url::Parsed& parsed = url.parsed_for_possibly_invalid_spec();
+ // + 1 to skip the slash at the beginning of the path.
+ int offset = parsed.CountCharactersBefore(url::Parsed::PATH, false) + 1;
+
+ if (offset < static_cast<int>(spec.size()))
+ path->assign(spec.substr(offset));
+}
+
namespace {
class DevToolsJobFactory
: public net::URLRequestJobFactory::ProtocolHandler {
public:
- // |is_incognito| should be set for incognito profiles.
- DevToolsJobFactory(ResourceContext* resource_context, bool is_incognito);
+ explicit DevToolsJobFactory(ResourceContext* resource_context);
~DevToolsJobFactory() override;
net::URLRequestJob* MaybeCreateJob(
@@ -828,15 +717,11 @@ class DevToolsJobFactory
// which owns this ProtocolHandler.
ResourceContext* const resource_context_;
- // True when generated from an incognito profile.
- const bool is_incognito_;
-
DISALLOW_COPY_AND_ASSIGN(DevToolsJobFactory);
};
-DevToolsJobFactory::DevToolsJobFactory(ResourceContext* resource_context,
- bool is_incognito)
- : resource_context_(resource_context), is_incognito_(is_incognito) {
+DevToolsJobFactory::DevToolsJobFactory(ResourceContext* resource_context)
+ : resource_context_(resource_context) {
DCHECK(resource_context_);
}
@@ -847,15 +732,14 @@ DevToolsJobFactory::MaybeCreateJob(
net::URLRequest* request, net::NetworkDelegate* network_delegate) const {
return new URLRequestChromeJob(
request, network_delegate,
- GetURLDataManagerForResourceContext(resource_context_), is_incognito_);
+ GetURLDataManagerForResourceContext(resource_context_));
}
} // namespace
net::URLRequestJobFactory::ProtocolHandler* CreateDevToolsProtocolHandler(
- ResourceContext* resource_context,
- bool is_incognito) {
- return new DevToolsJobFactory(resource_context, is_incognito);
+ ResourceContext* resource_context) {
+ return new DevToolsJobFactory(resource_context);
}
} // namespace content
« no previous file with comments | « content/browser/webui/url_data_manager_backend.h ('k') | content/browser/webui/url_data_manager_backend_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698