weburlloader_impl.cc revision 21d179b334e59e9a3bfcaed4c4430bef1bc5759d
1513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Copyright (c) 2010 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" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/process_util.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/scoped_ptr.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" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/WebKit/WebKit/chromium/public/WebHTTPHeaderVisitor.h" 22201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "third_party/WebKit/WebKit/chromium/public/WebHTTPLoadInfo.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/WebKit/WebKit/chromium/public/WebSecurityPolicy.h" 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/WebKit/WebKit/chromium/public/WebURL.h" 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/WebKit/WebKit/chromium/public/WebURLError.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/WebKit/WebKit/chromium/public/WebURLLoadTiming.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/WebKit/WebKit/chromium/public/WebURLLoaderClient.h" 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/WebKit/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 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // pulled it out as a separate parameter. We likewise prune the UA since 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // that will be added back by the network layer. 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (LowerCaseEqualsASCII(name_utf8, "referer") || 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LowerCaseEqualsASCII(name_utf8, "user-agent")) 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Skip over "Cache-Control: max-age=0" header if the corresponding 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // load flag is already specified. FrameLoader sets both the flag and 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the extra header -- the extra header is redundant since our network 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // implementation will add the necessary headers based on load flags. 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // See http://code.google.com/p/chromium/issues/detail?id=3434. 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((load_flags_ & net::LOAD_VALIDATE_CACHE) && 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LowerCaseEqualsASCII(name_utf8, "cache-control") && 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LowerCaseEqualsASCII(value_utf8, "max-age=0")) 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (LowerCaseEqualsASCII(name_utf8, "accept")) 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch has_accept_header_ = true; 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!buffer_.empty()) 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buffer_.append("\r\n"); 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buffer_.append(name_utf8 + ": " + value_utf8); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& GetBuffer() { 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // In some cases, WebKit doesn't add an Accept header, but not having the 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // header confuses some web servers. See bug 808613. 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!has_accept_header_) { 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!buffer_.empty()) 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buffer_.append("\r\n"); 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buffer_.append("Accept: */*"); 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch has_accept_header_ = true; 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return buffer_; 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int load_flags_; 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string buffer_; 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool has_accept_header_; 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochResourceType::Type FromTargetType(WebURLRequest::TargetType type) { 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (type) { 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsMainFrame: 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::MAIN_FRAME; 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsSubframe: 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::SUB_FRAME; 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsSubresource: 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::SUB_RESOURCE; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsStyleSheet: 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::STYLESHEET; 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsScript: 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::SCRIPT; 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsFontResource: 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::FONT_RESOURCE; 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsImage: 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::IMAGE; 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsObject: 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::OBJECT; 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsMedia: 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::MEDIA; 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsWorker: 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::WORKER; 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::TargetIsSharedWorker: 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceType::SHARED_WORKER; 1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case WebURLRequest::TargetIsPrefetch: 1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ResourceType::PREFETCH; 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, 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string* data, URLRequestStatus* status) { 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string mime_type; 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string charset; 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (net::DataURL::Parse(url, &mime_type, &charset, data)) { 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *status = URLRequestStatus(URLRequestStatus::SUCCESS, 0); 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info->request_time = Time::Now(); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info->response_time = Time::Now(); 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info->headers = NULL; 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info->mime_type.swap(mime_type); 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info->charset.swap(charset); 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info->security_info.clear(); 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info->content_length = -1; 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *status = URLRequestStatus(URLRequestStatus::FAILED, net::ERR_INVALID_URL); 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 169731df977c0511bca2206b5f333555b1205ff1f43Iain Merricktypedef ResourceDevToolsInfo::HeadersVector HeadersVector; 170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PopulateURLResponse( 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, 173731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ResourceResponseInfo& info, 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLResponse* response) { 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setURL(url); 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setResponseTime(info.response_time.ToDoubleT()); 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setMIMEType(WebString::fromUTF8(info.mime_type)); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setTextEncodingName(WebString::fromUTF8(info.charset)); 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setExpectedContentLength(info.content_length); 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setSecurityInfo(info.security_info); 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setAppCacheID(info.appcache_id); 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setAppCacheManifestURL(info.appcache_manifest_url); 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setWasCached(!info.load_timing.base_time.is_null() && 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info.response_time < info.load_timing.base_time); 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setWasFetchedViaSPDY(info.was_fetched_via_spdy); 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setWasNpnNegotiated(info.was_npn_negotiated); 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setWasAlternateProtocolAvailable( 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info.was_alternate_protocol_available); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setWasFetchedViaProxy(info.was_fetched_via_proxy); 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setConnectionID(info.connection_id); 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setConnectionReused(info.connection_reused); 1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick response->setDownloadFilePath(FilePathToWebString(info.download_file_path)); 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLLoadTiming timing; 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timing.initialize(); 196731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ResourceLoadTimingInfo& timing_info = info.load_timing; 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timing.setRequestTime(timing_info.base_time.ToDoubleT()); 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timing.setProxyStart(timing_info.proxy_start); 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timing.setProxyEnd(timing_info.proxy_end); 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timing.setDNSStart(timing_info.dns_start); 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timing.setDNSEnd(timing_info.dns_end); 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timing.setConnectStart(timing_info.connect_start); 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timing.setConnectEnd(timing_info.connect_end); 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timing.setSSLStart(timing_info.ssl_start); 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timing.setSSLEnd(timing_info.ssl_end); 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timing.setSendStart(timing_info.send_start); 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timing.setSendEnd(timing_info.send_end); 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timing.setReceiveHeadersEnd(timing_info.receive_headers_end); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setLoadTiming(timing); 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 211731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (info.devtools_info.get()) { 212201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch WebHTTPLoadInfo load_info; 213201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 214201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch load_info.setHTTPStatusCode(info.devtools_info->http_status_code); 215201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch load_info.setHTTPStatusText(WebString::fromUTF8( 216201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch info.devtools_info->http_status_text)); 217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const HeadersVector& request_headers = info.devtools_info->request_headers; 219201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (HeadersVector::const_iterator it = request_headers.begin(); 220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick it != request_headers.end(); ++it) { 221201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch load_info.addRequestHeader(WebString::fromUTF8(it->first), 222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WebString::fromUTF8(it->second)); 223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 224731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const HeadersVector& response_headers = 225731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick info.devtools_info->response_headers; 226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (HeadersVector::const_iterator it = response_headers.begin(); 227731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick it != response_headers.end(); ++it) { 228201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch load_info.addResponseHeader(WebString::fromUTF8(it->first), 229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WebString::fromUTF8(it->second)); 230731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 231201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch response->setHTTPLoadInfo(load_info); 232731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 233731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const net::HttpResponseHeaders* headers = info.headers; 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!headers) 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setHTTPStatusCode(headers->response_code()); 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setHTTPStatusText(WebString::fromUTF8(headers->GetStatusText())); 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(darin): We should leverage HttpResponseHeaders for this, and this 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // should be using the same code as ResourceDispatcherHost. 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(jungshik): Figure out the actual value of the referrer charset and 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // pass it to GetSuggestedFilename. 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string value; 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (headers->EnumerateHeader(NULL, "content-disposition", &value)) { 2473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick response->setSuggestedFileName(FilePathToWebString( 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::GetSuggestedFilename(url, value, "", FilePath()))); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time time_val; 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (headers->GetLastModifiedValue(&time_val)) 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->setLastModifiedDate(time_val.ToDoubleT()); 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Build up the header map. 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void* iter = NULL; 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string name; 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (headers->EnumerateHeaderLines(&iter, &name, &value)) { 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response->addHTTPHeaderField(WebString::fromUTF8(name), 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebString::fromUTF8(value)); 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// WebURLLoaderImpl::Context -------------------------------------------------- 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This inner class exists since the WebURLLoader may be deleted while inside a 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// call to WebURLLoaderClient. The bridge requires its Peer to stay alive 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// until it receives OnCompletedRequest. 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass WebURLLoaderImpl::Context : public base::RefCounted<Context>, 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public ResourceLoaderBridge::Peer { 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit Context(WebURLLoaderImpl* loader); 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLLoaderClient* client() const { return client_; } 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_client(WebURLLoaderClient* client) { client_ = client; } 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Cancel(); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void SetDefersLoading(bool value); 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Start( 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const WebURLRequest& request, 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResourceLoaderBridge::SyncLoadResponse* sync_load_response); 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ResourceLoaderBridge::Peer methods: 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnUploadProgress(uint64 position, uint64 size); 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool OnReceivedRedirect( 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& new_url, 289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ResourceResponseInfo& info, 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool* has_new_first_party_for_cookies, 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL* new_first_party_for_cookies); 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnReceivedResponse( 293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ResourceResponseInfo& info, bool content_filtered); 2943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void OnDownloadedData(int len); 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnReceivedData(const char* data, int len); 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnReceivedCachedMetadata(const char* data, int len); 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnCompletedRequest( 2983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const URLRequestStatus& status, 2993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& security_info, 3003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const base::Time& completion_time); 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend class base::RefCounted<Context>; 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~Context() {} 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 30621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // We can optimize the handling of data URLs in most cases. 30721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bool CanHandleDataURL(const GURL& url) const; 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void HandleDataURL(); 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLLoaderImpl* loader_; 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLRequest request_; 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLLoaderClient* client_; 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<ResourceLoaderBridge> bridge_; 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_; 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<MultipartResponseDelegate> multipart_delegate_; 3163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<ResourceLoaderBridge> completed_bridge_; 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(japhet): Storing this is a temporary hack for site isolation logging. 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURL response_url_; 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebURLLoaderImpl::Context::Context(WebURLLoaderImpl* loader) 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : loader_(loader), 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_(NULL) { 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::Cancel() { 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The bridge will still send OnCompletedRequest, which will Release() us, so 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we don't do that here. 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (bridge_.get()) 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_->Cancel(); 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Ensure that we do not notify the multipart delegate anymore as it has 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // its own pointer to the client. 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (multipart_delegate_.get()) 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch multipart_delegate_->Cancel(); 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Do not make any further calls to the client. 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_ = NULL; 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch loader_ = NULL; 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::SetDefersLoading(bool value) { 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (bridge_.get()) 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_->SetDefersLoading(value); 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::Start( 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const WebURLRequest& request, 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResourceLoaderBridge::SyncLoadResponse* sync_load_response) { 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!bridge_.get()); 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_ = request; // Save the request. 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url = request.url(); 35621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (url.SchemeIs("data") && CanHandleDataURL(url)) { 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (sync_load_response) { 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This is a sync load. Do the work now. 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_load_response->url = url; 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string data; 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetInfoFromDataURL(sync_load_response->url, sync_load_response, 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &sync_load_response->data, 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &sync_load_response->status); 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddRef(); // Balanced in OnCompletedRequest 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->PostTask(FROM_HERE, 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewRunnableMethod(this, &Context::HandleDataURL)); 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL referrer_url( 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.httpHeaderField(WebString::fromUTF8("Referer")).utf8()); 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& method = request.httpMethod().utf8(); 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int load_flags = net::LOAD_NORMAL; 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (request.cachePolicy()) { 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::ReloadIgnoringCacheData: 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Required by LayoutTests/http/tests/misc/refresh-headers.php 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_VALIDATE_CACHE; 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::ReturnCacheDataElseLoad: 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_PREFERRING_CACHE; 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::ReturnCacheDataDontLoad: 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_ONLY_FROM_CACHE; 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebURLRequest::UseProtocolCachePolicy: 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (request.reportUploadProgress()) 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_ENABLE_UPLOAD_PROGRESS; 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (request.reportLoadTiming()) 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_ENABLE_LOAD_TIMING; 396731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (request.reportRawHeaders()) 397731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick load_flags |= net::LOAD_REPORT_RAW_HEADERS; 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!request.allowCookies() || !request.allowStoredCredentials()) { 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES; 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_DO_NOT_SEND_COOKIES; 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!request.allowStoredCredentials()) 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA; 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(jcampan): in the non out-of-process plugin case the request does not 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // have a requestor_pid. Find a better place to set this. 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int requestor_pid = request.requestorProcessID(); 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (requestor_pid == 0) 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requestor_pid = base::GetCurrentProcId(); 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HeaderFlattener flattener(load_flags); 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request.visitHTTPHeaderFields(&flattener); 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(abarth): These are wrong! I need to figure out how to get the right 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // strings here. See: http://crbug.com/8706 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string frame_origin = request.firstPartyForCookies().spec(); 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string main_frame_origin = request.firstPartyForCookies().spec(); 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(brettw) this should take parameter encoding into account when 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // creating the GURLs. 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ResourceLoaderBridge::RequestInfo request_info; 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.method = method; 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.url = url; 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.first_party_for_cookies = request.firstPartyForCookies(); 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.referrer = referrer_url; 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.frame_origin = frame_origin; 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.main_frame_origin = main_frame_origin; 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.headers = flattener.GetBuffer(); 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.load_flags = load_flags; 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.requestor_pid = requestor_pid; 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.request_type = FromTargetType(request.targetType()); 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.appcache_host_id = request.appCacheHostID(); 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_info.routing_id = request.requestorID(); 4373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick request_info.download_to_file = request.downloadToFile(); 43821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_info.has_user_gesture = request.hasUserGesture(); 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_.reset(ResourceLoaderBridge::Create(request_info)); 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!request.httpBody().isNull()) { 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // GET and HEAD requests shouldn't have http bodies. 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(method != "GET" && method != "HEAD"); 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const WebHTTPBody& httpBody = request.httpBody(); 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t i = 0; 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebHTTPBody::Element element; 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (httpBody.elementAt(i++, element)) { 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (element.type) { 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebHTTPBody::Element::TypeData: 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!element.data.isEmpty()) { 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // WebKit sometimes gives up empty data to append. These aren't 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // necessary so we just optimize those out here. 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_->AppendDataToUpload( 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch element.data.data(), static_cast<int>(element.data.size())); 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WebHTTPBody::Element::TypeFile: 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (element.fileLength == -1) { 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_->AppendFileToUpload( 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebStringToFilePath(element.filePath)); 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_->AppendFileRangeToUpload( 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebStringToFilePath(element.filePath), 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<uint64>(element.fileStart), 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<uint64>(element.fileLength), 4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::Time::FromDoubleT(element.modificationTime)); 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 4693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case WebHTTPBody::Element::TypeBlob: 4703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bridge_->AppendBlobToUpload(GURL(element.blobURL)); 4713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_->SetUploadIdentifier(request.httpBody().identifier()); 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (sync_load_response) { 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_->SyncLoad(sync_load_response); 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (bridge_->Start(this)) { 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddRef(); // Balanced in OnCompletedRequest 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bridge_.reset(); 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) { 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (client_) 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_->didSendData(loader_, position, size); 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WebURLLoaderImpl::Context::OnReceivedRedirect( 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& new_url, 498731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ResourceResponseInfo& info, 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool* has_new_first_party_for_cookies, 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL* new_first_party_for_cookies) { 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!client_) 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLResponse response; 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response.initialize(); 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PopulateURLResponse(request_.url(), info, &response); 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(darin): We lack sufficient information to construct the actual 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // request that resulted from the redirect. 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLRequest new_request(new_url); 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_request.setFirstPartyForCookies(request_.firstPartyForCookies()); 512731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new_request.setDownloadToFile(request_.downloadToFile()); 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebString referrer_string = WebString::fromUTF8("Referer"); 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebString referrer = request_.httpHeaderField(referrer_string); 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!WebSecurityPolicy::shouldHideReferrer(new_url, referrer)) 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_request.setHTTPHeaderField(referrer_string, referrer); 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (response.httpStatusCode() == 307) 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_request.setHTTPMethod(request_.httpMethod()); 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_->willSendRequest(loader_, new_request, response); 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_ = new_request; 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *has_new_first_party_for_cookies = true; 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *new_first_party_for_cookies = request_.firstPartyForCookies(); 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Only follow the redirect if WebKit left the URL unmodified. 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (new_url == GURL(new_request.url())) 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We assume that WebKit only changes the URL to suppress a redirect, and we 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // assume that it does so by setting it to be invalid. 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!new_request.url().isValid()); 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::OnReceivedResponse( 538731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ResourceResponseInfo& info, 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool content_filtered) { 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!client_) 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLResponse response; 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response.initialize(); 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PopulateURLResponse(request_.url(), info, &response); 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response.setIsContentFiltered(content_filtered); 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool show_raw_listing = (GURL(request_.url()).query() == "raw"); 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (info.mime_type == "text/vnd.chromium.ftp-dir") { 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (show_raw_listing) { 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set the MIME type to plain text to prevent any active content. 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response.setMIMEType("text/plain"); 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We're going to produce a parsed listing in HTML. 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response.setMIMEType("text/html"); 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_->didReceiveResponse(loader_, response); 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We may have been cancelled after didReceiveResponse, which would leave us 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // without a client and therefore without much need to do further handling. 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!client_) 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!ftp_listing_delegate_.get()); 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!multipart_delegate_.get()); 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (info.headers && info.mime_type == "multipart/x-mixed-replace") { 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string content_type; 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info.headers->EnumerateHeader(NULL, "content-type", &content_type); 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 573513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string boundary = net::GetHeaderParamValue( 574513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch content_type, "boundary", net::QuoteRule::REMOVE_OUTER_QUOTES); 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TrimString(boundary, " \"", &boundary); 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If there's no boundary, just handle the request normally. In the gecko 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // code, nsMultiMixedConv::OnStartRequest throws an exception. 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!boundary.empty()) { 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch multipart_delegate_.reset( 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new MultipartResponseDelegate(client_, loader_, response, boundary)); 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (info.mime_type == "text/vnd.chromium.ftp-dir" && 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !show_raw_listing) { 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ftp_listing_delegate_.reset( 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new FtpDirectoryListingResponseDelegate(client_, loader_, response)); 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response_url_ = response.url(); 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid WebURLLoaderImpl::Context::OnDownloadedData(int len) { 5933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (client_) 5943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick client_->didDownloadData(loader_, len); 5953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 5963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::OnReceivedData(const char* data, int len) { 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!client_) 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Temporary logging, see site_isolation_metrics.h/cc. 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SiteIsolationMetrics::SniffCrossOriginHTML(response_url_, data, len); 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ftp_listing_delegate_.get()) { 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The FTP listing delegate will make the appropriate calls to 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // client_->didReceiveData and client_->didReceiveResponse. 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ftp_listing_delegate_->OnReceivedData(data, len); 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (multipart_delegate_.get()) { 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The multipart delegate will make the appropriate calls to 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // client_->didReceiveData and client_->didReceiveResponse. 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch multipart_delegate_->OnReceivedData(data, len); 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_->didReceiveData(loader_, data, len); 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::OnReceivedCachedMetadata( 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* data, int len) { 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (client_) 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_->didReceiveCachedMetadata(loader_, data, len); 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::OnCompletedRequest( 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const URLRequestStatus& status, 6253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& security_info, 6263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const base::Time& completion_time) { 627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ftp_listing_delegate_.get()) { 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ftp_listing_delegate_->OnCompletedRequest(); 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ftp_listing_delegate_.reset(NULL); 630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (multipart_delegate_.get()) { 631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch multipart_delegate_->OnCompletedRequest(); 632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch multipart_delegate_.reset(NULL); 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Prevent any further IPC to the browser now that we're complete, but 6363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // don't delete it to keep any downloaded temp files alive. 6373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(!completed_bridge_.get()); 6383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick completed_bridge_.swap(bridge_); 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (client_) { 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (status.status() != URLRequestStatus::SUCCESS) { 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int error_code; 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (status.status() == URLRequestStatus::HANDLED_EXTERNALLY) { 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // By marking this request as aborted we insure that we don't navigate 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to an error page. 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_code = net::ERR_ABORTED; 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_code = status.os_error(); 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLError error; 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error.domain = WebString::fromUTF8(net::kErrorDomain); 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error.reason = error_code; 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error.unreachableURL = request_.url(); 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch client_->didFail(loader_, error); 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 6563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick client_->didFinishLoading(loader_, completion_time.ToDoubleT()); 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Temporary logging, see site_isolation_metrics.h/cc 661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SiteIsolationMetrics::RemoveCompletedResponse(response_url_); 662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We are done with the bridge now, and so we need to release the reference 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to ourselves that we took on behalf of the bridge. This may cause our 665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // destruction. 666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Release(); 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 66921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool WebURLLoaderImpl::Context::CanHandleDataURL(const GURL& url) const { 67021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(url.SchemeIs("data")); 67121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 67221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Optimize for the case where we can handle a data URL locally. We must 67321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // skip this for data URLs targetted at frames since those could trigger a 67421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // download. 67521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // 67621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // NOTE: We special case MIME types we can render both for performance 67721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // reasons as well as to support unit tests, which do not have an underlying 67821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // ResourceLoaderBridge implementation. 67921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 68021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (request_.targetType() != WebURLRequest::TargetIsMainFrame && 68121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request_.targetType() != WebURLRequest::TargetIsSubframe) 68221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return true; 68321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 68421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string mime_type, unused_charset; 68521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (net::DataURL::Parse(url, &mime_type, &unused_charset, NULL) && 68621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::IsSupportedMimeType(mime_type)) 68721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return true; 68821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 68921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 69021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 69121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::Context::HandleDataURL() { 693731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ResourceResponseInfo info; 694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch URLRequestStatus status; 695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string data; 696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GetInfoFromDataURL(request_.url(), &info, &data, &status)) { 698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnReceivedResponse(info, false); 699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!data.empty()) 700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnReceivedData(data.data(), data.size()); 701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick OnCompletedRequest(status, info.security_info, base::Time::Now()); 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// WebURLLoaderImpl ----------------------------------------------------------- 707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 708c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebURLLoaderImpl::WebURLLoaderImpl() 709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : ALLOW_THIS_IN_INITIALIZER_LIST(context_(new Context(this))) { 710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 712c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebURLLoaderImpl::~WebURLLoaderImpl() { 713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cancel(); 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::loadSynchronously(const WebURLRequest& request, 717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLResponse& response, 718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLError& error, 719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebData& data) { 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResourceLoaderBridge::SyncLoadResponse sync_load_response; 721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch context_->Start(request, &sync_load_response); 722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& final_url = sync_load_response.url; 724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(tc): For file loads, we may want to include a more descriptive 726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // status code or status text. 727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const URLRequestStatus::Status& status = sync_load_response.status.status(); 728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (status != URLRequestStatus::SUCCESS && 729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status != URLRequestStatus::HANDLED_EXTERNALLY) { 730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response.setURL(final_url); 731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error.domain = WebString::fromUTF8(net::kErrorDomain); 732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error.reason = sync_load_response.status.os_error(); 733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error.unreachableURL = final_url; 734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PopulateURLResponse(final_url, sync_load_response, &response); 738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data.assign(sync_load_response.data.data(), 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_load_response.data.size()); 741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::loadAsynchronously(const WebURLRequest& request, 744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLLoaderClient* client) { 745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!context_->client()); 746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch context_->set_client(client); 748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch context_->Start(request, NULL); 749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::cancel() { 752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch context_->Cancel(); 753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebURLLoaderImpl::setDefersLoading(bool value) { 756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch context_->SetDefersLoading(value); 757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace webkit_glue 760