Index: webkit/child/weburlloader_impl.cc |
diff --git a/webkit/child/weburlloader_impl.cc b/webkit/child/weburlloader_impl.cc |
index 63ce778da190cc1ab6e217469ad82afdef646bb8..c776d7945243966d9728e53bf3515f2c544b06d3 100644 |
--- a/webkit/child/weburlloader_impl.cc |
+++ b/webkit/child/weburlloader_impl.cc |
@@ -31,6 +31,7 @@ |
#include "webkit/child/ftp_directory_listing_response_delegate.h" |
#include "webkit/child/multipart_response_delegate.h" |
#include "webkit/child/resource_loader_bridge.h" |
+#include "webkit/child/site_isolation_policy.h" |
#include "webkit/child/webkitplatformsupport_impl.h" |
#include "webkit/child/weburlrequest_extradata_impl.h" |
#include "webkit/child/weburlresponse_extradata_impl.h" |
@@ -59,263 +60,264 @@ namespace webkit_glue { |
namespace { |
-const char kThrottledErrorDescription[] = |
- "Request throttled. Visit http://dev.chromium.org/throttling for more " |
- "information."; |
- |
-class HeaderFlattener : public WebHTTPHeaderVisitor { |
- public: |
- explicit HeaderFlattener(int load_flags) |
- : load_flags_(load_flags), |
- has_accept_header_(false) { |
- } |
- |
- virtual void visitHeader(const WebString& name, const WebString& value) { |
- // TODO(darin): is UTF-8 really correct here? It is if the strings are |
- // already ASCII (i.e., if they are already escaped properly). |
- const std::string& name_utf8 = name.utf8(); |
- const std::string& value_utf8 = value.utf8(); |
- |
- // Skip over referrer headers found in the header map because we already |
- // pulled it out as a separate parameter. |
- if (LowerCaseEqualsASCII(name_utf8, "referer")) |
- return; |
- |
- // Skip over "Cache-Control: max-age=0" header if the corresponding |
- // load flag is already specified. FrameLoader sets both the flag and |
- // the extra header -- the extra header is redundant since our network |
- // implementation will add the necessary headers based on load flags. |
- // See http://code.google.com/p/chromium/issues/detail?id=3434. |
- if ((load_flags_ & net::LOAD_VALIDATE_CACHE) && |
- LowerCaseEqualsASCII(name_utf8, "cache-control") && |
- LowerCaseEqualsASCII(value_utf8, "max-age=0")) |
- return; |
- |
- if (LowerCaseEqualsASCII(name_utf8, "accept")) |
- has_accept_header_ = true; |
- |
- if (!buffer_.empty()) |
- buffer_.append("\r\n"); |
- buffer_.append(name_utf8 + ": " + value_utf8); |
- } |
- |
- const std::string& GetBuffer() { |
- // In some cases, WebKit doesn't add an Accept header, but not having the |
- // header confuses some web servers. See bug 808613. |
- if (!has_accept_header_) { |
- if (!buffer_.empty()) |
- buffer_.append("\r\n"); |
- buffer_.append("Accept: */*"); |
- has_accept_header_ = true; |
- } |
- return buffer_; |
- } |
+ const char kThrottledErrorDescription[] = "Request throttled. Visit http://dev.chromium.org/throttling for more " |
+ "information."; |
- private: |
- int load_flags_; |
- std::string buffer_; |
- bool has_accept_header_; |
-}; |
+ class HeaderFlattener : public WebHTTPHeaderVisitor { |
+ public: |
+ explicit HeaderFlattener(int load_flags) |
+ : load_flags_(load_flags) |
+ , has_accept_header_(false) |
+ { |
+ } |
-// Extracts the information from a data: url. |
-bool GetInfoFromDataURL(const GURL& url, |
- ResourceResponseInfo* info, |
- std::string* data, |
- int* error_code) { |
- std::string mime_type; |
- std::string charset; |
- if (net::DataURL::Parse(url, &mime_type, &charset, data)) { |
- *error_code = net::OK; |
- // Assure same time for all time fields of data: URLs. |
- Time now = Time::Now(); |
- info->load_timing.request_start = TimeTicks::Now(); |
- info->load_timing.request_start_time = now; |
- info->request_time = now; |
- info->response_time = now; |
- info->headers = NULL; |
- info->mime_type.swap(mime_type); |
- info->charset.swap(charset); |
- info->security_info.clear(); |
- info->content_length = data->length(); |
- info->encoded_data_length = 0; |
- |
- return true; |
- } |
- |
- *error_code = net::ERR_INVALID_URL; |
- return false; |
-} |
+ virtual void visitHeader(const WebString& name, const WebString& value) |
+ { |
+ // TODO(darin): is UTF-8 really correct here? It is if the strings are |
+ // already ASCII (i.e., if they are already escaped properly). |
+ const std::string& name_utf8 = name.utf8(); |
+ const std::string& value_utf8 = value.utf8(); |
+ |
+ // Skip over referrer headers found in the header map because we already |
+ // pulled it out as a separate parameter. |
+ if (LowerCaseEqualsASCII(name_utf8, "referer")) |
+ return; |
+ |
+ // Skip over "Cache-Control: max-age=0" header if the corresponding |
+ // load flag is already specified. FrameLoader sets both the flag and |
+ // the extra header -- the extra header is redundant since our network |
+ // implementation will add the necessary headers based on load flags. |
+ // See http://code.google.com/p/chromium/issues/detail?id=3434. |
+ if ((load_flags_ & net::LOAD_VALIDATE_CACHE) && LowerCaseEqualsASCII(name_utf8, "cache-control") && LowerCaseEqualsASCII(value_utf8, "max-age=0")) |
+ return; |
+ |
+ if (LowerCaseEqualsASCII(name_utf8, "accept")) |
+ has_accept_header_ = true; |
+ |
+ if (!buffer_.empty()) |
+ buffer_.append("\r\n"); |
+ buffer_.append(name_utf8 + ": " + value_utf8); |
+ } |
-typedef ResourceDevToolsInfo::HeadersVector HeadersVector; |
- |
-// Converts timing data from |load_timing| to the format used by WebKit. |
-void PopulateURLLoadTiming(const net::LoadTimingInfo& load_timing, |
- WebURLLoadTiming* url_timing) { |
- DCHECK(!load_timing.request_start.is_null()); |
- |
- const TimeTicks kNullTicks; |
- url_timing->initialize(); |
- url_timing->setRequestTime( |
- (load_timing.request_start - kNullTicks).InSecondsF()); |
- url_timing->setProxyStart( |
- (load_timing.proxy_resolve_start - kNullTicks).InSecondsF()); |
- url_timing->setProxyEnd( |
- (load_timing.proxy_resolve_end - kNullTicks).InSecondsF()); |
- url_timing->setDNSStart( |
- (load_timing.connect_timing.dns_start - kNullTicks).InSecondsF()); |
- url_timing->setDNSEnd( |
- (load_timing.connect_timing.dns_end - kNullTicks).InSecondsF()); |
- url_timing->setConnectStart( |
- (load_timing.connect_timing.connect_start - kNullTicks).InSecondsF()); |
- url_timing->setConnectEnd( |
- (load_timing.connect_timing.connect_end - kNullTicks).InSecondsF()); |
- url_timing->setSSLStart( |
- (load_timing.connect_timing.ssl_start - kNullTicks).InSecondsF()); |
- url_timing->setSSLEnd( |
- (load_timing.connect_timing.ssl_end - kNullTicks).InSecondsF()); |
- url_timing->setSendStart( |
- (load_timing.send_start - kNullTicks).InSecondsF()); |
- url_timing->setSendEnd( |
- (load_timing.send_end - kNullTicks).InSecondsF()); |
- url_timing->setReceiveHeadersEnd( |
- (load_timing.receive_headers_end - kNullTicks).InSecondsF()); |
-} |
+ const std::string& GetBuffer() |
+ { |
+ // In some cases, WebKit doesn't add an Accept header, but not having the |
+ // header confuses some web servers. See bug 808613. |
+ if (!has_accept_header_) { |
+ if (!buffer_.empty()) |
+ buffer_.append("\r\n"); |
+ buffer_.append("Accept: */*"); |
+ has_accept_header_ = true; |
+ } |
+ return buffer_; |
+ } |
-void PopulateURLResponse( |
- const GURL& url, |
- const ResourceResponseInfo& info, |
- WebURLResponse* response) { |
- response->setURL(url); |
- response->setResponseTime(info.response_time.ToDoubleT()); |
- response->setMIMEType(WebString::fromUTF8(info.mime_type)); |
- response->setTextEncodingName(WebString::fromUTF8(info.charset)); |
- response->setExpectedContentLength(info.content_length); |
- response->setSecurityInfo(info.security_info); |
- response->setAppCacheID(info.appcache_id); |
- response->setAppCacheManifestURL(info.appcache_manifest_url); |
- response->setWasCached(!info.load_timing.request_start_time.is_null() && |
- info.response_time < info.load_timing.request_start_time); |
- response->setRemoteIPAddress( |
- WebString::fromUTF8(info.socket_address.host())); |
- response->setRemotePort(info.socket_address.port()); |
- response->setConnectionID(info.load_timing.socket_log_id); |
- response->setConnectionReused(info.load_timing.socket_reused); |
- response->setDownloadFilePath(info.download_file_path.AsUTF16Unsafe()); |
- WebURLResponseExtraDataImpl* extra_data = |
- new WebURLResponseExtraDataImpl(info.npn_negotiated_protocol); |
- response->setExtraData(extra_data); |
- extra_data->set_was_fetched_via_spdy(info.was_fetched_via_spdy); |
- extra_data->set_was_npn_negotiated(info.was_npn_negotiated); |
- extra_data->set_was_alternate_protocol_available( |
- info.was_alternate_protocol_available); |
- extra_data->set_connection_info(info.connection_info); |
- extra_data->set_was_fetched_via_proxy(info.was_fetched_via_proxy); |
- |
- // If there's no received headers end time, don't set load timing. This is |
- // the case for non-HTTP requests, requests that don't go over the wire, and |
- // certain error cases. |
- if (!info.load_timing.receive_headers_end.is_null()) { |
- WebURLLoadTiming timing; |
- PopulateURLLoadTiming(info.load_timing, &timing); |
- response->setLoadTiming(timing); |
- } |
- |
- if (info.devtools_info.get()) { |
- WebHTTPLoadInfo load_info; |
- |
- load_info.setHTTPStatusCode(info.devtools_info->http_status_code); |
- load_info.setHTTPStatusText(WebString::fromUTF8( |
- info.devtools_info->http_status_text)); |
- load_info.setEncodedDataLength(info.encoded_data_length); |
- |
- load_info.setRequestHeadersText(WebString::fromUTF8( |
- info.devtools_info->request_headers_text)); |
- load_info.setResponseHeadersText(WebString::fromUTF8( |
- info.devtools_info->response_headers_text)); |
- const HeadersVector& request_headers = info.devtools_info->request_headers; |
- for (HeadersVector::const_iterator it = request_headers.begin(); |
- it != request_headers.end(); ++it) { |
- load_info.addRequestHeader(WebString::fromUTF8(it->first), |
- WebString::fromUTF8(it->second)); |
+ private: |
+ int load_flags_; |
+ std::string buffer_; |
+ bool has_accept_header_; |
+ }; |
+ |
+ // Extracts the information from a data: url. |
+ bool GetInfoFromDataURL(const GURL& url, |
+ ResourceResponseInfo* info, |
+ std::string* data, |
+ int* error_code) |
+ { |
+ std::string mime_type; |
+ std::string charset; |
+ if (net::DataURL::Parse(url, &mime_type, &charset, data)) { |
+ *error_code = net::OK; |
+ // Assure same time for all time fields of data: URLs. |
+ Time now = Time::Now(); |
+ info->load_timing.request_start = TimeTicks::Now(); |
+ info->load_timing.request_start_time = now; |
+ info->request_time = now; |
+ info->response_time = now; |
+ info->headers = NULL; |
+ info->mime_type.swap(mime_type); |
+ info->charset.swap(charset); |
+ info->security_info.clear(); |
+ info->content_length = data->length(); |
+ info->encoded_data_length = 0; |
+ |
+ return true; |
+ } |
+ |
+ *error_code = net::ERR_INVALID_URL; |
+ return false; |
} |
- const HeadersVector& response_headers = |
- info.devtools_info->response_headers; |
- for (HeadersVector::const_iterator it = response_headers.begin(); |
- it != response_headers.end(); ++it) { |
- load_info.addResponseHeader(WebString::fromUTF8(it->first), |
- WebString::fromUTF8(it->second)); |
+ |
+ typedef ResourceDevToolsInfo::HeadersVector HeadersVector; |
+ |
+ // Converts timing data from |load_timing| to the format used by WebKit. |
+ void PopulateURLLoadTiming(const net::LoadTimingInfo& load_timing, |
+ WebURLLoadTiming* url_timing) |
+ { |
+ DCHECK(!load_timing.request_start.is_null()); |
+ |
+ const TimeTicks kNullTicks; |
+ url_timing->initialize(); |
+ url_timing->setRequestTime( |
+ (load_timing.request_start - kNullTicks).InSecondsF()); |
+ url_timing->setProxyStart( |
+ (load_timing.proxy_resolve_start - kNullTicks).InSecondsF()); |
+ url_timing->setProxyEnd( |
+ (load_timing.proxy_resolve_end - kNullTicks).InSecondsF()); |
+ url_timing->setDNSStart( |
+ (load_timing.connect_timing.dns_start - kNullTicks).InSecondsF()); |
+ url_timing->setDNSEnd( |
+ (load_timing.connect_timing.dns_end - kNullTicks).InSecondsF()); |
+ url_timing->setConnectStart( |
+ (load_timing.connect_timing.connect_start - kNullTicks).InSecondsF()); |
+ url_timing->setConnectEnd( |
+ (load_timing.connect_timing.connect_end - kNullTicks).InSecondsF()); |
+ url_timing->setSSLStart( |
+ (load_timing.connect_timing.ssl_start - kNullTicks).InSecondsF()); |
+ url_timing->setSSLEnd( |
+ (load_timing.connect_timing.ssl_end - kNullTicks).InSecondsF()); |
+ url_timing->setSendStart( |
+ (load_timing.send_start - kNullTicks).InSecondsF()); |
+ url_timing->setSendEnd( |
+ (load_timing.send_end - kNullTicks).InSecondsF()); |
+ url_timing->setReceiveHeadersEnd( |
+ (load_timing.receive_headers_end - kNullTicks).InSecondsF()); |
} |
- response->setHTTPLoadInfo(load_info); |
- } |
- |
- const net::HttpResponseHeaders* headers = info.headers.get(); |
- if (!headers) |
- return; |
- |
- WebURLResponse::HTTPVersion version = WebURLResponse::Unknown; |
- if (headers->GetHttpVersion() == net::HttpVersion(0, 9)) |
- version = WebURLResponse::HTTP_0_9; |
- else if (headers->GetHttpVersion() == net::HttpVersion(1, 0)) |
- version = WebURLResponse::HTTP_1_0; |
- else if (headers->GetHttpVersion() == net::HttpVersion(1, 1)) |
- version = WebURLResponse::HTTP_1_1; |
- response->setHTTPVersion(version); |
- response->setHTTPStatusCode(headers->response_code()); |
- response->setHTTPStatusText(WebString::fromUTF8(headers->GetStatusText())); |
- |
- // TODO(darin): We should leverage HttpResponseHeaders for this, and this |
- // should be using the same code as ResourceDispatcherHost. |
- // TODO(jungshik): Figure out the actual value of the referrer charset and |
- // pass it to GetSuggestedFilename. |
- std::string value; |
- headers->EnumerateHeader(NULL, "content-disposition", &value); |
- response->setSuggestedFileName( |
- net::GetSuggestedFilename(url, |
- value, |
- std::string(), // referrer_charset |
- std::string(), // suggested_name |
- std::string(), // mime_type |
- std::string())); // default_name |
- |
- Time time_val; |
- if (headers->GetLastModifiedValue(&time_val)) |
- response->setLastModifiedDate(time_val.ToDoubleT()); |
- |
- // Build up the header map. |
- void* iter = NULL; |
- std::string name; |
- while (headers->EnumerateHeaderLines(&iter, &name, &value)) { |
- response->addHTTPHeaderField(WebString::fromUTF8(name), |
- WebString::fromUTF8(value)); |
- } |
-} |
-net::RequestPriority ConvertWebKitPriorityToNetPriority( |
- const WebURLRequest::Priority& priority) { |
- switch (priority) { |
- case WebURLRequest::PriorityVeryHigh: |
- return net::HIGHEST; |
+ void PopulateURLResponse( |
+ const GURL& url, |
+ const ResourceResponseInfo& info, |
+ WebURLResponse* response) |
+ { |
+ response->setURL(url); |
+ response->setResponseTime(info.response_time.ToDoubleT()); |
+ response->setMIMEType(WebString::fromUTF8(info.mime_type)); |
+ response->setTextEncodingName(WebString::fromUTF8(info.charset)); |
+ response->setExpectedContentLength(info.content_length); |
+ response->setSecurityInfo(info.security_info); |
+ response->setAppCacheID(info.appcache_id); |
+ response->setAppCacheManifestURL(info.appcache_manifest_url); |
+ response->setWasCached(!info.load_timing.request_start_time.is_null() && info.response_time < info.load_timing.request_start_time); |
+ response->setRemoteIPAddress( |
+ WebString::fromUTF8(info.socket_address.host())); |
+ response->setRemotePort(info.socket_address.port()); |
+ response->setConnectionID(info.load_timing.socket_log_id); |
+ response->setConnectionReused(info.load_timing.socket_reused); |
+ response->setDownloadFilePath(info.download_file_path.AsUTF16Unsafe()); |
+ WebURLResponseExtraDataImpl* extra_data = new WebURLResponseExtraDataImpl(info.npn_negotiated_protocol); |
+ response->setExtraData(extra_data); |
+ extra_data->set_was_fetched_via_spdy(info.was_fetched_via_spdy); |
+ extra_data->set_was_npn_negotiated(info.was_npn_negotiated); |
+ extra_data->set_was_alternate_protocol_available( |
+ info.was_alternate_protocol_available); |
+ extra_data->set_connection_info(info.connection_info); |
+ extra_data->set_was_fetched_via_proxy(info.was_fetched_via_proxy); |
+ |
+ // If there's no received headers end time, don't set load timing. This is |
+ // the case for non-HTTP requests, requests that don't go over the wire, and |
+ // certain error cases. |
+ if (!info.load_timing.receive_headers_end.is_null()) { |
+ WebURLLoadTiming timing; |
+ PopulateURLLoadTiming(info.load_timing, &timing); |
+ response->setLoadTiming(timing); |
+ } |
- case WebURLRequest::PriorityHigh: |
- return net::MEDIUM; |
+ if (info.devtools_info.get()) { |
+ WebHTTPLoadInfo load_info; |
+ |
+ load_info.setHTTPStatusCode(info.devtools_info->http_status_code); |
+ load_info.setHTTPStatusText(WebString::fromUTF8( |
+ info.devtools_info->http_status_text)); |
+ load_info.setEncodedDataLength(info.encoded_data_length); |
+ |
+ load_info.setRequestHeadersText(WebString::fromUTF8( |
+ info.devtools_info->request_headers_text)); |
+ load_info.setResponseHeadersText(WebString::fromUTF8( |
+ info.devtools_info->response_headers_text)); |
+ const HeadersVector& request_headers = info.devtools_info->request_headers; |
+ for (HeadersVector::const_iterator it = request_headers.begin(); |
+ it != request_headers.end(); ++it) { |
+ load_info.addRequestHeader(WebString::fromUTF8(it->first), |
+ WebString::fromUTF8(it->second)); |
+ } |
+ const HeadersVector& response_headers = info.devtools_info->response_headers; |
+ for (HeadersVector::const_iterator it = response_headers.begin(); |
+ it != response_headers.end(); ++it) { |
+ load_info.addResponseHeader(WebString::fromUTF8(it->first), |
+ WebString::fromUTF8(it->second)); |
+ } |
+ response->setHTTPLoadInfo(load_info); |
+ } |
- case WebURLRequest::PriorityMedium: |
- return net::LOW; |
+ const net::HttpResponseHeaders* headers = info.headers.get(); |
+ if (!headers) |
+ return; |
+ |
+ WebURLResponse::HTTPVersion version = WebURLResponse::Unknown; |
+ if (headers->GetHttpVersion() == net::HttpVersion(0, 9)) |
+ version = WebURLResponse::HTTP_0_9; |
+ else if (headers->GetHttpVersion() == net::HttpVersion(1, 0)) |
+ version = WebURLResponse::HTTP_1_0; |
+ else if (headers->GetHttpVersion() == net::HttpVersion(1, 1)) |
+ version = WebURLResponse::HTTP_1_1; |
+ response->setHTTPVersion(version); |
+ response->setHTTPStatusCode(headers->response_code()); |
+ response->setHTTPStatusText(WebString::fromUTF8(headers->GetStatusText())); |
+ |
+ // TODO(darin): We should leverage HttpResponseHeaders for this, and this |
+ // should be using the same code as ResourceDispatcherHost. |
+ // TODO(jungshik): Figure out the actual value of the referrer charset and |
+ // pass it to GetSuggestedFilename. |
+ std::string value; |
+ headers->EnumerateHeader(NULL, "content-disposition", &value); |
+ response->setSuggestedFileName( |
+ net::GetSuggestedFilename(url, |
+ value, |
+ std::string(), // referrer_charset |
+ std::string(), // suggested_name |
+ std::string(), // mime_type |
+ std::string())); // default_name |
+ |
+ Time time_val; |
+ if (headers->GetLastModifiedValue(&time_val)) |
+ response->setLastModifiedDate(time_val.ToDoubleT()); |
+ |
+ // Build up the header map. |
+ void* iter = NULL; |
+ std::string name; |
+ while (headers->EnumerateHeaderLines(&iter, &name, &value)) { |
+ response->addHTTPHeaderField(WebString::fromUTF8(name), |
+ WebString::fromUTF8(value)); |
+ } |
+ } |
- case WebURLRequest::PriorityLow: |
- return net::LOWEST; |
+ net::RequestPriority ConvertWebKitPriorityToNetPriority( |
+ const WebURLRequest::Priority& priority) |
+ { |
+ switch (priority) { |
+ case WebURLRequest::PriorityVeryHigh: |
+ return net::HIGHEST; |
- case WebURLRequest::PriorityVeryLow: |
- return net::IDLE; |
+ case WebURLRequest::PriorityHigh: |
+ return net::MEDIUM; |
- case WebURLRequest::PriorityUnresolved: |
- default: |
- NOTREACHED(); |
- return net::LOW; |
- } |
-} |
+ case WebURLRequest::PriorityMedium: |
+ return net::LOW; |
+ |
+ case WebURLRequest::PriorityLow: |
+ return net::LOWEST; |
+ |
+ case WebURLRequest::PriorityVeryLow: |
+ return net::IDLE; |
-} // namespace |
+ case WebURLRequest::PriorityUnresolved: |
+ default: |
+ NOTREACHED(); |
+ return net::LOW; |
+ } |
+ } |
+ |
+} // namespace |
// WebURLLoaderImpl::Context -------------------------------------------------- |
@@ -324,530 +326,571 @@ net::RequestPriority ConvertWebKitPriorityToNetPriority( |
// until it receives OnCompletedRequest. |
class WebURLLoaderImpl::Context : public base::RefCounted<Context>, |
public ResourceLoaderBridge::Peer { |
- public: |
- explicit Context(WebURLLoaderImpl* loader); |
- |
- WebURLLoaderClient* client() const { return client_; } |
- void set_client(WebURLLoaderClient* client) { client_ = client; } |
- |
- void Cancel(); |
- void SetDefersLoading(bool value); |
- void DidChangePriority(WebURLRequest::Priority new_priority); |
- void Start( |
- const WebURLRequest& request, |
- ResourceLoaderBridge::SyncLoadResponse* sync_load_response, |
- WebKitPlatformSupportImpl* platform); |
- |
- // ResourceLoaderBridge::Peer methods: |
- virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE; |
- virtual bool OnReceivedRedirect( |
- const GURL& new_url, |
- const ResourceResponseInfo& info, |
- bool* has_new_first_party_for_cookies, |
- GURL* new_first_party_for_cookies) OVERRIDE; |
- virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE; |
- virtual void OnDownloadedData(int len) OVERRIDE; |
- virtual void OnReceivedData(const char* data, |
- int data_length, |
- int encoded_data_length) OVERRIDE; |
- virtual void OnReceivedCachedMetadata(const char* data, int len) OVERRIDE; |
- virtual void OnCompletedRequest( |
- int error_code, |
- bool was_ignored_by_handler, |
- const std::string& security_info, |
- const base::TimeTicks& completion_time) OVERRIDE; |
- |
- private: |
- friend class base::RefCounted<Context>; |
- virtual ~Context() {} |
- |
- // We can optimize the handling of data URLs in most cases. |
- bool CanHandleDataURL(const GURL& url) const; |
- void HandleDataURL(); |
- |
- WebURLLoaderImpl* loader_; |
- WebURLRequest request_; |
- WebURLLoaderClient* client_; |
- WebReferrerPolicy referrer_policy_; |
- scoped_ptr<ResourceLoaderBridge> bridge_; |
- scoped_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_; |
- scoped_ptr<MultipartResponseDelegate> multipart_delegate_; |
- scoped_ptr<ResourceLoaderBridge> completed_bridge_; |
+public: |
+ explicit Context(WebURLLoaderImpl* loader); |
+ |
+ WebURLLoaderClient* client() const |
+ { |
+ return client_; |
+ } |
+ void set_client(WebURLLoaderClient* client) |
+ { |
+ client_ = client; |
+ } |
+ |
+ void Cancel(); |
+ void SetDefersLoading(bool value); |
+ void DidChangePriority(WebURLRequest::Priority new_priority); |
+ void Start( |
+ const WebURLRequest& request, |
+ ResourceLoaderBridge::SyncLoadResponse* sync_load_response, |
+ WebKitPlatformSupportImpl* platform); |
+ |
+ // ResourceLoaderBridge::Peer methods: |
+ virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE; |
+ virtual bool OnReceivedRedirect( |
+ const GURL& new_url, |
+ const ResourceResponseInfo& info, |
+ bool* has_new_first_party_for_cookies, |
+ GURL* new_first_party_for_cookies) OVERRIDE; |
+ virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE; |
+ virtual void OnDownloadedData(int len) OVERRIDE; |
+ virtual void OnReceivedData(const char* data, |
+ int data_length, |
+ int encoded_data_length) OVERRIDE; |
+ virtual void OnReceivedCachedMetadata(const char* data, int len) OVERRIDE; |
+ virtual void OnCompletedRequest( |
+ int error_code, |
+ bool was_ignored_by_handler, |
+ const std::string& security_info, |
+ const base::TimeTicks& completion_time) OVERRIDE; |
+ |
+private: |
+ friend class base::RefCounted<Context>; |
+ virtual ~Context() |
+ { |
+ } |
+ |
+ // We can optimize the handling of data URLs in most cases. |
+ bool CanHandleDataURL(const GURL& url) const; |
+ void HandleDataURL(); |
+ |
+ WebURLLoaderImpl* loader_; |
+ WebURLRequest request_; |
+ WebURLLoaderClient* client_; |
+ WebReferrerPolicy referrer_policy_; |
+ scoped_ptr<ResourceLoaderBridge> bridge_; |
+ scoped_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_; |
+ scoped_ptr<MultipartResponseDelegate> multipart_delegate_; |
+ scoped_ptr<ResourceLoaderBridge> completed_bridge_; |
+ |
+ // TODO(dsjang): A temporary hack to connect the lastest response |
+ // observed by OnReceiveResponse() and the data stream received by OnReceivedData(). |
+ WebURL response_url_; |
}; |
WebURLLoaderImpl::Context::Context(WebURLLoaderImpl* loader) |
- : loader_(loader), |
- client_(NULL), |
- referrer_policy_(WebKit::WebReferrerPolicyDefault) { |
+ : loader_(loader) |
+ , client_(NULL) |
+ , referrer_policy_(WebKit::WebReferrerPolicyDefault) |
+{ |
} |
-void WebURLLoaderImpl::Context::Cancel() { |
- // The bridge will still send OnCompletedRequest, which will Release() us, so |
- // we don't do that here. |
- if (bridge_) |
- bridge_->Cancel(); |
- |
- // Ensure that we do not notify the multipart delegate anymore as it has |
- // its own pointer to the client. |
- if (multipart_delegate_) |
- multipart_delegate_->Cancel(); |
- |
- // Do not make any further calls to the client. |
- client_ = NULL; |
- loader_ = NULL; |
+void WebURLLoaderImpl::Context::Cancel() |
+{ |
+ // The bridge will still send OnCompletedRequest, which will Release() us, so |
+ // we don't do that here. |
+ if (bridge_) |
+ bridge_->Cancel(); |
+ |
+ // Ensure that we do not notify the multipart delegate anymore as it has |
+ // its own pointer to the client. |
+ if (multipart_delegate_) |
+ multipart_delegate_->Cancel(); |
+ |
+ // Do not make any further calls to the client. |
+ client_ = NULL; |
+ loader_ = NULL; |
} |
-void WebURLLoaderImpl::Context::SetDefersLoading(bool value) { |
- if (bridge_) |
- bridge_->SetDefersLoading(value); |
+void WebURLLoaderImpl::Context::SetDefersLoading(bool value) |
+{ |
+ if (bridge_) |
+ bridge_->SetDefersLoading(value); |
} |
void WebURLLoaderImpl::Context::DidChangePriority( |
- WebURLRequest::Priority new_priority) { |
- if (bridge_) |
- bridge_->DidChangePriority( |
- ConvertWebKitPriorityToNetPriority(new_priority)); |
+ WebURLRequest::Priority new_priority) |
+{ |
+ if (bridge_) |
+ bridge_->DidChangePriority( |
+ ConvertWebKitPriorityToNetPriority(new_priority)); |
} |
void WebURLLoaderImpl::Context::Start( |
const WebURLRequest& request, |
ResourceLoaderBridge::SyncLoadResponse* sync_load_response, |
- WebKitPlatformSupportImpl* platform) { |
- DCHECK(!bridge_.get()); |
- |
- request_ = request; // Save the request. |
- |
- GURL url = request.url(); |
- if (url.SchemeIs("data") && CanHandleDataURL(url)) { |
- if (sync_load_response) { |
- // This is a sync load. Do the work now. |
- sync_load_response->url = url; |
- std::string data; |
- GetInfoFromDataURL(sync_load_response->url, sync_load_response, |
- &sync_load_response->data, |
- &sync_load_response->error_code); |
- } else { |
- AddRef(); // Balanced in OnCompletedRequest |
- base::MessageLoop::current()->PostTask( |
- FROM_HERE, base::Bind(&Context::HandleDataURL, this)); |
+ WebKitPlatformSupportImpl* platform) |
+{ |
+ DCHECK(!bridge_.get()); |
+ |
+ request_ = request; // Save the request. |
+ |
+ GURL url = request.url(); |
+ if (url.SchemeIs("data") && CanHandleDataURL(url)) { |
+ if (sync_load_response) { |
+ // This is a sync load. Do the work now. |
+ sync_load_response->url = url; |
+ std::string data; |
+ GetInfoFromDataURL(sync_load_response->url, sync_load_response, |
+ &sync_load_response->data, |
+ &sync_load_response->error_code); |
+ } else { |
+ AddRef(); // Balanced in OnCompletedRequest |
+ base::MessageLoop::current()->PostTask( |
+ FROM_HERE, base::Bind(&Context::HandleDataURL, this)); |
+ } |
+ return; |
} |
- return; |
- } |
- GURL referrer_url( |
- request.httpHeaderField(WebString::fromUTF8("Referer")).utf8()); |
- const std::string& method = request.httpMethod().utf8(); |
+ GURL referrer_url( |
+ request.httpHeaderField(WebString::fromUTF8("Referer")).utf8()); |
+ const std::string& method = request.httpMethod().utf8(); |
- int load_flags = net::LOAD_NORMAL; |
- switch (request.cachePolicy()) { |
+ int load_flags = net::LOAD_NORMAL; |
+ switch (request.cachePolicy()) { |
case WebURLRequest::ReloadIgnoringCacheData: |
- // Required by LayoutTests/http/tests/misc/refresh-headers.php |
- load_flags |= net::LOAD_VALIDATE_CACHE; |
- break; |
+ // Required by LayoutTests/http/tests/misc/refresh-headers.php |
+ load_flags |= net::LOAD_VALIDATE_CACHE; |
+ break; |
case WebURLRequest::ReturnCacheDataElseLoad: |
- load_flags |= net::LOAD_PREFERRING_CACHE; |
- break; |
+ load_flags |= net::LOAD_PREFERRING_CACHE; |
+ break; |
case WebURLRequest::ReturnCacheDataDontLoad: |
- load_flags |= net::LOAD_ONLY_FROM_CACHE; |
- break; |
+ load_flags |= net::LOAD_ONLY_FROM_CACHE; |
+ break; |
case WebURLRequest::UseProtocolCachePolicy: |
- break; |
- } |
- |
- if (request.reportUploadProgress()) |
- load_flags |= net::LOAD_ENABLE_UPLOAD_PROGRESS; |
- if (request.reportLoadTiming()) |
- load_flags |= net::LOAD_ENABLE_LOAD_TIMING; |
- if (request.reportRawHeaders()) |
- load_flags |= net::LOAD_REPORT_RAW_HEADERS; |
- |
- if (!request.allowCookies() || !request.allowStoredCredentials()) { |
- load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES; |
- load_flags |= net::LOAD_DO_NOT_SEND_COOKIES; |
- } |
- |
- if (!request.allowStoredCredentials()) |
- load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA; |
- |
- HeaderFlattener flattener(load_flags); |
- request.visitHTTPHeaderFields(&flattener); |
- |
- // TODO(brettw) this should take parameter encoding into account when |
- // creating the GURLs. |
- |
- ResourceLoaderBridge::RequestInfo request_info; |
- request_info.method = method; |
- request_info.url = url; |
- request_info.first_party_for_cookies = request.firstPartyForCookies(); |
- request_info.referrer = referrer_url; |
- request_info.headers = flattener.GetBuffer(); |
- request_info.load_flags = load_flags; |
- // requestor_pid only needs to be non-zero if the request originates outside |
- // the render process, so we can use requestorProcessID even for requests |
- // from in-process plugins. |
- request_info.requestor_pid = request.requestorProcessID(); |
- request_info.request_type = |
- ResourceType::FromTargetType(request.targetType()); |
- request_info.priority = |
- ConvertWebKitPriorityToNetPriority(request.priority()); |
- request_info.appcache_host_id = request.appCacheHostID(); |
- request_info.routing_id = request.requestorID(); |
- request_info.download_to_file = request.downloadToFile(); |
- request_info.has_user_gesture = request.hasUserGesture(); |
- request_info.extra_data = request.extraData(); |
- if (request.extraData()) { |
- referrer_policy_ = static_cast<WebURLRequestExtraDataImpl*>( |
- request.extraData())->referrer_policy(); |
- request_info.referrer_policy = referrer_policy_; |
- } |
- bridge_.reset(platform->CreateResourceLoader(request_info)); |
- |
- if (!request.httpBody().isNull()) { |
- // GET and HEAD requests shouldn't have http bodies. |
- DCHECK(method != "GET" && method != "HEAD"); |
- const WebHTTPBody& httpBody = request.httpBody(); |
- size_t i = 0; |
- WebHTTPBody::Element element; |
- scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody; |
- while (httpBody.elementAt(i++, element)) { |
- switch (element.type) { |
- case WebHTTPBody::Element::TypeData: |
- if (!element.data.isEmpty()) { |
- // WebKit sometimes gives up empty data to append. These aren't |
- // necessary so we just optimize those out here. |
- request_body->AppendBytes( |
- element.data.data(), static_cast<int>(element.data.size())); |
- } |
- break; |
- case WebHTTPBody::Element::TypeFile: |
- if (element.fileLength == -1) { |
- request_body->AppendFileRange( |
- base::FilePath::FromUTF16Unsafe(element.filePath), |
- 0, kuint64max, base::Time()); |
- } else { |
- request_body->AppendFileRange( |
- base::FilePath::FromUTF16Unsafe(element.filePath), |
- static_cast<uint64>(element.fileStart), |
- static_cast<uint64>(element.fileLength), |
- base::Time::FromDoubleT(element.modificationTime)); |
- } |
- break; |
- case WebHTTPBody::Element::TypeURL: { |
- GURL url = GURL(element.url); |
- DCHECK(url.SchemeIsFileSystem()); |
- request_body->AppendFileSystemFileRange( |
- url, |
- static_cast<uint64>(element.fileStart), |
- static_cast<uint64>(element.fileLength), |
- base::Time::FromDoubleT(element.modificationTime)); |
- break; |
+ break; |
+ } |
+ |
+ if (request.reportUploadProgress()) |
+ load_flags |= net::LOAD_ENABLE_UPLOAD_PROGRESS; |
+ if (request.reportLoadTiming()) |
+ load_flags |= net::LOAD_ENABLE_LOAD_TIMING; |
+ if (request.reportRawHeaders()) |
+ load_flags |= net::LOAD_REPORT_RAW_HEADERS; |
+ |
+ if (!request.allowCookies() || !request.allowStoredCredentials()) { |
+ load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES; |
+ load_flags |= net::LOAD_DO_NOT_SEND_COOKIES; |
+ } |
+ |
+ if (!request.allowStoredCredentials()) |
+ load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA; |
+ |
+ HeaderFlattener flattener(load_flags); |
+ request.visitHTTPHeaderFields(&flattener); |
+ |
+ // TODO(brettw) this should take parameter encoding into account when |
+ // creating the GURLs. |
+ |
+ ResourceLoaderBridge::RequestInfo request_info; |
+ request_info.method = method; |
+ request_info.url = url; |
+ request_info.first_party_for_cookies = request.firstPartyForCookies(); |
+ request_info.referrer = referrer_url; |
+ request_info.headers = flattener.GetBuffer(); |
+ request_info.load_flags = load_flags; |
+ // requestor_pid only needs to be non-zero if the request originates outside |
+ // the render process, so we can use requestorProcessID even for requests |
+ // from in-process plugins. |
+ request_info.requestor_pid = request.requestorProcessID(); |
+ request_info.request_type = ResourceType::FromTargetType(request.targetType()); |
+ request_info.priority = ConvertWebKitPriorityToNetPriority(request.priority()); |
+ request_info.appcache_host_id = request.appCacheHostID(); |
+ request_info.routing_id = request.requestorID(); |
+ request_info.download_to_file = request.downloadToFile(); |
+ request_info.has_user_gesture = request.hasUserGesture(); |
+ request_info.extra_data = request.extraData(); |
+ if (request.extraData()) { |
+ referrer_policy_ = static_cast<WebURLRequestExtraDataImpl*>( |
+ request.extraData())->referrer_policy(); |
+ request_info.referrer_policy = referrer_policy_; |
+ } |
+ bridge_.reset(platform->CreateResourceLoader(request_info)); |
+ |
+ if (!request.httpBody().isNull()) { |
+ // GET and HEAD requests shouldn't have http bodies. |
+ DCHECK(method != "GET" && method != "HEAD"); |
+ const WebHTTPBody& httpBody = request.httpBody(); |
+ size_t i = 0; |
+ WebHTTPBody::Element element; |
+ scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody; |
+ while (httpBody.elementAt(i++, element)) { |
+ switch (element.type) { |
+ case WebHTTPBody::Element::TypeData: |
+ if (!element.data.isEmpty()) { |
+ // WebKit sometimes gives up empty data to append. These aren't |
+ // necessary so we just optimize those out here. |
+ request_body->AppendBytes( |
+ element.data.data(), static_cast<int>(element.data.size())); |
+ } |
+ break; |
+ case WebHTTPBody::Element::TypeFile: |
+ if (element.fileLength == -1) { |
+ request_body->AppendFileRange( |
+ base::FilePath::FromUTF16Unsafe(element.filePath), |
+ 0, kuint64max, base::Time()); |
+ } else { |
+ request_body->AppendFileRange( |
+ base::FilePath::FromUTF16Unsafe(element.filePath), |
+ static_cast<uint64>(element.fileStart), |
+ static_cast<uint64>(element.fileLength), |
+ base::Time::FromDoubleT(element.modificationTime)); |
+ } |
+ break; |
+ case WebHTTPBody::Element::TypeURL: { |
+ GURL url = GURL(element.url); |
+ DCHECK(url.SchemeIsFileSystem()); |
+ request_body->AppendFileSystemFileRange( |
+ url, |
+ static_cast<uint64>(element.fileStart), |
+ static_cast<uint64>(element.fileLength), |
+ base::Time::FromDoubleT(element.modificationTime)); |
+ break; |
+ } |
+ case WebHTTPBody::Element::TypeBlob: |
+ request_body->AppendBlob(GURL(element.blobURL)); |
+ break; |
+ default: |
+ NOTREACHED(); |
+ } |
} |
- case WebHTTPBody::Element::TypeBlob: |
- request_body->AppendBlob(GURL(element.blobURL)); |
- break; |
- default: |
- NOTREACHED(); |
- } |
+ request_body->set_identifier(request.httpBody().identifier()); |
+ bridge_->SetRequestBody(request_body.get()); |
+ } |
+ |
+ if (sync_load_response) { |
+ bridge_->SyncLoad(sync_load_response); |
+ return; |
+ } |
+ |
+ if (bridge_->Start(this)) { |
+ AddRef(); // Balanced in OnCompletedRequest |
+ } else { |
+ bridge_.reset(); |
} |
- request_body->set_identifier(request.httpBody().identifier()); |
- bridge_->SetRequestBody(request_body.get()); |
- } |
- |
- if (sync_load_response) { |
- bridge_->SyncLoad(sync_load_response); |
- return; |
- } |
- |
- if (bridge_->Start(this)) { |
- AddRef(); // Balanced in OnCompletedRequest |
- } else { |
- bridge_.reset(); |
- } |
} |
-void WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) { |
- if (client_) |
- client_->didSendData(loader_, position, size); |
+void WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) |
+{ |
+ if (client_) |
+ client_->didSendData(loader_, position, size); |
} |
bool WebURLLoaderImpl::Context::OnReceivedRedirect( |
const GURL& new_url, |
const ResourceResponseInfo& info, |
bool* has_new_first_party_for_cookies, |
- GURL* new_first_party_for_cookies) { |
- if (!client_) |
+ GURL* new_first_party_for_cookies) |
+{ |
+ if (!client_) |
+ return false; |
+ |
+ WebURLResponse response; |
+ response.initialize(); |
+ PopulateURLResponse(request_.url(), info, &response); |
+ |
+ // TODO(darin): We lack sufficient information to construct the actual |
+ // request that resulted from the redirect. |
+ WebURLRequest new_request(new_url); |
+ new_request.setFirstPartyForCookies(request_.firstPartyForCookies()); |
+ new_request.setDownloadToFile(request_.downloadToFile()); |
+ |
+ WebString referrer_string = WebString::fromUTF8("Referer"); |
+ WebString referrer = WebSecurityPolicy::generateReferrerHeader( |
+ referrer_policy_, |
+ new_url, |
+ request_.httpHeaderField(referrer_string)); |
+ if (!referrer.isEmpty()) |
+ new_request.setHTTPHeaderField(referrer_string, referrer); |
+ |
+ if (response.httpStatusCode() == 307) |
+ new_request.setHTTPMethod(request_.httpMethod()); |
+ |
+ client_->willSendRequest(loader_, new_request, response); |
+ request_ = new_request; |
+ *has_new_first_party_for_cookies = true; |
+ *new_first_party_for_cookies = request_.firstPartyForCookies(); |
+ |
+ // Only follow the redirect if WebKit left the URL unmodified. |
+ if (new_url == GURL(new_request.url())) |
+ return true; |
+ |
+ // We assume that WebKit only changes the URL to suppress a redirect, and we |
+ // assume that it does so by setting it to be invalid. |
+ DCHECK(!new_request.url().isValid()); |
return false; |
- |
- WebURLResponse response; |
- response.initialize(); |
- PopulateURLResponse(request_.url(), info, &response); |
- |
- // TODO(darin): We lack sufficient information to construct the actual |
- // request that resulted from the redirect. |
- WebURLRequest new_request(new_url); |
- new_request.setFirstPartyForCookies(request_.firstPartyForCookies()); |
- new_request.setDownloadToFile(request_.downloadToFile()); |
- |
- WebString referrer_string = WebString::fromUTF8("Referer"); |
- WebString referrer = WebSecurityPolicy::generateReferrerHeader( |
- referrer_policy_, |
- new_url, |
- request_.httpHeaderField(referrer_string)); |
- if (!referrer.isEmpty()) |
- new_request.setHTTPHeaderField(referrer_string, referrer); |
- |
- if (response.httpStatusCode() == 307) |
- new_request.setHTTPMethod(request_.httpMethod()); |
- |
- client_->willSendRequest(loader_, new_request, response); |
- request_ = new_request; |
- *has_new_first_party_for_cookies = true; |
- *new_first_party_for_cookies = request_.firstPartyForCookies(); |
- |
- // Only follow the redirect if WebKit left the URL unmodified. |
- if (new_url == GURL(new_request.url())) |
- return true; |
- |
- // We assume that WebKit only changes the URL to suppress a redirect, and we |
- // assume that it does so by setting it to be invalid. |
- DCHECK(!new_request.url().isValid()); |
- return false; |
} |
void WebURLLoaderImpl::Context::OnReceivedResponse( |
- const ResourceResponseInfo& info) { |
- if (!client_) |
- return; |
- |
- WebURLResponse response; |
- response.initialize(); |
- PopulateURLResponse(request_.url(), info, &response); |
- |
- bool show_raw_listing = (GURL(request_.url()).query() == "raw"); |
- |
- if (info.mime_type == "text/vnd.chromium.ftp-dir") { |
- if (show_raw_listing) { |
- // Set the MIME type to plain text to prevent any active content. |
- response.setMIMEType("text/plain"); |
- } else { |
- // We're going to produce a parsed listing in HTML. |
- response.setMIMEType("text/html"); |
+ const ResourceResponseInfo& info) |
+{ |
+ if (!client_) |
+ return; |
+ |
+ WebURLResponse response; |
+ response.initialize(); |
+ PopulateURLResponse(request_.url(), info, &response); |
+ |
+ bool show_raw_listing = (GURL(request_.url()).query() == "raw"); |
+ |
+ if (info.mime_type == "text/vnd.chromium.ftp-dir") { |
+ if (show_raw_listing) { |
+ // Set the MIME type to plain text to prevent any active content. |
+ response.setMIMEType("text/plain"); |
+ } else { |
+ // We're going to produce a parsed listing in HTML. |
+ response.setMIMEType("text/html"); |
+ } |
} |
- } |
- |
- scoped_refptr<Context> protect(this); |
- client_->didReceiveResponse(loader_, response); |
- |
- // We may have been cancelled after didReceiveResponse, which would leave us |
- // without a client and therefore without much need to do further handling. |
- if (!client_) |
- return; |
- |
- DCHECK(!ftp_listing_delegate_.get()); |
- DCHECK(!multipart_delegate_.get()); |
- if (info.headers.get() && info.mime_type == "multipart/x-mixed-replace") { |
- std::string content_type; |
- info.headers->EnumerateHeader(NULL, "content-type", &content_type); |
- |
- std::string mime_type; |
- std::string charset; |
- bool had_charset = false; |
- std::string boundary; |
- net::HttpUtil::ParseContentType(content_type, &mime_type, &charset, |
- &had_charset, &boundary); |
- TrimString(boundary, " \"", &boundary); |
- |
- // If there's no boundary, just handle the request normally. In the gecko |
- // code, nsMultiMixedConv::OnStartRequest throws an exception. |
- if (!boundary.empty()) { |
- multipart_delegate_.reset( |
- new MultipartResponseDelegate(client_, loader_, response, boundary)); |
+ |
+ scoped_refptr<Context> protect(this); |
+ client_->didReceiveResponse(loader_, response); |
+ |
+ // We may have been cancelled after didReceiveResponse, which would leave us |
+ // without a client and therefore without much need to do further handling. |
+ if (!client_) |
+ return; |
+ |
+ DCHECK(!ftp_listing_delegate_.get()); |
+ DCHECK(!multipart_delegate_.get()); |
+ if (info.headers.get() && info.mime_type == "multipart/x-mixed-replace") { |
+ std::string content_type; |
+ info.headers->EnumerateHeader(NULL, "content-type", &content_type); |
+ |
+ std::string mime_type; |
+ std::string charset; |
+ bool had_charset = false; |
+ std::string boundary; |
+ net::HttpUtil::ParseContentType(content_type, &mime_type, &charset, |
+ &had_charset, &boundary); |
+ TrimString(boundary, " \"", &boundary); |
+ |
+ // If there's no boundary, just handle the request normally. In the gecko |
+ // code, nsMultiMixedConv::OnStartRequest throws an exception. |
+ if (!boundary.empty()) { |
+ multipart_delegate_.reset( |
+ new MultipartResponseDelegate(client_, loader_, response, boundary)); |
+ } |
+ } else if (info.mime_type == "text/vnd.chromium.ftp-dir" && !show_raw_listing) { |
+ ftp_listing_delegate_.reset( |
+ new FtpDirectoryListingResponseDelegate(client_, loader_, response)); |
} |
- } else if (info.mime_type == "text/vnd.chromium.ftp-dir" && |
- !show_raw_listing) { |
- ftp_listing_delegate_.reset( |
- new FtpDirectoryListingResponseDelegate(client_, loader_, response)); |
- } |
+ |
+ response_url_ = response.url(); |
} |
-void WebURLLoaderImpl::Context::OnDownloadedData(int len) { |
- if (client_) |
- client_->didDownloadData(loader_, len); |
+void WebURLLoaderImpl::Context::OnDownloadedData(int len) |
+{ |
+ if (client_) |
+ client_->didDownloadData(loader_, len); |
} |
void WebURLLoaderImpl::Context::OnReceivedData(const char* data, |
int data_length, |
- int encoded_data_length) { |
- if (!client_) |
- return; |
- |
- if (ftp_listing_delegate_) { |
- // The FTP listing delegate will make the appropriate calls to |
- // client_->didReceiveData and client_->didReceiveResponse. |
- ftp_listing_delegate_->OnReceivedData(data, data_length); |
- } else if (multipart_delegate_) { |
- // The multipart delegate will make the appropriate calls to |
- // client_->didReceiveData and client_->didReceiveResponse. |
- multipart_delegate_->OnReceivedData(data, data_length, encoded_data_length); |
- } else { |
- client_->didReceiveData(loader_, data, data_length, encoded_data_length); |
- } |
+ int encoded_data_length) |
+{ |
+ if (!client_) |
+ return; |
+ |
+ if (ftp_listing_delegate_) { |
+ // The FTP listing delegate will make the appropriate calls to |
+ // client_->didReceiveData and client_->didReceiveResponse. |
+ ftp_listing_delegate_->OnReceivedData(data, data_length); |
+ } else if (multipart_delegate_) { |
+ // The multipart delegate will make the appropriate calls to |
+ // client_->didReceiveData and client_->didReceiveResponse. |
+ multipart_delegate_->OnReceivedData(data, data_length, encoded_data_length); |
+ } else { |
+ client_->didReceiveData(loader_, data, data_length, encoded_data_length); |
+ } |
+ |
+ // TODO(dsjang): This logging code is just temporary. There has to |
+ // be a better way to connect the received data to the response_url |
+ // than this. |
+ SiteIsolationPolicy::DidReceiveData(data, data_length, response_url_); |
} |
void WebURLLoaderImpl::Context::OnReceivedCachedMetadata( |
- const char* data, int len) { |
- if (client_) |
- client_->didReceiveCachedMetadata(loader_, data, len); |
+ const char* data, int len) |
+{ |
+ if (client_) |
+ client_->didReceiveCachedMetadata(loader_, data, len); |
} |
void WebURLLoaderImpl::Context::OnCompletedRequest( |
int error_code, |
bool was_ignored_by_handler, |
const std::string& security_info, |
- const base::TimeTicks& completion_time) { |
- if (ftp_listing_delegate_) { |
- ftp_listing_delegate_->OnCompletedRequest(); |
- ftp_listing_delegate_.reset(NULL); |
- } else if (multipart_delegate_) { |
- multipart_delegate_->OnCompletedRequest(); |
- multipart_delegate_.reset(NULL); |
- } |
- |
- // Prevent any further IPC to the browser now that we're complete, but |
- // don't delete it to keep any downloaded temp files alive. |
- DCHECK(!completed_bridge_.get()); |
- completed_bridge_.swap(bridge_); |
- |
- if (client_) { |
- if (error_code != net::OK) { |
- client_->didFail(loader_, CreateError(request_.url(), error_code)); |
- } else { |
- client_->didFinishLoading( |
- loader_, (completion_time - TimeTicks()).InSecondsF()); |
+ const base::TimeTicks& completion_time) |
+{ |
+ if (ftp_listing_delegate_) { |
+ ftp_listing_delegate_->OnCompletedRequest(); |
+ ftp_listing_delegate_.reset(NULL); |
+ } else if (multipart_delegate_) { |
+ multipart_delegate_->OnCompletedRequest(); |
+ multipart_delegate_.reset(NULL); |
+ } |
+ |
+ // Prevent any further IPC to the browser now that we're complete, but |
+ // don't delete it to keep any downloaded temp files alive. |
+ DCHECK(!completed_bridge_.get()); |
+ completed_bridge_.swap(bridge_); |
+ |
+ if (client_) { |
+ if (error_code != net::OK) { |
+ client_->didFail(loader_, CreateError(request_.url(), error_code)); |
+ } else { |
+ client_->didFinishLoading( |
+ loader_, (completion_time - TimeTicks()).InSecondsF()); |
+ } |
} |
- } |
- // We are done with the bridge now, and so we need to release the reference |
- // to ourselves that we took on behalf of the bridge. This may cause our |
- // destruction. |
- Release(); |
+ // TODO(dsjang): This logging code is just temporary. There has to |
+ // be a better way to connect the received data to the response_url |
+ // than this. |
+ SiteIsolationPolicy::DidFinishResourceLoad(response_url_); |
+ |
+ // We are done with the bridge now, and so we need to release the reference |
+ // to ourselves that we took on behalf of the bridge. This may cause our |
+ // destruction. |
+ Release(); |
} |
-bool WebURLLoaderImpl::Context::CanHandleDataURL(const GURL& url) const { |
- DCHECK(url.SchemeIs("data")); |
+bool WebURLLoaderImpl::Context::CanHandleDataURL(const GURL& url) const |
+{ |
+ DCHECK(url.SchemeIs("data")); |
- // Optimize for the case where we can handle a data URL locally. We must |
- // skip this for data URLs targetted at frames since those could trigger a |
- // download. |
- // |
- // NOTE: We special case MIME types we can render both for performance |
- // reasons as well as to support unit tests, which do not have an underlying |
- // ResourceLoaderBridge implementation. |
+// Optimize for the case where we can handle a data URL locally. We must |
+// skip this for data URLs targetted at frames since those could trigger a |
+// download. |
+// |
+// NOTE: We special case MIME types we can render both for performance |
+// reasons as well as to support unit tests, which do not have an underlying |
+// ResourceLoaderBridge implementation. |
#if defined(OS_ANDROID) |
- // For compatibility reasons on Android we need to expose top-level data:// |
- // to the browser. |
- if (request_.targetType() == WebURLRequest::TargetIsMainFrame) |
- return false; |
+ // For compatibility reasons on Android we need to expose top-level data:// |
+ // to the browser. |
+ if (request_.targetType() == WebURLRequest::TargetIsMainFrame) |
+ return false; |
#endif |
- if (request_.targetType() != WebURLRequest::TargetIsMainFrame && |
- request_.targetType() != WebURLRequest::TargetIsSubframe) |
- return true; |
+ if (request_.targetType() != WebURLRequest::TargetIsMainFrame && request_.targetType() != WebURLRequest::TargetIsSubframe) |
+ return true; |
- std::string mime_type, unused_charset; |
- if (net::DataURL::Parse(url, &mime_type, &unused_charset, NULL) && |
- net::IsSupportedMimeType(mime_type)) |
- return true; |
+ std::string mime_type, unused_charset; |
+ if (net::DataURL::Parse(url, &mime_type, &unused_charset, NULL) && net::IsSupportedMimeType(mime_type)) |
+ return true; |
- return false; |
+ return false; |
} |
-void WebURLLoaderImpl::Context::HandleDataURL() { |
- ResourceResponseInfo info; |
- int error_code; |
- std::string data; |
+void WebURLLoaderImpl::Context::HandleDataURL() |
+{ |
+ ResourceResponseInfo info; |
+ int error_code; |
+ std::string data; |
- if (GetInfoFromDataURL(request_.url(), &info, &data, &error_code)) { |
- OnReceivedResponse(info); |
- if (!data.empty()) |
- OnReceivedData(data.data(), data.size(), 0); |
- } |
+ if (GetInfoFromDataURL(request_.url(), &info, &data, &error_code)) { |
+ OnReceivedResponse(info); |
+ if (!data.empty()) |
+ OnReceivedData(data.data(), data.size(), 0); |
+ } |
- OnCompletedRequest(error_code, false, info.security_info, |
- base::TimeTicks::Now()); |
+ OnCompletedRequest(error_code, false, info.security_info, |
+ base::TimeTicks::Now()); |
} |
// WebURLLoaderImpl ----------------------------------------------------------- |
WebURLLoaderImpl::WebURLLoaderImpl(WebKitPlatformSupportImpl* platform) |
- : context_(new Context(this)), |
- platform_(platform) { |
+ : context_(new Context(this)) |
+ , platform_(platform) |
+{ |
} |
-WebURLLoaderImpl::~WebURLLoaderImpl() { |
- cancel(); |
+WebURLLoaderImpl::~WebURLLoaderImpl() |
+{ |
+ cancel(); |
} |
WebURLError WebURLLoaderImpl::CreateError(const WebURL& unreachable_url, |
- int reason) { |
- WebURLError error; |
- error.domain = WebString::fromUTF8(net::kErrorDomain); |
- error.reason = reason; |
- error.unreachableURL = unreachable_url; |
- if (reason == net::ERR_ABORTED) { |
- error.isCancellation = true; |
- } else if (reason == net::ERR_TEMPORARILY_THROTTLED) { |
- error.localizedDescription = WebString::fromUTF8( |
- kThrottledErrorDescription); |
- } |
- return error; |
+ int reason) |
+{ |
+ WebURLError error; |
+ error.domain = WebString::fromUTF8(net::kErrorDomain); |
+ error.reason = reason; |
+ error.unreachableURL = unreachable_url; |
+ if (reason == net::ERR_ABORTED) { |
+ error.isCancellation = true; |
+ } else if (reason == net::ERR_TEMPORARILY_THROTTLED) { |
+ error.localizedDescription = WebString::fromUTF8( |
+ kThrottledErrorDescription); |
+ } |
+ return error; |
} |
void WebURLLoaderImpl::loadSynchronously(const WebURLRequest& request, |
WebURLResponse& response, |
WebURLError& error, |
- WebData& data) { |
- ResourceLoaderBridge::SyncLoadResponse sync_load_response; |
- context_->Start(request, &sync_load_response, platform_); |
+ WebData& data) |
+{ |
+ ResourceLoaderBridge::SyncLoadResponse sync_load_response; |
+ context_->Start(request, &sync_load_response, platform_); |
- const GURL& final_url = sync_load_response.url; |
+ const GURL& final_url = sync_load_response.url; |
- // TODO(tc): For file loads, we may want to include a more descriptive |
- // status code or status text. |
- int error_code = sync_load_response.error_code; |
- if (error_code != net::OK) { |
- response.setURL(final_url); |
- error.domain = WebString::fromUTF8(net::kErrorDomain); |
- error.reason = error_code; |
- error.unreachableURL = final_url; |
- return; |
- } |
+ // TODO(tc): For file loads, we may want to include a more descriptive |
+ // status code or status text. |
+ int error_code = sync_load_response.error_code; |
+ if (error_code != net::OK) { |
+ response.setURL(final_url); |
+ error.domain = WebString::fromUTF8(net::kErrorDomain); |
+ error.reason = error_code; |
+ error.unreachableURL = final_url; |
+ return; |
+ } |
- PopulateURLResponse(final_url, sync_load_response, &response); |
+ PopulateURLResponse(final_url, sync_load_response, &response); |
- data.assign(sync_load_response.data.data(), |
- sync_load_response.data.size()); |
+ data.assign(sync_load_response.data.data(), |
+ sync_load_response.data.size()); |
} |
void WebURLLoaderImpl::loadAsynchronously(const WebURLRequest& request, |
- WebURLLoaderClient* client) { |
- DCHECK(!context_->client()); |
+ WebURLLoaderClient* client) |
+{ |
+ DCHECK(!context_->client()); |
- context_->set_client(client); |
- context_->Start(request, NULL, platform_); |
+ context_->set_client(client); |
+ context_->Start(request, NULL, platform_); |
} |
-void WebURLLoaderImpl::cancel() { |
- context_->Cancel(); |
+void WebURLLoaderImpl::cancel() |
+{ |
+ context_->Cancel(); |
} |
-void WebURLLoaderImpl::setDefersLoading(bool value) { |
- context_->SetDefersLoading(value); |
+void WebURLLoaderImpl::setDefersLoading(bool value) |
+{ |
+ context_->SetDefersLoading(value); |
} |
-void WebURLLoaderImpl::didChangePriority(WebURLRequest::Priority new_priority) { |
- context_->DidChangePriority(new_priority); |
+void WebURLLoaderImpl::didChangePriority(WebURLRequest::Priority new_priority) |
+{ |
+ context_->DidChangePriority(new_priority); |
} |
-} // namespace webkit_glue |
+} // namespace webkit_glue |