Commit 6ee72da1 authored by horo@chromium.org's avatar horo@chromium.org

[ServiceWorker] Propagates ServiceWorker fetched response's URL and...

[ServiceWorker] Propagates ServiceWorker fetched response's URL and wasFetchedViaServiceWorker flag.

If the request was fetched via a ServiceWorker, the URL of the response could be different from the URL of the original request. 
The URL must be checked in the renderer process for CSP and CORS.

So in this patch I introduce was_fetched_via_service_worker flag and original_url_via_service_worker which are set in ServiceWorkerURLRequestJob and propagated to the renderer process.


This change depends on http://crrev.com/370733002 and http://crrev.com/378473002.

BUG=373120

Review URL: https://codereview.chromium.org/375513002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284627 0039d316-1c4b-4281-b951-d872f2087c98
parent a5e6b747
......@@ -14,6 +14,7 @@
#include "content/browser/loader/detachable_resource_handler.h"
#include "content/browser/loader/resource_loader_delegate.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/service_worker/service_worker_request_handler.h"
#include "content/browser/ssl/ssl_client_auth_handler.h"
#include "content/browser/ssl/ssl_manager.h"
#include "content/common/ssl_status_serialization.h"
......@@ -54,6 +55,12 @@ void PopulateResourceResponse(net::URLRequest* request,
response->head.connection_info = response_info.connection_info;
response->head.was_fetched_via_proxy = request->was_fetched_via_proxy();
response->head.socket_address = request->GetSocketAddress();
if (ServiceWorkerRequestHandler* handler =
ServiceWorkerRequestHandler::GetHandler(request)) {
handler->GetExtraResponseInfo(
&response->head.was_fetched_via_service_worker,
&response->head.original_url_via_service_worker);
}
AppCacheInterceptor::GetExtraResponseInfo(
request,
&response->head.appcache_id,
......
......@@ -146,7 +146,9 @@ void EmbeddedWorkerTestHelper::OnFetchEvent(
embedded_worker_id,
request_id,
SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE,
ServiceWorkerResponse(200, "OK",
ServiceWorkerResponse(GURL(""),
200,
"OK",
std::map<std::string, std::string>(),
std::string())));
}
......
......@@ -72,6 +72,13 @@ net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJob(
return NULL;
}
void ServiceWorkerContextRequestHandler::GetExtraResponseInfo(
bool* was_fetched_via_service_worker,
GURL* original_url_via_service_worker) const {
*was_fetched_via_service_worker = false;
*original_url_via_service_worker = GURL();
}
bool ServiceWorkerContextRequestHandler::ShouldAddToScriptCache(
const GURL& url) {
// We only write imports that occur during the initial eval.
......
......@@ -28,6 +28,10 @@ class CONTENT_EXPORT ServiceWorkerContextRequestHandler
net::URLRequest* request,
net::NetworkDelegate* network_delegate) OVERRIDE;
virtual void GetExtraResponseInfo(
bool* was_fetched_via_service_worker,
GURL* original_url_via_service_worker) const OVERRIDE;
private:
bool ShouldAddToScriptCache(const GURL& url);
bool ShouldReadFromScriptCache(const GURL& url, int64* response_id_out);
......
......@@ -96,6 +96,18 @@ net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob(
return job_.get();
}
void ServiceWorkerControlleeRequestHandler::GetExtraResponseInfo(
bool* was_fetched_via_service_worker,
GURL* original_url_via_service_worker) const {
if (!job_) {
*was_fetched_via_service_worker = false;
*original_url_via_service_worker = GURL();
return;
}
job_->GetExtraResponseInfo(was_fetched_via_service_worker,
original_url_via_service_worker);
}
void ServiceWorkerControlleeRequestHandler::PrepareForMainResource(
const GURL& url) {
DCHECK(job_.get());
......
......@@ -34,6 +34,10 @@ class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
net::URLRequest* request,
net::NetworkDelegate* network_delegate) OVERRIDE;
virtual void GetExtraResponseInfo(
bool* was_fetched_via_service_worker,
GURL* original_url_via_service_worker) const OVERRIDE;
private:
typedef ServiceWorkerControlleeRequestHandler self;
......
......@@ -63,6 +63,10 @@ class CONTENT_EXPORT ServiceWorkerRequestHandler
net::URLRequest* request,
net::NetworkDelegate* network_delegate) = 0;
virtual void GetExtraResponseInfo(
bool* was_fetched_via_service_worker,
GURL* original_url_via_service_worker) const = 0;
protected:
ServiceWorkerRequestHandler(
base::WeakPtr<ServiceWorkerContextCore> context,
......
......@@ -173,6 +173,19 @@ const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const {
return http_response_info_.get();
}
void ServiceWorkerURLRequestJob::GetExtraResponseInfo(
bool* was_fetched_via_service_worker,
GURL* original_url_via_service_worker) const {
if (response_type_ != FORWARD_TO_SERVICE_WORKER) {
*was_fetched_via_service_worker = false;
*original_url_via_service_worker = GURL();
return;
}
*was_fetched_via_service_worker = true;
*original_url_via_service_worker = response_url_;
}
ServiceWorkerURLRequestJob::~ServiceWorkerURLRequestJob() {
}
......@@ -262,6 +275,7 @@ void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
blob_request_->Start();
}
response_url_ = response.url;
CreateResponseHeader(
response.status_code, response.status_text, response.headers);
if (!blob_request_)
......
......@@ -82,6 +82,9 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob
const net::HttpResponseInfo* http_info() const;
void GetExtraResponseInfo(bool* was_fetched_via_service_worker,
GURL* original_url_via_service_worker) const;
protected:
virtual ~ServiceWorkerURLRequestJob();
......@@ -124,6 +127,7 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob
scoped_ptr<net::HttpResponseInfo> http_response_info_;
// Headers that have not yet been committed to |http_response_info_|.
scoped_refptr<net::HttpResponseHeaders> http_response_headers_;
GURL response_url_;
// Used when response type is FORWARD_TO_SERVICE_WORKER.
scoped_ptr<ServiceWorkerFetchDispatcher> fetch_dispatcher_;
......
......@@ -204,7 +204,8 @@ class BlobResponder : public EmbeddedWorkerTestHelper {
embedded_worker_id,
request_id,
SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE,
ServiceWorkerResponse(200,
ServiceWorkerResponse(GURL(""),
200,
"OK",
std::map<std::string, std::string>(),
blob_uuid_)));
......
......@@ -358,6 +358,13 @@ void ResourceDispatcher::OnReceivedResponse(
request_info->peer = new_peer;
}
// Updates the response_url if the response was fetched by a ServiceWorker,
// and it was not generated inside the ServiceWorker.
if (response_head.was_fetched_via_service_worker &&
!response_head.original_url_via_service_worker.is_empty()) {
request_info->response_url = response_head.original_url_via_service_worker;
}
ResourceResponseInfo renderer_response_info;
ToResourceResponseInfo(*request_info, response_head, &renderer_response_info);
request_info->site_isolation_metadata =
......
......@@ -530,6 +530,12 @@ void WebURLLoaderImpl::Context::OnReceivedResponse(
WebURLResponse response;
response.initialize();
// Updates the request url if the response was fetched by a ServiceWorker,
// and it was not generated inside the ServiceWorker.
if (info.was_fetched_via_service_worker &&
!info.original_url_via_service_worker.is_empty()) {
request_.setURL(info.original_url_via_service_worker);
}
PopulateURLResponse(request_.url(), info, &response);
bool show_raw_listing = (GURL(request_.url()).query() == "raw");
......@@ -752,6 +758,7 @@ void WebURLLoaderImpl::PopulateURLResponse(const GURL& url,
response->setConnectionID(info.load_timing.socket_log_id);
response->setConnectionReused(info.load_timing.socket_reused);
response->setDownloadFilePath(info.download_file_path.AsUTF16Unsafe());
response->setWasFetchedViaServiceWorker(info.was_fetched_via_service_worker);
WebURLResponseExtraDataImpl* extra_data =
new WebURLResponseExtraDataImpl(info.npn_negotiated_protocol);
response->setExtraData(extra_data);
......
......@@ -117,6 +117,8 @@ IPC_STRUCT_TRAITS_BEGIN(content::ResourceResponseInfo)
IPC_STRUCT_TRAITS_MEMBER(was_fetched_via_proxy)
IPC_STRUCT_TRAITS_MEMBER(npn_negotiated_protocol)
IPC_STRUCT_TRAITS_MEMBER(socket_address)
IPC_STRUCT_TRAITS_MEMBER(was_fetched_via_service_worker)
IPC_STRUCT_TRAITS_MEMBER(original_url_via_service_worker)
IPC_STRUCT_TRAITS_END()
// Parameters for a resource request.
......
......@@ -39,6 +39,7 @@ IPC_ENUM_TRAITS_MAX_VALUE(content::ServiceWorkerFetchEventResult,
content::SERVICE_WORKER_FETCH_EVENT_LAST)
IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerResponse)
IPC_STRUCT_TRAITS_MEMBER(url)
IPC_STRUCT_TRAITS_MEMBER(status_code)
IPC_STRUCT_TRAITS_MEMBER(status_text)
IPC_STRUCT_TRAITS_MEMBER(headers)
......
......@@ -27,11 +27,13 @@ ServiceWorkerFetchRequest::~ServiceWorkerFetchRequest() {}
ServiceWorkerResponse::ServiceWorkerResponse() : status_code(0) {}
ServiceWorkerResponse::ServiceWorkerResponse(
const GURL& url,
int status_code,
const std::string& status_text,
const std::map<std::string, std::string>& headers,
const std::string& blob_uuid)
: status_code(status_code),
: url(url),
status_code(status_code),
status_text(status_text),
headers(headers),
blob_uuid(blob_uuid) {
......
......@@ -62,12 +62,14 @@ struct CONTENT_EXPORT ServiceWorkerFetchRequest {
// Represents a response to a fetch.
struct CONTENT_EXPORT ServiceWorkerResponse {
ServiceWorkerResponse();
ServiceWorkerResponse(int status_code,
ServiceWorkerResponse(const GURL& url,
int status_code,
const std::string& status_text,
const std::map<std::string, std::string>& headers,
const std::string& blob_uuid);
~ServiceWorkerResponse();
GURL url;
int status_code;
std::string status_text;
std::map<std::string, std::string> headers;
......
......@@ -17,7 +17,8 @@ ResourceResponseInfo::ResourceResponseInfo()
was_npn_negotiated(false),
was_alternate_protocol_available(false),
connection_info(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN),
was_fetched_via_proxy(false) {
was_fetched_via_proxy(false),
was_fetched_via_service_worker(false) {
}
ResourceResponseInfo::~ResourceResponseInfo() {
......
......@@ -97,6 +97,13 @@ struct ResourceResponseInfo {
// Remote address of the socket which fetched this resource.
net::HostPortPair socket_address;
// True if the response was fetched by a ServiceWorker.
bool was_fetched_via_service_worker;
// The original URL of the response which was fetched by the ServiceWorker.
// This may be empty if the response was created inside the ServiceWorker.
GURL original_url_via_service_worker;
};
} // namespace content
......
......@@ -262,7 +262,8 @@ void EmbeddedWorkerContextClient::didHandleFetchEvent(
headers[base::UTF16ToUTF8(key)] =
base::UTF16ToUTF8(web_response.getHeader(key));
}
ServiceWorkerResponse response(web_response.status(),
ServiceWorkerResponse response(web_response.url(),
web_response.status(),
web_response.statusText().utf8(),
headers,
web_response.blobUUID().utf8());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment