172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// An implementation of WebURLLoader in terms of ResourceLoaderBridge. 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/weburlloader_impl.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h" 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/process_util.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/data_url.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/load_flags.h" 1721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/mime_util.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_errors.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_response_headers.h" 2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebHTTPHeaderVisitor.h" 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebHTTPLoadInfo.h" 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h" 2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h" 2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h" 2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoadTiming.h" 2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderClient.h" 2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/ftp_directory_listing_response_delegate.h" 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/multipart_response_delegate.h" 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/resource_loader_bridge.h" 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/site_isolation_metrics.h" 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/webkit_glue.h" 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time; 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta; 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebData; 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebHTTPBody; 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebHTTPHeaderVisitor; 41201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochusing WebKit::WebHTTPLoadInfo; 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebSecurityPolicy; 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebString; 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURL; 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLError; 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLLoadTiming; 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLLoader; 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLLoaderClient; 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLRequest; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLResponse; 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace webkit_glue { 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Utilities ------------------------------------------------------------------ 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass HeaderFlattener : public WebHTTPHeaderVisitor { 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit HeaderFlattener(int load_flags) 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : load_flags_(load_flags), 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch has_accept_header_(false) { 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void visitHeader(const WebString& name, const WebString& value) { 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(darin): is UTF-8 really correct here? It is if the strings are 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // already ASCII (i.e., if they are already escaped properly). 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& name_utf8 = name.utf8(); 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& value_utf8 = value.utf8(); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Skip over referrer headers found in the header map because we already 7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // pulled it out as a separate parameter. 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (LowerCaseEqualsASCII(name_utf8, "referer")) 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Skip over "Cache-Control: max-age=0" header if the corresponding 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // load flag is already specified. FrameLoader sets both the flag and 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the extra header -- the extra header is redundant since our network 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // implementation will add the necessary headers based on load flags. 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // See http://code.google.com/p/chromium/issues/detail?id=3434. 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((load_flags_ & net::LOAD_VALIDATE_CACHE) && 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LowerCaseEqualsASCII(name_utf8, "cache-control") && 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LowerCaseEqualsASCII(value_utf8, "max-age=0")) 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (LowerCaseEqualsASCII(name_utf8, "accept")) 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch has_accept_header_ = true; 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!buffer_.empty()) 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buffer_.append("\r\n"); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buffer_.append(name_utf8 + ": " + value_utf8); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& GetBuffer() { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // In some cases, WebKit doesn't add an Accept header, but not having the 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // header confuses some web servers. See bug 808613. 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!has_accept_header_) { 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!buffer_.empty()) 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buffer_.append("\r\n"); 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buffer_.append("Accept: */*"); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch has_accept_header_ = true; 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return buffer_; 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int load_flags_; 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string buffer_; 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool has_accept_header_; 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochResourceType::Type FromTargetType(WebURLRequest::TargetType type) { 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (type) { 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsMainFrame: 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::MAIN_FRAME; 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsSubframe: 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::SUB_FRAME; 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsSubresource: 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::SUB_RESOURCE; 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsStyleSheet: 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::STYLESHEET; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsScript: 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::SCRIPT; 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsFontResource: 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::FONT_RESOURCE; 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsImage: 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::IMAGE; 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsObject: 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::OBJECT; 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsMedia: 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::MEDIA; 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsWorker: 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::WORKER; 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsSharedWorker: 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::SHARED_WORKER; 1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case WebURLRequest::TargetIsPrefetch: 1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ResourceType::PREFETCH; 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case WebURLRequest::TargetIsFavicon: 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return ResourceType::FAVICON; 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::SUB_RESOURCE; 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Extracts the information from a data: url. 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool GetInfoFromDataURL(const GURL& url, 148731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ResourceResponseInfo* info, 14972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string* data, 15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::URLRequestStatus* status) { 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string mime_type; 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string charset; 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (net::DataURL::Parse(url, &mime_type, &charset, data)) { 15472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *status = net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info->request_time = Time::Now(); 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info->response_time = Time::Now(); 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info->headers = NULL; 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info->mime_type.swap(mime_type); 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info->charset.swap(charset); 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info->security_info.clear(); 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info->content_length = -1; 162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen info->encoded_data_length = 0; 163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen info->load_timing.base_time = Time::Now(); 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *status = net::URLRequestStatus(net::URLRequestStatus::FAILED, 16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::ERR_INVALID_URL); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 173731df977c0511bca2206b5f333555b1205ff1f43Iain Merricktypedef ResourceDevToolsInfo::HeadersVector HeadersVector; 174731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PopulateURLResponse( 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, 177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ResourceResponseInfo& info, 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLResponse* response) { 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setURL(url); 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setResponseTime(info.response_time.ToDoubleT()); 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setMIMEType(WebString::fromUTF8(info.mime_type)); 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setTextEncodingName(WebString::fromUTF8(info.charset)); 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setExpectedContentLength(info.content_length); 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setSecurityInfo(info.security_info); 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setAppCacheID(info.appcache_id); 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setAppCacheManifestURL(info.appcache_manifest_url); 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setWasCached(!info.load_timing.base_time.is_null() && 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info.response_time < info.load_timing.base_time); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setWasFetchedViaSPDY(info.was_fetched_via_spdy); 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setWasNpnNegotiated(info.was_npn_negotiated); 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setWasAlternateProtocolAvailable( 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info.was_alternate_protocol_available); 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setWasFetchedViaProxy(info.was_fetched_via_proxy); 194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen response->setRemoteIPAddress( 195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen WebString::fromUTF8(info.socket_address.host())); 196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen response->setRemotePort(info.socket_address.port()); 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setConnectionID(info.connection_id); 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setConnectionReused(info.connection_reused); 1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick response->setDownloadFilePath(FilePathToWebString(info.download_file_path)); 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ResourceLoadTimingInfo& timing_info = info.load_timing; 202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!timing_info.base_time.is_null()) { 203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen WebURLLoadTiming timing; 204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen timing.initialize(); 205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen timing.setRequestTime(timing_info.base_time.ToDoubleT()); 206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen timing.setProxyStart(timing_info.proxy_start); 207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen timing.setProxyEnd(timing_info.proxy_end); 208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen timing.setDNSStart(timing_info.dns_start); 209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen timing.setDNSEnd(timing_info.dns_end); 210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen timing.setConnectStart(timing_info.connect_start); 211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen timing.setConnectEnd(timing_info.connect_end); 212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen timing.setSSLStart(timing_info.ssl_start); 213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen timing.setSSLEnd(timing_info.ssl_end); 214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen timing.setSendStart(timing_info.send_start); 215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen timing.setSendEnd(timing_info.send_end); 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen timing.setReceiveHeadersEnd(timing_info.receive_headers_end); 217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen response->setLoadTiming(timing); 218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (info.devtools_info.get()) { 221201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch WebHTTPLoadInfo load_info; 222201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 223201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch load_info.setHTTPStatusCode(info.devtools_info->http_status_code); 224201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch load_info.setHTTPStatusText(WebString::fromUTF8( 225201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch info.devtools_info->http_status_text)); 226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen load_info.setEncodedDataLength(info.encoded_data_length); 227731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 228731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const HeadersVector& request_headers = info.devtools_info->request_headers; 229201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (HeadersVector::const_iterator it = request_headers.begin(); 230731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick it != request_headers.end(); ++it) { 231201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch load_info.addRequestHeader(WebString::fromUTF8(it->first), 232731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WebString::fromUTF8(it->second)); 233731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 234731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const HeadersVector& response_headers = 235731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick info.devtools_info->response_headers; 236731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (HeadersVector::const_iterator it = response_headers.begin(); 237731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick it != response_headers.end(); ++it) { 238201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch load_info.addResponseHeader(WebString::fromUTF8(it->first), 239731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WebString::fromUTF8(it->second)); 240731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 241201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch response->setHTTPLoadInfo(load_info); 242731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 243731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const net::HttpResponseHeaders* headers = info.headers; 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!headers) 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setHTTPStatusCode(headers->response_code()); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setHTTPStatusText(WebString::fromUTF8(headers->GetStatusText())); 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(darin): We should leverage HttpResponseHeaders for this, and this 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // should be using the same code as ResourceDispatcherHost. 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(jungshik): Figure out the actual value of the referrer charset and 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // pass it to GetSuggestedFilename. 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string value; 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (headers->EnumerateHeader(NULL, "content-disposition", &value)) { 25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response->setSuggestedFileName( 25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::GetSuggestedFilename(url, value, "", string16())); 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time time_val; 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (headers->GetLastModifiedValue(&time_val)) 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setLastModifiedDate(time_val.ToDoubleT()); 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Build up the header map. 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void* iter = NULL; 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string name; 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (headers->EnumerateHeaderLines(&iter, &name, &value)) { 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->addHTTPHeaderField(WebString::fromUTF8(name), 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebString::fromUTF8(value)); 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// WebURLLoaderImpl::Context -------------------------------------------------- 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This inner class exists since the WebURLLoader may be deleted while inside a 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// call to WebURLLoaderClient. The bridge requires its Peer to stay alive 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// until it receives OnCompletedRequest. 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass WebURLLoaderImpl::Context : public base::RefCounted<Context>, 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public ResourceLoaderBridge::Peer { 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit Context(WebURLLoaderImpl* loader); 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLLoaderClient* client() const { return client_; } 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_client(WebURLLoaderClient* client) { client_ = client; } 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Cancel(); 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void SetDefersLoading(bool value); 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Start( 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const WebURLRequest& request, 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResourceLoaderBridge::SyncLoadResponse* sync_load_response); 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ResourceLoaderBridge::Peer methods: 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnUploadProgress(uint64 position, uint64 size); 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool OnReceivedRedirect( 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& new_url, 299731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ResourceResponseInfo& info, 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool* has_new_first_party_for_cookies, 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL* new_first_party_for_cookies); 302dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen virtual void OnReceivedResponse(const ResourceResponseInfo& info); 3033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void OnDownloadedData(int len); 304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void OnReceivedData(const char* data, 305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int data_length, 306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int encoded_data_length); 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnReceivedCachedMetadata(const char* data, int len); 30872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void OnCompletedRequest(const net::URLRequestStatus& status, 30972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& security_info, 31072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const base::Time& completion_time); 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend class base::RefCounted<Context>; 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~Context() {} 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // We can optimize the handling of data URLs in most cases. 31721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bool CanHandleDataURL(const GURL& url) const; 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void HandleDataURL(); 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLLoaderImpl* loader_; 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLRequest request_; 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLLoaderClient* client_; 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<ResourceLoaderBridge> bridge_; 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_; 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<MultipartResponseDelegate> multipart_delegate_; 3263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<ResourceLoaderBridge> completed_bridge_; 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(japhet): Storing this is a temporary hack for site isolation logging. 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURL response_url_; 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebURLLoaderImpl::Context::Context(WebURLLoaderImpl* loader) 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : loader_(loader), 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_(NULL) { 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::Cancel() { 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The bridge will still send OnCompletedRequest, which will Release() us, so 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we don't do that here. 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (bridge_.get()) 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_->Cancel(); 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Ensure that we do not notify the multipart delegate anymore as it has 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // its own pointer to the client. 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (multipart_delegate_.get()) 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch multipart_delegate_->Cancel(); 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Do not make any further calls to the client. 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_ = NULL; 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch loader_ = NULL; 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::SetDefersLoading(bool value) { 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (bridge_.get()) 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_->SetDefersLoading(value); 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::Start( 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const WebURLRequest& request, 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResourceLoaderBridge::SyncLoadResponse* sync_load_response) { 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!bridge_.get()); 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_ = request; // Save the request. 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url = request.url(); 36621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (url.SchemeIs("data") && CanHandleDataURL(url)) { 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (sync_load_response) { 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This is a sync load. Do the work now. 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_load_response->url = url; 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string data; 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetInfoFromDataURL(sync_load_response->url, sync_load_response, 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &sync_load_response->data, 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &sync_load_response->status); 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddRef(); // Balanced in OnCompletedRequest 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->PostTask(FROM_HERE, 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewRunnableMethod(this, &Context::HandleDataURL)); 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL referrer_url( 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.httpHeaderField(WebString::fromUTF8("Referer")).utf8()); 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& method = request.httpMethod().utf8(); 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int load_flags = net::LOAD_NORMAL; 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (request.cachePolicy()) { 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::ReloadIgnoringCacheData: 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Required by LayoutTests/http/tests/misc/refresh-headers.php 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_VALIDATE_CACHE; 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::ReturnCacheDataElseLoad: 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_PREFERRING_CACHE; 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::ReturnCacheDataDontLoad: 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_ONLY_FROM_CACHE; 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::UseProtocolCachePolicy: 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (request.reportUploadProgress()) 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_ENABLE_UPLOAD_PROGRESS; 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (request.reportLoadTiming()) 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_ENABLE_LOAD_TIMING; 406731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (request.reportRawHeaders()) 407731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick load_flags |= net::LOAD_REPORT_RAW_HEADERS; 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!request.allowCookies() || !request.allowStoredCredentials()) { 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES; 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_DO_NOT_SEND_COOKIES; 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!request.allowStoredCredentials()) 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA; 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HeaderFlattener flattener(load_flags); 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.visitHTTPHeaderFields(&flattener); 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(abarth): These are wrong! I need to figure out how to get the right 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // strings here. See: http://crbug.com/8706 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string frame_origin = request.firstPartyForCookies().spec(); 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string main_frame_origin = request.firstPartyForCookies().spec(); 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(brettw) this should take parameter encoding into account when 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // creating the GURLs. 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ResourceLoaderBridge::RequestInfo request_info; 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.method = method; 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.url = url; 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.first_party_for_cookies = request.firstPartyForCookies(); 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.referrer = referrer_url; 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.frame_origin = frame_origin; 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.main_frame_origin = main_frame_origin; 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.headers = flattener.GetBuffer(); 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.load_flags = load_flags; 43772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // requestor_pid only needs to be non-zero if the request originates outside 43872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // the render process, so we can use requestorProcessID even for requests 43972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // from in-process plugins. 44072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen request_info.requestor_pid = request.requestorProcessID(); 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.request_type = FromTargetType(request.targetType()); 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.appcache_host_id = request.appCacheHostID(); 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.routing_id = request.requestorID(); 4443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request_info.download_to_file = request.downloadToFile(); 44521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_info.has_user_gesture = request.hasUserGesture(); 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_.reset(ResourceLoaderBridge::Create(request_info)); 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!request.httpBody().isNull()) { 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // GET and HEAD requests shouldn't have http bodies. 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(method != "GET" && method != "HEAD"); 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const WebHTTPBody& httpBody = request.httpBody(); 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t i = 0; 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebHTTPBody::Element element; 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (httpBody.elementAt(i++, element)) { 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (element.type) { 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebHTTPBody::Element::TypeData: 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!element.data.isEmpty()) { 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // WebKit sometimes gives up empty data to append. These aren't 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // necessary so we just optimize those out here. 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_->AppendDataToUpload( 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch element.data.data(), static_cast<int>(element.data.size())); 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebHTTPBody::Element::TypeFile: 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (element.fileLength == -1) { 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_->AppendFileToUpload( 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebStringToFilePath(element.filePath)); 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_->AppendFileRangeToUpload( 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebStringToFilePath(element.filePath), 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<uint64>(element.fileStart), 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<uint64>(element.fileLength), 4733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::Time::FromDoubleT(element.modificationTime)); 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 4763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case WebHTTPBody::Element::TypeBlob: 4773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bridge_->AppendBlobToUpload(GURL(element.blobURL)); 4783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_->SetUploadIdentifier(request.httpBody().identifier()); 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (sync_load_response) { 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_->SyncLoad(sync_load_response); 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (bridge_->Start(this)) { 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddRef(); // Balanced in OnCompletedRequest 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_.reset(); 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) { 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (client_) 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_->didSendData(loader_, position, size); 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WebURLLoaderImpl::Context::OnReceivedRedirect( 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& new_url, 505731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ResourceResponseInfo& info, 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool* has_new_first_party_for_cookies, 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL* new_first_party_for_cookies) { 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!client_) 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLResponse response; 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response.initialize(); 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PopulateURLResponse(request_.url(), info, &response); 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(darin): We lack sufficient information to construct the actual 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // request that resulted from the redirect. 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLRequest new_request(new_url); 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_request.setFirstPartyForCookies(request_.firstPartyForCookies()); 519731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new_request.setDownloadToFile(request_.downloadToFile()); 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebString referrer_string = WebString::fromUTF8("Referer"); 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebString referrer = request_.httpHeaderField(referrer_string); 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!WebSecurityPolicy::shouldHideReferrer(new_url, referrer)) 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_request.setHTTPHeaderField(referrer_string, referrer); 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (response.httpStatusCode() == 307) 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_request.setHTTPMethod(request_.httpMethod()); 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_->willSendRequest(loader_, new_request, response); 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_ = new_request; 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *has_new_first_party_for_cookies = true; 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *new_first_party_for_cookies = request_.firstPartyForCookies(); 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Only follow the redirect if WebKit left the URL unmodified. 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (new_url == GURL(new_request.url())) 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We assume that WebKit only changes the URL to suppress a redirect, and we 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // assume that it does so by setting it to be invalid. 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!new_request.url().isValid()); 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::OnReceivedResponse( 545dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const ResourceResponseInfo& info) { 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!client_) 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLResponse response; 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response.initialize(); 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PopulateURLResponse(request_.url(), info, &response); 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool show_raw_listing = (GURL(request_.url()).query() == "raw"); 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (info.mime_type == "text/vnd.chromium.ftp-dir") { 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (show_raw_listing) { 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set the MIME type to plain text to prevent any active content. 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response.setMIMEType("text/plain"); 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We're going to produce a parsed listing in HTML. 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response.setMIMEType("text/html"); 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_->didReceiveResponse(loader_, response); 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We may have been cancelled after didReceiveResponse, which would leave us 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // without a client and therefore without much need to do further handling. 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!client_) 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!ftp_listing_delegate_.get()); 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!multipart_delegate_.get()); 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (info.headers && info.mime_type == "multipart/x-mixed-replace") { 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string content_type; 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info.headers->EnumerateHeader(NULL, "content-type", &content_type); 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 578513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string boundary = net::GetHeaderParamValue( 579513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch content_type, "boundary", net::QuoteRule::REMOVE_OUTER_QUOTES); 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TrimString(boundary, " \"", &boundary); 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If there's no boundary, just handle the request normally. In the gecko 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // code, nsMultiMixedConv::OnStartRequest throws an exception. 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!boundary.empty()) { 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch multipart_delegate_.reset( 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new MultipartResponseDelegate(client_, loader_, response, boundary)); 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (info.mime_type == "text/vnd.chromium.ftp-dir" && 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !show_raw_listing) { 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ftp_listing_delegate_.reset( 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new FtpDirectoryListingResponseDelegate(client_, loader_, response)); 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response_url_ = response.url(); 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid WebURLLoaderImpl::Context::OnDownloadedData(int len) { 5983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (client_) 5993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick client_->didDownloadData(loader_, len); 6003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid WebURLLoaderImpl::Context::OnReceivedData(const char* data, 603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int data_length, 604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int encoded_data_length) { 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!client_) 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Temporary logging, see site_isolation_metrics.h/cc. 609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SiteIsolationMetrics::SniffCrossOriginHTML(response_url_, data, data_length); 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ftp_listing_delegate_.get()) { 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The FTP listing delegate will make the appropriate calls to 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // client_->didReceiveData and client_->didReceiveResponse. 614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ftp_listing_delegate_->OnReceivedData(data, data_length); 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (multipart_delegate_.get()) { 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The multipart delegate will make the appropriate calls to 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // client_->didReceiveData and client_->didReceiveResponse. 618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen multipart_delegate_->OnReceivedData(data, data_length, encoded_data_length); 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 620ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen client_->didReceiveData(loader_, data, data_length, encoded_data_length); 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::OnReceivedCachedMetadata( 625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* data, int len) { 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (client_) 627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_->didReceiveCachedMetadata(loader_, data, len); 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::OnCompletedRequest( 63172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const net::URLRequestStatus& status, 6323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& security_info, 6333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const base::Time& completion_time) { 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ftp_listing_delegate_.get()) { 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ftp_listing_delegate_->OnCompletedRequest(); 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ftp_listing_delegate_.reset(NULL); 637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (multipart_delegate_.get()) { 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch multipart_delegate_->OnCompletedRequest(); 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch multipart_delegate_.reset(NULL); 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Prevent any further IPC to the browser now that we're complete, but 6433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // don't delete it to keep any downloaded temp files alive. 6443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(!completed_bridge_.get()); 6453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick completed_bridge_.swap(bridge_); 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (client_) { 64872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (status.status() != net::URLRequestStatus::SUCCESS) { 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int error_code; 65072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (status.status() == net::URLRequestStatus::HANDLED_EXTERNALLY) { 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // By marking this request as aborted we insure that we don't navigate 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to an error page. 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_code = net::ERR_ABORTED; 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_code = status.os_error(); 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLError error; 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error.domain = WebString::fromUTF8(net::kErrorDomain); 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error.reason = error_code; 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error.unreachableURL = request_.url(); 661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_->didFail(loader_, error); 662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 6633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick client_->didFinishLoading(loader_, completion_time.ToDoubleT()); 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Temporary logging, see site_isolation_metrics.h/cc 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SiteIsolationMetrics::RemoveCompletedResponse(response_url_); 669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We are done with the bridge now, and so we need to release the reference 671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to ourselves that we took on behalf of the bridge. This may cause our 672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // destruction. 673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Release(); 674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool WebURLLoaderImpl::Context::CanHandleDataURL(const GURL& url) const { 67721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(url.SchemeIs("data")); 67821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 67921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Optimize for the case where we can handle a data URL locally. We must 68021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // skip this for data URLs targetted at frames since those could trigger a 68121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // download. 68221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // 68321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // NOTE: We special case MIME types we can render both for performance 68421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // reasons as well as to support unit tests, which do not have an underlying 68521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // ResourceLoaderBridge implementation. 68621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 68721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (request_.targetType() != WebURLRequest::TargetIsMainFrame && 68821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_.targetType() != WebURLRequest::TargetIsSubframe) 68921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return true; 69021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 69121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string mime_type, unused_charset; 69221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (net::DataURL::Parse(url, &mime_type, &unused_charset, NULL) && 69321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::IsSupportedMimeType(mime_type)) 69421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return true; 69521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 69621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 69721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 69821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::HandleDataURL() { 700731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ResourceResponseInfo info; 70172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::URLRequestStatus status; 702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string data; 703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GetInfoFromDataURL(request_.url(), &info, &data, &status)) { 705dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen OnReceivedResponse(info); 706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!data.empty()) 707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen OnReceivedData(data.data(), data.size(), 0); 708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick OnCompletedRequest(status, info.security_info, base::Time::Now()); 711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// WebURLLoaderImpl ----------------------------------------------------------- 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebURLLoaderImpl::WebURLLoaderImpl() 716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : ALLOW_THIS_IN_INITIALIZER_LIST(context_(new Context(this))) { 717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 719c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebURLLoaderImpl::~WebURLLoaderImpl() { 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cancel(); 721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::loadSynchronously(const WebURLRequest& request, 724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLResponse& response, 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLError& error, 726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebData& data) { 727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResourceLoaderBridge::SyncLoadResponse sync_load_response; 728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch context_->Start(request, &sync_load_response); 729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& final_url = sync_load_response.url; 731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(tc): For file loads, we may want to include a more descriptive 733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // status code or status text. 73472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const net::URLRequestStatus::Status& status = 73572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sync_load_response.status.status(); 73672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (status != net::URLRequestStatus::SUCCESS && 73772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen status != net::URLRequestStatus::HANDLED_EXTERNALLY) { 738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response.setURL(final_url); 739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error.domain = WebString::fromUTF8(net::kErrorDomain); 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error.reason = sync_load_response.status.os_error(); 741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error.unreachableURL = final_url; 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PopulateURLResponse(final_url, sync_load_response, &response); 746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data.assign(sync_load_response.data.data(), 748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_load_response.data.size()); 749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::loadAsynchronously(const WebURLRequest& request, 752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLLoaderClient* client) { 753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!context_->client()); 754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch context_->set_client(client); 756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch context_->Start(request, NULL); 757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::cancel() { 760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch context_->Cancel(); 761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::setDefersLoading(bool value) { 764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch context_->SetDefersLoading(value); 765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace webkit_glue 768