| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // An implementation of WebURLLoader in terms of ResourceLoaderBridge. | 5 // An implementation of WebURLLoader in terms of ResourceLoaderBridge. |
| 6 | 6 |
| 7 #include "webkit/child/weburlloader_impl.h" | 7 #include "webkit/child/weburlloader_impl.h" |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "third_party/WebKit/public/platform/WebURL.h" | 24 #include "third_party/WebKit/public/platform/WebURL.h" |
| 25 #include "third_party/WebKit/public/platform/WebURLError.h" | 25 #include "third_party/WebKit/public/platform/WebURLError.h" |
| 26 #include "third_party/WebKit/public/platform/WebURLLoadTiming.h" | 26 #include "third_party/WebKit/public/platform/WebURLLoadTiming.h" |
| 27 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h" | 27 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h" |
| 28 #include "third_party/WebKit/public/platform/WebURLRequest.h" | 28 #include "third_party/WebKit/public/platform/WebURLRequest.h" |
| 29 #include "third_party/WebKit/public/platform/WebURLResponse.h" | 29 #include "third_party/WebKit/public/platform/WebURLResponse.h" |
| 30 #include "third_party/WebKit/public/web/WebSecurityPolicy.h" | 30 #include "third_party/WebKit/public/web/WebSecurityPolicy.h" |
| 31 #include "webkit/child/ftp_directory_listing_response_delegate.h" | 31 #include "webkit/child/ftp_directory_listing_response_delegate.h" |
| 32 #include "webkit/child/multipart_response_delegate.h" | 32 #include "webkit/child/multipart_response_delegate.h" |
| 33 #include "webkit/child/resource_loader_bridge.h" | 33 #include "webkit/child/resource_loader_bridge.h" |
| 34 #include "webkit/child/site_isolation_policy.h" |
| 34 #include "webkit/child/webkitplatformsupport_impl.h" | 35 #include "webkit/child/webkitplatformsupport_impl.h" |
| 35 #include "webkit/child/weburlrequest_extradata_impl.h" | 36 #include "webkit/child/weburlrequest_extradata_impl.h" |
| 36 #include "webkit/child/weburlresponse_extradata_impl.h" | 37 #include "webkit/child/weburlresponse_extradata_impl.h" |
| 37 #include "webkit/common/resource_request_body.h" | 38 #include "webkit/common/resource_request_body.h" |
| 38 | 39 |
| 39 using base::Time; | 40 using base::Time; |
| 40 using base::TimeTicks; | 41 using base::TimeTicks; |
| 41 using WebKit::WebData; | 42 using WebKit::WebData; |
| 42 using WebKit::WebHTTPBody; | 43 using WebKit::WebHTTPBody; |
| 43 using WebKit::WebHTTPHeaderVisitor; | 44 using WebKit::WebHTTPHeaderVisitor; |
| 44 using WebKit::WebHTTPLoadInfo; | 45 using WebKit::WebHTTPLoadInfo; |
| 45 using WebKit::WebReferrerPolicy; | 46 using WebKit::WebReferrerPolicy; |
| 46 using WebKit::WebSecurityPolicy; | 47 using WebKit::WebSecurityPolicy; |
| 47 using WebKit::WebString; | 48 using WebKit::WebString; |
| 48 using WebKit::WebURL; | 49 using WebKit::WebURL; |
| 49 using WebKit::WebURLError; | 50 using WebKit::WebURLError; |
| 50 using WebKit::WebURLLoadTiming; | 51 using WebKit::WebURLLoadTiming; |
| 51 using WebKit::WebURLLoader; | 52 using WebKit::WebURLLoader; |
| 52 using WebKit::WebURLLoaderClient; | 53 using WebKit::WebURLLoaderClient; |
| 53 using WebKit::WebURLRequest; | 54 using WebKit::WebURLRequest; |
| 54 using WebKit::WebURLResponse; | 55 using WebKit::WebURLResponse; |
| 55 | 56 |
| 56 namespace webkit_glue { | 57 namespace webkit_glue { |
| 57 | 58 |
| 58 // Utilities ------------------------------------------------------------------ | 59 // Utilities ------------------------------------------------------------------ |
| 59 | 60 |
| 60 namespace { | 61 namespace { |
| 61 | 62 |
| 62 const char kThrottledErrorDescription[] = | 63 const char kThrottledErrorDescription[] = "Request throttled. Visit http://d
ev.chromium.org/throttling for more " |
| 63 "Request throttled. Visit http://dev.chromium.org/throttling for more " | 64 "information."; |
| 64 "information."; | 65 |
| 65 | 66 class HeaderFlattener : public WebHTTPHeaderVisitor { |
| 66 class HeaderFlattener : public WebHTTPHeaderVisitor { | 67 public: |
| 67 public: | 68 explicit HeaderFlattener(int load_flags) |
| 68 explicit HeaderFlattener(int load_flags) | 69 : load_flags_(load_flags) |
| 69 : load_flags_(load_flags), | 70 , has_accept_header_(false) |
| 70 has_accept_header_(false) { | 71 { |
| 71 } | 72 } |
| 72 | 73 |
| 73 virtual void visitHeader(const WebString& name, const WebString& value) { | 74 virtual void visitHeader(const WebString& name, const WebString& value) |
| 74 // TODO(darin): is UTF-8 really correct here? It is if the strings are | 75 { |
| 75 // already ASCII (i.e., if they are already escaped properly). | 76 // TODO(darin): is UTF-8 really correct here? It is if the strings
are |
| 76 const std::string& name_utf8 = name.utf8(); | 77 // already ASCII (i.e., if they are already escaped properly). |
| 77 const std::string& value_utf8 = value.utf8(); | 78 const std::string& name_utf8 = name.utf8(); |
| 78 | 79 const std::string& value_utf8 = value.utf8(); |
| 79 // Skip over referrer headers found in the header map because we already | 80 |
| 80 // pulled it out as a separate parameter. | 81 // Skip over referrer headers found in the header map because we alr
eady |
| 81 if (LowerCaseEqualsASCII(name_utf8, "referer")) | 82 // pulled it out as a separate parameter. |
| 82 return; | 83 if (LowerCaseEqualsASCII(name_utf8, "referer")) |
| 83 | 84 return; |
| 84 // Skip over "Cache-Control: max-age=0" header if the corresponding | 85 |
| 85 // load flag is already specified. FrameLoader sets both the flag and | 86 // Skip over "Cache-Control: max-age=0" header if the corresponding |
| 86 // the extra header -- the extra header is redundant since our network | 87 // load flag is already specified. FrameLoader sets both the flag an
d |
| 87 // implementation will add the necessary headers based on load flags. | 88 // the extra header -- the extra header is redundant since our netwo
rk |
| 88 // See http://code.google.com/p/chromium/issues/detail?id=3434. | 89 // implementation will add the necessary headers based on load flags
. |
| 89 if ((load_flags_ & net::LOAD_VALIDATE_CACHE) && | 90 // See http://code.google.com/p/chromium/issues/detail?id=3434. |
| 90 LowerCaseEqualsASCII(name_utf8, "cache-control") && | 91 if ((load_flags_ & net::LOAD_VALIDATE_CACHE) && LowerCaseEqualsASCII
(name_utf8, "cache-control") && LowerCaseEqualsASCII(value_utf8, "max-age=0")) |
| 91 LowerCaseEqualsASCII(value_utf8, "max-age=0")) | 92 return; |
| 92 return; | 93 |
| 93 | 94 if (LowerCaseEqualsASCII(name_utf8, "accept")) |
| 94 if (LowerCaseEqualsASCII(name_utf8, "accept")) | 95 has_accept_header_ = true; |
| 95 has_accept_header_ = true; | 96 |
| 96 | 97 if (!buffer_.empty()) |
| 97 if (!buffer_.empty()) | 98 buffer_.append("\r\n"); |
| 98 buffer_.append("\r\n"); | 99 buffer_.append(name_utf8 + ": " + value_utf8); |
| 99 buffer_.append(name_utf8 + ": " + value_utf8); | 100 } |
| 100 } | 101 |
| 101 | 102 const std::string& GetBuffer() |
| 102 const std::string& GetBuffer() { | 103 { |
| 103 // In some cases, WebKit doesn't add an Accept header, but not having the | 104 // In some cases, WebKit doesn't add an Accept header, but not havin
g the |
| 104 // header confuses some web servers. See bug 808613. | 105 // header confuses some web servers. See bug 808613. |
| 105 if (!has_accept_header_) { | 106 if (!has_accept_header_) { |
| 106 if (!buffer_.empty()) | 107 if (!buffer_.empty()) |
| 107 buffer_.append("\r\n"); | 108 buffer_.append("\r\n"); |
| 108 buffer_.append("Accept: */*"); | 109 buffer_.append("Accept: */*"); |
| 109 has_accept_header_ = true; | 110 has_accept_header_ = true; |
| 110 } | 111 } |
| 111 return buffer_; | 112 return buffer_; |
| 112 } | 113 } |
| 113 | 114 |
| 114 private: | 115 private: |
| 115 int load_flags_; | 116 int load_flags_; |
| 116 std::string buffer_; | 117 std::string buffer_; |
| 117 bool has_accept_header_; | 118 bool has_accept_header_; |
| 118 }; | 119 }; |
| 119 | 120 |
| 120 // Extracts the information from a data: url. | 121 // Extracts the information from a data: url. |
| 121 bool GetInfoFromDataURL(const GURL& url, | 122 bool GetInfoFromDataURL(const GURL& url, |
| 122 ResourceResponseInfo* info, | 123 ResourceResponseInfo* info, |
| 123 std::string* data, | 124 std::string* data, |
| 124 int* error_code) { | 125 int* error_code) |
| 125 std::string mime_type; | 126 { |
| 126 std::string charset; | 127 std::string mime_type; |
| 127 if (net::DataURL::Parse(url, &mime_type, &charset, data)) { | 128 std::string charset; |
| 128 *error_code = net::OK; | 129 if (net::DataURL::Parse(url, &mime_type, &charset, data)) { |
| 129 // Assure same time for all time fields of data: URLs. | 130 *error_code = net::OK; |
| 130 Time now = Time::Now(); | 131 // Assure same time for all time fields of data: URLs. |
| 131 info->load_timing.request_start = TimeTicks::Now(); | 132 Time now = Time::Now(); |
| 132 info->load_timing.request_start_time = now; | 133 info->load_timing.request_start = TimeTicks::Now(); |
| 133 info->request_time = now; | 134 info->load_timing.request_start_time = now; |
| 134 info->response_time = now; | 135 info->request_time = now; |
| 135 info->headers = NULL; | 136 info->response_time = now; |
| 136 info->mime_type.swap(mime_type); | 137 info->headers = NULL; |
| 137 info->charset.swap(charset); | 138 info->mime_type.swap(mime_type); |
| 138 info->security_info.clear(); | 139 info->charset.swap(charset); |
| 139 info->content_length = data->length(); | 140 info->security_info.clear(); |
| 140 info->encoded_data_length = 0; | 141 info->content_length = data->length(); |
| 141 | 142 info->encoded_data_length = 0; |
| 142 return true; | 143 |
| 143 } | 144 return true; |
| 144 | 145 } |
| 145 *error_code = net::ERR_INVALID_URL; | 146 |
| 146 return false; | 147 *error_code = net::ERR_INVALID_URL; |
| 147 } | 148 return false; |
| 148 | 149 } |
| 149 typedef ResourceDevToolsInfo::HeadersVector HeadersVector; | 150 |
| 150 | 151 typedef ResourceDevToolsInfo::HeadersVector HeadersVector; |
| 151 // Converts timing data from |load_timing| to the format used by WebKit. | 152 |
| 152 void PopulateURLLoadTiming(const net::LoadTimingInfo& load_timing, | 153 // Converts timing data from |load_timing| to the format used by WebKit. |
| 153 WebURLLoadTiming* url_timing) { | 154 void PopulateURLLoadTiming(const net::LoadTimingInfo& load_timing, |
| 154 DCHECK(!load_timing.request_start.is_null()); | 155 WebURLLoadTiming* url_timing) |
| 155 | 156 { |
| 156 const TimeTicks kNullTicks; | 157 DCHECK(!load_timing.request_start.is_null()); |
| 157 url_timing->initialize(); | 158 |
| 158 url_timing->setRequestTime( | 159 const TimeTicks kNullTicks; |
| 159 (load_timing.request_start - kNullTicks).InSecondsF()); | 160 url_timing->initialize(); |
| 160 url_timing->setProxyStart( | 161 url_timing->setRequestTime( |
| 161 (load_timing.proxy_resolve_start - kNullTicks).InSecondsF()); | 162 (load_timing.request_start - kNullTicks).InSecondsF()); |
| 162 url_timing->setProxyEnd( | 163 url_timing->setProxyStart( |
| 163 (load_timing.proxy_resolve_end - kNullTicks).InSecondsF()); | 164 (load_timing.proxy_resolve_start - kNullTicks).InSecondsF()); |
| 164 url_timing->setDNSStart( | 165 url_timing->setProxyEnd( |
| 165 (load_timing.connect_timing.dns_start - kNullTicks).InSecondsF()); | 166 (load_timing.proxy_resolve_end - kNullTicks).InSecondsF()); |
| 166 url_timing->setDNSEnd( | 167 url_timing->setDNSStart( |
| 167 (load_timing.connect_timing.dns_end - kNullTicks).InSecondsF()); | 168 (load_timing.connect_timing.dns_start - kNullTicks).InSecondsF()); |
| 168 url_timing->setConnectStart( | 169 url_timing->setDNSEnd( |
| 169 (load_timing.connect_timing.connect_start - kNullTicks).InSecondsF()); | 170 (load_timing.connect_timing.dns_end - kNullTicks).InSecondsF()); |
| 170 url_timing->setConnectEnd( | 171 url_timing->setConnectStart( |
| 171 (load_timing.connect_timing.connect_end - kNullTicks).InSecondsF()); | 172 (load_timing.connect_timing.connect_start - kNullTicks).InSecondsF()
); |
| 172 url_timing->setSSLStart( | 173 url_timing->setConnectEnd( |
| 173 (load_timing.connect_timing.ssl_start - kNullTicks).InSecondsF()); | 174 (load_timing.connect_timing.connect_end - kNullTicks).InSecondsF()); |
| 174 url_timing->setSSLEnd( | 175 url_timing->setSSLStart( |
| 175 (load_timing.connect_timing.ssl_end - kNullTicks).InSecondsF()); | 176 (load_timing.connect_timing.ssl_start - kNullTicks).InSecondsF()); |
| 176 url_timing->setSendStart( | 177 url_timing->setSSLEnd( |
| 177 (load_timing.send_start - kNullTicks).InSecondsF()); | 178 (load_timing.connect_timing.ssl_end - kNullTicks).InSecondsF()); |
| 178 url_timing->setSendEnd( | 179 url_timing->setSendStart( |
| 179 (load_timing.send_end - kNullTicks).InSecondsF()); | 180 (load_timing.send_start - kNullTicks).InSecondsF()); |
| 180 url_timing->setReceiveHeadersEnd( | 181 url_timing->setSendEnd( |
| 181 (load_timing.receive_headers_end - kNullTicks).InSecondsF()); | 182 (load_timing.send_end - kNullTicks).InSecondsF()); |
| 182 } | 183 url_timing->setReceiveHeadersEnd( |
| 183 | 184 (load_timing.receive_headers_end - kNullTicks).InSecondsF()); |
| 184 void PopulateURLResponse( | 185 } |
| 185 const GURL& url, | 186 |
| 186 const ResourceResponseInfo& info, | 187 void PopulateURLResponse( |
| 187 WebURLResponse* response) { | 188 const GURL& url, |
| 188 response->setURL(url); | 189 const ResourceResponseInfo& info, |
| 189 response->setResponseTime(info.response_time.ToDoubleT()); | 190 WebURLResponse* response) |
| 190 response->setMIMEType(WebString::fromUTF8(info.mime_type)); | 191 { |
| 191 response->setTextEncodingName(WebString::fromUTF8(info.charset)); | 192 response->setURL(url); |
| 192 response->setExpectedContentLength(info.content_length); | 193 response->setResponseTime(info.response_time.ToDoubleT()); |
| 193 response->setSecurityInfo(info.security_info); | 194 response->setMIMEType(WebString::fromUTF8(info.mime_type)); |
| 194 response->setAppCacheID(info.appcache_id); | 195 response->setTextEncodingName(WebString::fromUTF8(info.charset)); |
| 195 response->setAppCacheManifestURL(info.appcache_manifest_url); | 196 response->setExpectedContentLength(info.content_length); |
| 196 response->setWasCached(!info.load_timing.request_start_time.is_null() && | 197 response->setSecurityInfo(info.security_info); |
| 197 info.response_time < info.load_timing.request_start_time); | 198 response->setAppCacheID(info.appcache_id); |
| 198 response->setRemoteIPAddress( | 199 response->setAppCacheManifestURL(info.appcache_manifest_url); |
| 199 WebString::fromUTF8(info.socket_address.host())); | 200 response->setWasCached(!info.load_timing.request_start_time.is_null() &&
info.response_time < info.load_timing.request_start_time); |
| 200 response->setRemotePort(info.socket_address.port()); | 201 response->setRemoteIPAddress( |
| 201 response->setConnectionID(info.load_timing.socket_log_id); | 202 WebString::fromUTF8(info.socket_address.host())); |
| 202 response->setConnectionReused(info.load_timing.socket_reused); | 203 response->setRemotePort(info.socket_address.port()); |
| 203 response->setDownloadFilePath(info.download_file_path.AsUTF16Unsafe()); | 204 response->setConnectionID(info.load_timing.socket_log_id); |
| 204 WebURLResponseExtraDataImpl* extra_data = | 205 response->setConnectionReused(info.load_timing.socket_reused); |
| 205 new WebURLResponseExtraDataImpl(info.npn_negotiated_protocol); | 206 response->setDownloadFilePath(info.download_file_path.AsUTF16Unsafe()); |
| 206 response->setExtraData(extra_data); | 207 WebURLResponseExtraDataImpl* extra_data = new WebURLResponseExtraDataImp
l(info.npn_negotiated_protocol); |
| 207 extra_data->set_was_fetched_via_spdy(info.was_fetched_via_spdy); | 208 response->setExtraData(extra_data); |
| 208 extra_data->set_was_npn_negotiated(info.was_npn_negotiated); | 209 extra_data->set_was_fetched_via_spdy(info.was_fetched_via_spdy); |
| 209 extra_data->set_was_alternate_protocol_available( | 210 extra_data->set_was_npn_negotiated(info.was_npn_negotiated); |
| 210 info.was_alternate_protocol_available); | 211 extra_data->set_was_alternate_protocol_available( |
| 211 extra_data->set_connection_info(info.connection_info); | 212 info.was_alternate_protocol_available); |
| 212 extra_data->set_was_fetched_via_proxy(info.was_fetched_via_proxy); | 213 extra_data->set_connection_info(info.connection_info); |
| 213 | 214 extra_data->set_was_fetched_via_proxy(info.was_fetched_via_proxy); |
| 214 // If there's no received headers end time, don't set load timing. This is | 215 |
| 215 // the case for non-HTTP requests, requests that don't go over the wire, and | 216 // If there's no received headers end time, don't set load timing. This
is |
| 216 // certain error cases. | 217 // the case for non-HTTP requests, requests that don't go over the wire,
and |
| 217 if (!info.load_timing.receive_headers_end.is_null()) { | 218 // certain error cases. |
| 218 WebURLLoadTiming timing; | 219 if (!info.load_timing.receive_headers_end.is_null()) { |
| 219 PopulateURLLoadTiming(info.load_timing, &timing); | 220 WebURLLoadTiming timing; |
| 220 response->setLoadTiming(timing); | 221 PopulateURLLoadTiming(info.load_timing, &timing); |
| 221 } | 222 response->setLoadTiming(timing); |
| 222 | 223 } |
| 223 if (info.devtools_info.get()) { | 224 |
| 224 WebHTTPLoadInfo load_info; | 225 if (info.devtools_info.get()) { |
| 225 | 226 WebHTTPLoadInfo load_info; |
| 226 load_info.setHTTPStatusCode(info.devtools_info->http_status_code); | 227 |
| 227 load_info.setHTTPStatusText(WebString::fromUTF8( | 228 load_info.setHTTPStatusCode(info.devtools_info->http_status_code); |
| 228 info.devtools_info->http_status_text)); | 229 load_info.setHTTPStatusText(WebString::fromUTF8( |
| 229 load_info.setEncodedDataLength(info.encoded_data_length); | 230 info.devtools_info->http_status_text)); |
| 230 | 231 load_info.setEncodedDataLength(info.encoded_data_length); |
| 231 load_info.setRequestHeadersText(WebString::fromUTF8( | 232 |
| 232 info.devtools_info->request_headers_text)); | 233 load_info.setRequestHeadersText(WebString::fromUTF8( |
| 233 load_info.setResponseHeadersText(WebString::fromUTF8( | 234 info.devtools_info->request_headers_text)); |
| 234 info.devtools_info->response_headers_text)); | 235 load_info.setResponseHeadersText(WebString::fromUTF8( |
| 235 const HeadersVector& request_headers = info.devtools_info->request_headers; | 236 info.devtools_info->response_headers_text)); |
| 236 for (HeadersVector::const_iterator it = request_headers.begin(); | 237 const HeadersVector& request_headers = info.devtools_info->request_h
eaders; |
| 237 it != request_headers.end(); ++it) { | 238 for (HeadersVector::const_iterator it = request_headers.begin(); |
| 238 load_info.addRequestHeader(WebString::fromUTF8(it->first), | 239 it != request_headers.end(); ++it) { |
| 239 WebString::fromUTF8(it->second)); | 240 load_info.addRequestHeader(WebString::fromUTF8(it->first), |
| 240 } | 241 WebString::fromUTF8(it->second)); |
| 241 const HeadersVector& response_headers = | 242 } |
| 242 info.devtools_info->response_headers; | 243 const HeadersVector& response_headers = info.devtools_info->response
_headers; |
| 243 for (HeadersVector::const_iterator it = response_headers.begin(); | 244 for (HeadersVector::const_iterator it = response_headers.begin(); |
| 244 it != response_headers.end(); ++it) { | 245 it != response_headers.end(); ++it) { |
| 245 load_info.addResponseHeader(WebString::fromUTF8(it->first), | 246 load_info.addResponseHeader(WebString::fromUTF8(it->first), |
| 246 WebString::fromUTF8(it->second)); | 247 WebString::fromUTF8(it->second)); |
| 247 } | 248 } |
| 248 response->setHTTPLoadInfo(load_info); | 249 response->setHTTPLoadInfo(load_info); |
| 249 } | 250 } |
| 250 | 251 |
| 251 const net::HttpResponseHeaders* headers = info.headers.get(); | 252 const net::HttpResponseHeaders* headers = info.headers.get(); |
| 252 if (!headers) | 253 if (!headers) |
| 253 return; | 254 return; |
| 254 | 255 |
| 255 WebURLResponse::HTTPVersion version = WebURLResponse::Unknown; | 256 WebURLResponse::HTTPVersion version = WebURLResponse::Unknown; |
| 256 if (headers->GetHttpVersion() == net::HttpVersion(0, 9)) | 257 if (headers->GetHttpVersion() == net::HttpVersion(0, 9)) |
| 257 version = WebURLResponse::HTTP_0_9; | 258 version = WebURLResponse::HTTP_0_9; |
| 258 else if (headers->GetHttpVersion() == net::HttpVersion(1, 0)) | 259 else if (headers->GetHttpVersion() == net::HttpVersion(1, 0)) |
| 259 version = WebURLResponse::HTTP_1_0; | 260 version = WebURLResponse::HTTP_1_0; |
| 260 else if (headers->GetHttpVersion() == net::HttpVersion(1, 1)) | 261 else if (headers->GetHttpVersion() == net::HttpVersion(1, 1)) |
| 261 version = WebURLResponse::HTTP_1_1; | 262 version = WebURLResponse::HTTP_1_1; |
| 262 response->setHTTPVersion(version); | 263 response->setHTTPVersion(version); |
| 263 response->setHTTPStatusCode(headers->response_code()); | 264 response->setHTTPStatusCode(headers->response_code()); |
| 264 response->setHTTPStatusText(WebString::fromUTF8(headers->GetStatusText())); | 265 response->setHTTPStatusText(WebString::fromUTF8(headers->GetStatusText()
)); |
| 265 | 266 |
| 266 // TODO(darin): We should leverage HttpResponseHeaders for this, and this | 267 // TODO(darin): We should leverage HttpResponseHeaders for this, and thi
s |
| 267 // should be using the same code as ResourceDispatcherHost. | 268 // should be using the same code as ResourceDispatcherHost. |
| 268 // TODO(jungshik): Figure out the actual value of the referrer charset and | 269 // TODO(jungshik): Figure out the actual value of the referrer charset a
nd |
| 269 // pass it to GetSuggestedFilename. | 270 // pass it to GetSuggestedFilename. |
| 270 std::string value; | 271 std::string value; |
| 271 headers->EnumerateHeader(NULL, "content-disposition", &value); | 272 headers->EnumerateHeader(NULL, "content-disposition", &value); |
| 272 response->setSuggestedFileName( | 273 response->setSuggestedFileName( |
| 273 net::GetSuggestedFilename(url, | 274 net::GetSuggestedFilename(url, |
| 274 value, | 275 value, |
| 275 std::string(), // referrer_charset | 276 std::string(), // referrer_charset |
| 276 std::string(), // suggested_name | 277 std::string(), // suggested_name |
| 277 std::string(), // mime_type | 278 std::string(), // mime_type |
| 278 std::string())); // default_name | 279 std::string())); // default_name |
| 279 | 280 |
| 280 Time time_val; | 281 Time time_val; |
| 281 if (headers->GetLastModifiedValue(&time_val)) | 282 if (headers->GetLastModifiedValue(&time_val)) |
| 282 response->setLastModifiedDate(time_val.ToDoubleT()); | 283 response->setLastModifiedDate(time_val.ToDoubleT()); |
| 283 | 284 |
| 284 // Build up the header map. | 285 // Build up the header map. |
| 285 void* iter = NULL; | 286 void* iter = NULL; |
| 286 std::string name; | 287 std::string name; |
| 287 while (headers->EnumerateHeaderLines(&iter, &name, &value)) { | 288 while (headers->EnumerateHeaderLines(&iter, &name, &value)) { |
| 288 response->addHTTPHeaderField(WebString::fromUTF8(name), | 289 response->addHTTPHeaderField(WebString::fromUTF8(name), |
| 289 WebString::fromUTF8(value)); | 290 WebString::fromUTF8(value)); |
| 290 } | 291 } |
| 291 } | 292 } |
| 292 | 293 |
| 293 net::RequestPriority ConvertWebKitPriorityToNetPriority( | 294 net::RequestPriority ConvertWebKitPriorityToNetPriority( |
| 294 const WebURLRequest::Priority& priority) { | 295 const WebURLRequest::Priority& priority) |
| 295 switch (priority) { | 296 { |
| 296 case WebURLRequest::PriorityVeryHigh: | 297 switch (priority) { |
| 297 return net::HIGHEST; | 298 case WebURLRequest::PriorityVeryHigh: |
| 298 | 299 return net::HIGHEST; |
| 299 case WebURLRequest::PriorityHigh: | 300 |
| 300 return net::MEDIUM; | 301 case WebURLRequest::PriorityHigh: |
| 301 | 302 return net::MEDIUM; |
| 302 case WebURLRequest::PriorityMedium: | 303 |
| 303 return net::LOW; | 304 case WebURLRequest::PriorityMedium: |
| 304 | 305 return net::LOW; |
| 305 case WebURLRequest::PriorityLow: | 306 |
| 306 return net::LOWEST; | 307 case WebURLRequest::PriorityLow: |
| 307 | 308 return net::LOWEST; |
| 308 case WebURLRequest::PriorityVeryLow: | 309 |
| 309 return net::IDLE; | 310 case WebURLRequest::PriorityVeryLow: |
| 310 | 311 return net::IDLE; |
| 311 case WebURLRequest::PriorityUnresolved: | 312 |
| 312 default: | 313 case WebURLRequest::PriorityUnresolved: |
| 313 NOTREACHED(); | 314 default: |
| 314 return net::LOW; | 315 NOTREACHED(); |
| 315 } | 316 return net::LOW; |
| 316 } | 317 } |
| 317 | 318 } |
| 318 } // namespace | 319 |
| 320 } // namespace |
| 319 | 321 |
| 320 // WebURLLoaderImpl::Context -------------------------------------------------- | 322 // WebURLLoaderImpl::Context -------------------------------------------------- |
| 321 | 323 |
| 322 // This inner class exists since the WebURLLoader may be deleted while inside a | 324 // This inner class exists since the WebURLLoader may be deleted while inside a |
| 323 // call to WebURLLoaderClient. The bridge requires its Peer to stay alive | 325 // call to WebURLLoaderClient. The bridge requires its Peer to stay alive |
| 324 // until it receives OnCompletedRequest. | 326 // until it receives OnCompletedRequest. |
| 325 class WebURLLoaderImpl::Context : public base::RefCounted<Context>, | 327 class WebURLLoaderImpl::Context : public base::RefCounted<Context>, |
| 326 public ResourceLoaderBridge::Peer { | 328 public ResourceLoaderBridge::Peer { |
| 327 public: | 329 public: |
| 328 explicit Context(WebURLLoaderImpl* loader); | 330 explicit Context(WebURLLoaderImpl* loader); |
| 329 | 331 |
| 330 WebURLLoaderClient* client() const { return client_; } | 332 WebURLLoaderClient* client() const |
| 331 void set_client(WebURLLoaderClient* client) { client_ = client; } | 333 { |
| 332 | 334 return client_; |
| 333 void Cancel(); | 335 } |
| 334 void SetDefersLoading(bool value); | 336 void set_client(WebURLLoaderClient* client) |
| 335 void DidChangePriority(WebURLRequest::Priority new_priority); | 337 { |
| 336 void Start( | 338 client_ = client; |
| 337 const WebURLRequest& request, | 339 } |
| 338 ResourceLoaderBridge::SyncLoadResponse* sync_load_response, | 340 |
| 339 WebKitPlatformSupportImpl* platform); | 341 void Cancel(); |
| 340 | 342 void SetDefersLoading(bool value); |
| 341 // ResourceLoaderBridge::Peer methods: | 343 void DidChangePriority(WebURLRequest::Priority new_priority); |
| 342 virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE; | 344 void Start( |
| 343 virtual bool OnReceivedRedirect( | 345 const WebURLRequest& request, |
| 344 const GURL& new_url, | 346 ResourceLoaderBridge::SyncLoadResponse* sync_load_response, |
| 345 const ResourceResponseInfo& info, | 347 WebKitPlatformSupportImpl* platform); |
| 346 bool* has_new_first_party_for_cookies, | 348 |
| 347 GURL* new_first_party_for_cookies) OVERRIDE; | 349 // ResourceLoaderBridge::Peer methods: |
| 348 virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE; | 350 virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE; |
| 349 virtual void OnDownloadedData(int len) OVERRIDE; | 351 virtual bool OnReceivedRedirect( |
| 350 virtual void OnReceivedData(const char* data, | 352 const GURL& new_url, |
| 351 int data_length, | 353 const ResourceResponseInfo& info, |
| 352 int encoded_data_length) OVERRIDE; | 354 bool* has_new_first_party_for_cookies, |
| 353 virtual void OnReceivedCachedMetadata(const char* data, int len) OVERRIDE; | 355 GURL* new_first_party_for_cookies) OVERRIDE; |
| 354 virtual void OnCompletedRequest( | 356 virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE; |
| 355 int error_code, | 357 virtual void OnDownloadedData(int len) OVERRIDE; |
| 356 bool was_ignored_by_handler, | 358 virtual void OnReceivedData(const char* data, |
| 357 const std::string& security_info, | 359 int data_length, |
| 358 const base::TimeTicks& completion_time) OVERRIDE; | 360 int encoded_data_length) OVERRIDE; |
| 359 | 361 virtual void OnReceivedCachedMetadata(const char* data, int len) OVERRIDE; |
| 360 private: | 362 virtual void OnCompletedRequest( |
| 361 friend class base::RefCounted<Context>; | 363 int error_code, |
| 362 virtual ~Context() {} | 364 bool was_ignored_by_handler, |
| 363 | 365 const std::string& security_info, |
| 364 // We can optimize the handling of data URLs in most cases. | 366 const base::TimeTicks& completion_time) OVERRIDE; |
| 365 bool CanHandleDataURL(const GURL& url) const; | 367 |
| 366 void HandleDataURL(); | 368 private: |
| 367 | 369 friend class base::RefCounted<Context>; |
| 368 WebURLLoaderImpl* loader_; | 370 virtual ~Context() |
| 369 WebURLRequest request_; | 371 { |
| 370 WebURLLoaderClient* client_; | 372 } |
| 371 WebReferrerPolicy referrer_policy_; | 373 |
| 372 scoped_ptr<ResourceLoaderBridge> bridge_; | 374 // We can optimize the handling of data URLs in most cases. |
| 373 scoped_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_; | 375 bool CanHandleDataURL(const GURL& url) const; |
| 374 scoped_ptr<MultipartResponseDelegate> multipart_delegate_; | 376 void HandleDataURL(); |
| 375 scoped_ptr<ResourceLoaderBridge> completed_bridge_; | 377 |
| 378 WebURLLoaderImpl* loader_; |
| 379 WebURLRequest request_; |
| 380 WebURLLoaderClient* client_; |
| 381 WebReferrerPolicy referrer_policy_; |
| 382 scoped_ptr<ResourceLoaderBridge> bridge_; |
| 383 scoped_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_; |
| 384 scoped_ptr<MultipartResponseDelegate> multipart_delegate_; |
| 385 scoped_ptr<ResourceLoaderBridge> completed_bridge_; |
| 386 |
| 387 // TODO(dsjang): A temporary hack to connect the lastest response |
| 388 // observed by OnReceiveResponse() and the data stream received by OnReceive
dData(). |
| 389 WebURL response_url_; |
| 376 }; | 390 }; |
| 377 | 391 |
| 378 WebURLLoaderImpl::Context::Context(WebURLLoaderImpl* loader) | 392 WebURLLoaderImpl::Context::Context(WebURLLoaderImpl* loader) |
| 379 : loader_(loader), | 393 : loader_(loader) |
| 380 client_(NULL), | 394 , client_(NULL) |
| 381 referrer_policy_(WebKit::WebReferrerPolicyDefault) { | 395 , referrer_policy_(WebKit::WebReferrerPolicyDefault) |
| 382 } | 396 { |
| 383 | 397 } |
| 384 void WebURLLoaderImpl::Context::Cancel() { | 398 |
| 385 // The bridge will still send OnCompletedRequest, which will Release() us, so | 399 void WebURLLoaderImpl::Context::Cancel() |
| 386 // we don't do that here. | 400 { |
| 387 if (bridge_) | 401 // The bridge will still send OnCompletedRequest, which will Release() us, s
o |
| 388 bridge_->Cancel(); | 402 // we don't do that here. |
| 389 | 403 if (bridge_) |
| 390 // Ensure that we do not notify the multipart delegate anymore as it has | 404 bridge_->Cancel(); |
| 391 // its own pointer to the client. | 405 |
| 392 if (multipart_delegate_) | 406 // Ensure that we do not notify the multipart delegate anymore as it has |
| 393 multipart_delegate_->Cancel(); | 407 // its own pointer to the client. |
| 394 | 408 if (multipart_delegate_) |
| 395 // Do not make any further calls to the client. | 409 multipart_delegate_->Cancel(); |
| 396 client_ = NULL; | 410 |
| 397 loader_ = NULL; | 411 // Do not make any further calls to the client. |
| 398 } | 412 client_ = NULL; |
| 399 | 413 loader_ = NULL; |
| 400 void WebURLLoaderImpl::Context::SetDefersLoading(bool value) { | 414 } |
| 401 if (bridge_) | 415 |
| 402 bridge_->SetDefersLoading(value); | 416 void WebURLLoaderImpl::Context::SetDefersLoading(bool value) |
| 417 { |
| 418 if (bridge_) |
| 419 bridge_->SetDefersLoading(value); |
| 403 } | 420 } |
| 404 | 421 |
| 405 void WebURLLoaderImpl::Context::DidChangePriority( | 422 void WebURLLoaderImpl::Context::DidChangePriority( |
| 406 WebURLRequest::Priority new_priority) { | 423 WebURLRequest::Priority new_priority) |
| 407 if (bridge_) | 424 { |
| 408 bridge_->DidChangePriority( | 425 if (bridge_) |
| 409 ConvertWebKitPriorityToNetPriority(new_priority)); | 426 bridge_->DidChangePriority( |
| 427 ConvertWebKitPriorityToNetPriority(new_priority)); |
| 410 } | 428 } |
| 411 | 429 |
| 412 void WebURLLoaderImpl::Context::Start( | 430 void WebURLLoaderImpl::Context::Start( |
| 413 const WebURLRequest& request, | 431 const WebURLRequest& request, |
| 414 ResourceLoaderBridge::SyncLoadResponse* sync_load_response, | 432 ResourceLoaderBridge::SyncLoadResponse* sync_load_response, |
| 415 WebKitPlatformSupportImpl* platform) { | 433 WebKitPlatformSupportImpl* platform) |
| 416 DCHECK(!bridge_.get()); | 434 { |
| 417 | 435 DCHECK(!bridge_.get()); |
| 418 request_ = request; // Save the request. | 436 |
| 419 | 437 request_ = request; // Save the request. |
| 420 GURL url = request.url(); | 438 |
| 421 if (url.SchemeIs("data") && CanHandleDataURL(url)) { | 439 GURL url = request.url(); |
| 440 if (url.SchemeIs("data") && CanHandleDataURL(url)) { |
| 441 if (sync_load_response) { |
| 442 // This is a sync load. Do the work now. |
| 443 sync_load_response->url = url; |
| 444 std::string data; |
| 445 GetInfoFromDataURL(sync_load_response->url, sync_load_response, |
| 446 &sync_load_response->data, |
| 447 &sync_load_response->error_code); |
| 448 } else { |
| 449 AddRef(); // Balanced in OnCompletedRequest |
| 450 base::MessageLoop::current()->PostTask( |
| 451 FROM_HERE, base::Bind(&Context::HandleDataURL, this)); |
| 452 } |
| 453 return; |
| 454 } |
| 455 |
| 456 GURL referrer_url( |
| 457 request.httpHeaderField(WebString::fromUTF8("Referer")).utf8()); |
| 458 const std::string& method = request.httpMethod().utf8(); |
| 459 |
| 460 int load_flags = net::LOAD_NORMAL; |
| 461 switch (request.cachePolicy()) { |
| 462 case WebURLRequest::ReloadIgnoringCacheData: |
| 463 // Required by LayoutTests/http/tests/misc/refresh-headers.php |
| 464 load_flags |= net::LOAD_VALIDATE_CACHE; |
| 465 break; |
| 466 case WebURLRequest::ReturnCacheDataElseLoad: |
| 467 load_flags |= net::LOAD_PREFERRING_CACHE; |
| 468 break; |
| 469 case WebURLRequest::ReturnCacheDataDontLoad: |
| 470 load_flags |= net::LOAD_ONLY_FROM_CACHE; |
| 471 break; |
| 472 case WebURLRequest::UseProtocolCachePolicy: |
| 473 break; |
| 474 } |
| 475 |
| 476 if (request.reportUploadProgress()) |
| 477 load_flags |= net::LOAD_ENABLE_UPLOAD_PROGRESS; |
| 478 if (request.reportLoadTiming()) |
| 479 load_flags |= net::LOAD_ENABLE_LOAD_TIMING; |
| 480 if (request.reportRawHeaders()) |
| 481 load_flags |= net::LOAD_REPORT_RAW_HEADERS; |
| 482 |
| 483 if (!request.allowCookies() || !request.allowStoredCredentials()) { |
| 484 load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES; |
| 485 load_flags |= net::LOAD_DO_NOT_SEND_COOKIES; |
| 486 } |
| 487 |
| 488 if (!request.allowStoredCredentials()) |
| 489 load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA; |
| 490 |
| 491 HeaderFlattener flattener(load_flags); |
| 492 request.visitHTTPHeaderFields(&flattener); |
| 493 |
| 494 // TODO(brettw) this should take parameter encoding into account when |
| 495 // creating the GURLs. |
| 496 |
| 497 ResourceLoaderBridge::RequestInfo request_info; |
| 498 request_info.method = method; |
| 499 request_info.url = url; |
| 500 request_info.first_party_for_cookies = request.firstPartyForCookies(); |
| 501 request_info.referrer = referrer_url; |
| 502 request_info.headers = flattener.GetBuffer(); |
| 503 request_info.load_flags = load_flags; |
| 504 // requestor_pid only needs to be non-zero if the request originates outside |
| 505 // the render process, so we can use requestorProcessID even for requests |
| 506 // from in-process plugins. |
| 507 request_info.requestor_pid = request.requestorProcessID(); |
| 508 request_info.request_type = ResourceType::FromTargetType(request.targetType(
)); |
| 509 request_info.priority = ConvertWebKitPriorityToNetPriority(request.priority(
)); |
| 510 request_info.appcache_host_id = request.appCacheHostID(); |
| 511 request_info.routing_id = request.requestorID(); |
| 512 request_info.download_to_file = request.downloadToFile(); |
| 513 request_info.has_user_gesture = request.hasUserGesture(); |
| 514 request_info.extra_data = request.extraData(); |
| 515 if (request.extraData()) { |
| 516 referrer_policy_ = static_cast<WebURLRequestExtraDataImpl*>( |
| 517 request.extraData())->referrer_policy(); |
| 518 request_info.referrer_policy = referrer_policy_; |
| 519 } |
| 520 bridge_.reset(platform->CreateResourceLoader(request_info)); |
| 521 |
| 522 if (!request.httpBody().isNull()) { |
| 523 // GET and HEAD requests shouldn't have http bodies. |
| 524 DCHECK(method != "GET" && method != "HEAD"); |
| 525 const WebHTTPBody& httpBody = request.httpBody(); |
| 526 size_t i = 0; |
| 527 WebHTTPBody::Element element; |
| 528 scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBod
y; |
| 529 while (httpBody.elementAt(i++, element)) { |
| 530 switch (element.type) { |
| 531 case WebHTTPBody::Element::TypeData: |
| 532 if (!element.data.isEmpty()) { |
| 533 // WebKit sometimes gives up empty data to append. These are
n't |
| 534 // necessary so we just optimize those out here. |
| 535 request_body->AppendBytes( |
| 536 element.data.data(), static_cast<int>(element.data.size(
))); |
| 537 } |
| 538 break; |
| 539 case WebHTTPBody::Element::TypeFile: |
| 540 if (element.fileLength == -1) { |
| 541 request_body->AppendFileRange( |
| 542 base::FilePath::FromUTF16Unsafe(element.filePath), |
| 543 0, kuint64max, base::Time()); |
| 544 } else { |
| 545 request_body->AppendFileRange( |
| 546 base::FilePath::FromUTF16Unsafe(element.filePath), |
| 547 static_cast<uint64>(element.fileStart), |
| 548 static_cast<uint64>(element.fileLength), |
| 549 base::Time::FromDoubleT(element.modificationTime)); |
| 550 } |
| 551 break; |
| 552 case WebHTTPBody::Element::TypeURL: { |
| 553 GURL url = GURL(element.url); |
| 554 DCHECK(url.SchemeIsFileSystem()); |
| 555 request_body->AppendFileSystemFileRange( |
| 556 url, |
| 557 static_cast<uint64>(element.fileStart), |
| 558 static_cast<uint64>(element.fileLength), |
| 559 base::Time::FromDoubleT(element.modificationTime)); |
| 560 break; |
| 561 } |
| 562 case WebHTTPBody::Element::TypeBlob: |
| 563 request_body->AppendBlob(GURL(element.blobURL)); |
| 564 break; |
| 565 default: |
| 566 NOTREACHED(); |
| 567 } |
| 568 } |
| 569 request_body->set_identifier(request.httpBody().identifier()); |
| 570 bridge_->SetRequestBody(request_body.get()); |
| 571 } |
| 572 |
| 422 if (sync_load_response) { | 573 if (sync_load_response) { |
| 423 // This is a sync load. Do the work now. | 574 bridge_->SyncLoad(sync_load_response); |
| 424 sync_load_response->url = url; | 575 return; |
| 425 std::string data; | 576 } |
| 426 GetInfoFromDataURL(sync_load_response->url, sync_load_response, | 577 |
| 427 &sync_load_response->data, | 578 if (bridge_->Start(this)) { |
| 428 &sync_load_response->error_code); | 579 AddRef(); // Balanced in OnCompletedRequest |
| 429 } else { | 580 } else { |
| 430 AddRef(); // Balanced in OnCompletedRequest | 581 bridge_.reset(); |
| 431 base::MessageLoop::current()->PostTask( | 582 } |
| 432 FROM_HERE, base::Bind(&Context::HandleDataURL, this)); | 583 } |
| 433 } | 584 |
| 434 return; | 585 void WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) |
| 435 } | 586 { |
| 436 | 587 if (client_) |
| 437 GURL referrer_url( | 588 client_->didSendData(loader_, position, size); |
| 438 request.httpHeaderField(WebString::fromUTF8("Referer")).utf8()); | |
| 439 const std::string& method = request.httpMethod().utf8(); | |
| 440 | |
| 441 int load_flags = net::LOAD_NORMAL; | |
| 442 switch (request.cachePolicy()) { | |
| 443 case WebURLRequest::ReloadIgnoringCacheData: | |
| 444 // Required by LayoutTests/http/tests/misc/refresh-headers.php | |
| 445 load_flags |= net::LOAD_VALIDATE_CACHE; | |
| 446 break; | |
| 447 case WebURLRequest::ReturnCacheDataElseLoad: | |
| 448 load_flags |= net::LOAD_PREFERRING_CACHE; | |
| 449 break; | |
| 450 case WebURLRequest::ReturnCacheDataDontLoad: | |
| 451 load_flags |= net::LOAD_ONLY_FROM_CACHE; | |
| 452 break; | |
| 453 case WebURLRequest::UseProtocolCachePolicy: | |
| 454 break; | |
| 455 } | |
| 456 | |
| 457 if (request.reportUploadProgress()) | |
| 458 load_flags |= net::LOAD_ENABLE_UPLOAD_PROGRESS; | |
| 459 if (request.reportLoadTiming()) | |
| 460 load_flags |= net::LOAD_ENABLE_LOAD_TIMING; | |
| 461 if (request.reportRawHeaders()) | |
| 462 load_flags |= net::LOAD_REPORT_RAW_HEADERS; | |
| 463 | |
| 464 if (!request.allowCookies() || !request.allowStoredCredentials()) { | |
| 465 load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES; | |
| 466 load_flags |= net::LOAD_DO_NOT_SEND_COOKIES; | |
| 467 } | |
| 468 | |
| 469 if (!request.allowStoredCredentials()) | |
| 470 load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA; | |
| 471 | |
| 472 HeaderFlattener flattener(load_flags); | |
| 473 request.visitHTTPHeaderFields(&flattener); | |
| 474 | |
| 475 // TODO(brettw) this should take parameter encoding into account when | |
| 476 // creating the GURLs. | |
| 477 | |
| 478 ResourceLoaderBridge::RequestInfo request_info; | |
| 479 request_info.method = method; | |
| 480 request_info.url = url; | |
| 481 request_info.first_party_for_cookies = request.firstPartyForCookies(); | |
| 482 request_info.referrer = referrer_url; | |
| 483 request_info.headers = flattener.GetBuffer(); | |
| 484 request_info.load_flags = load_flags; | |
| 485 // requestor_pid only needs to be non-zero if the request originates outside | |
| 486 // the render process, so we can use requestorProcessID even for requests | |
| 487 // from in-process plugins. | |
| 488 request_info.requestor_pid = request.requestorProcessID(); | |
| 489 request_info.request_type = | |
| 490 ResourceType::FromTargetType(request.targetType()); | |
| 491 request_info.priority = | |
| 492 ConvertWebKitPriorityToNetPriority(request.priority()); | |
| 493 request_info.appcache_host_id = request.appCacheHostID(); | |
| 494 request_info.routing_id = request.requestorID(); | |
| 495 request_info.download_to_file = request.downloadToFile(); | |
| 496 request_info.has_user_gesture = request.hasUserGesture(); | |
| 497 request_info.extra_data = request.extraData(); | |
| 498 if (request.extraData()) { | |
| 499 referrer_policy_ = static_cast<WebURLRequestExtraDataImpl*>( | |
| 500 request.extraData())->referrer_policy(); | |
| 501 request_info.referrer_policy = referrer_policy_; | |
| 502 } | |
| 503 bridge_.reset(platform->CreateResourceLoader(request_info)); | |
| 504 | |
| 505 if (!request.httpBody().isNull()) { | |
| 506 // GET and HEAD requests shouldn't have http bodies. | |
| 507 DCHECK(method != "GET" && method != "HEAD"); | |
| 508 const WebHTTPBody& httpBody = request.httpBody(); | |
| 509 size_t i = 0; | |
| 510 WebHTTPBody::Element element; | |
| 511 scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody; | |
| 512 while (httpBody.elementAt(i++, element)) { | |
| 513 switch (element.type) { | |
| 514 case WebHTTPBody::Element::TypeData: | |
| 515 if (!element.data.isEmpty()) { | |
| 516 // WebKit sometimes gives up empty data to append. These aren't | |
| 517 // necessary so we just optimize those out here. | |
| 518 request_body->AppendBytes( | |
| 519 element.data.data(), static_cast<int>(element.data.size())); | |
| 520 } | |
| 521 break; | |
| 522 case WebHTTPBody::Element::TypeFile: | |
| 523 if (element.fileLength == -1) { | |
| 524 request_body->AppendFileRange( | |
| 525 base::FilePath::FromUTF16Unsafe(element.filePath), | |
| 526 0, kuint64max, base::Time()); | |
| 527 } else { | |
| 528 request_body->AppendFileRange( | |
| 529 base::FilePath::FromUTF16Unsafe(element.filePath), | |
| 530 static_cast<uint64>(element.fileStart), | |
| 531 static_cast<uint64>(element.fileLength), | |
| 532 base::Time::FromDoubleT(element.modificationTime)); | |
| 533 } | |
| 534 break; | |
| 535 case WebHTTPBody::Element::TypeURL: { | |
| 536 GURL url = GURL(element.url); | |
| 537 DCHECK(url.SchemeIsFileSystem()); | |
| 538 request_body->AppendFileSystemFileRange( | |
| 539 url, | |
| 540 static_cast<uint64>(element.fileStart), | |
| 541 static_cast<uint64>(element.fileLength), | |
| 542 base::Time::FromDoubleT(element.modificationTime)); | |
| 543 break; | |
| 544 } | |
| 545 case WebHTTPBody::Element::TypeBlob: | |
| 546 request_body->AppendBlob(GURL(element.blobURL)); | |
| 547 break; | |
| 548 default: | |
| 549 NOTREACHED(); | |
| 550 } | |
| 551 } | |
| 552 request_body->set_identifier(request.httpBody().identifier()); | |
| 553 bridge_->SetRequestBody(request_body.get()); | |
| 554 } | |
| 555 | |
| 556 if (sync_load_response) { | |
| 557 bridge_->SyncLoad(sync_load_response); | |
| 558 return; | |
| 559 } | |
| 560 | |
| 561 if (bridge_->Start(this)) { | |
| 562 AddRef(); // Balanced in OnCompletedRequest | |
| 563 } else { | |
| 564 bridge_.reset(); | |
| 565 } | |
| 566 } | |
| 567 | |
| 568 void WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) { | |
| 569 if (client_) | |
| 570 client_->didSendData(loader_, position, size); | |
| 571 } | 589 } |
| 572 | 590 |
| 573 bool WebURLLoaderImpl::Context::OnReceivedRedirect( | 591 bool WebURLLoaderImpl::Context::OnReceivedRedirect( |
| 574 const GURL& new_url, | 592 const GURL& new_url, |
| 575 const ResourceResponseInfo& info, | 593 const ResourceResponseInfo& info, |
| 576 bool* has_new_first_party_for_cookies, | 594 bool* has_new_first_party_for_cookies, |
| 577 GURL* new_first_party_for_cookies) { | 595 GURL* new_first_party_for_cookies) |
| 578 if (!client_) | 596 { |
| 597 if (!client_) |
| 598 return false; |
| 599 |
| 600 WebURLResponse response; |
| 601 response.initialize(); |
| 602 PopulateURLResponse(request_.url(), info, &response); |
| 603 |
| 604 // TODO(darin): We lack sufficient information to construct the actual |
| 605 // request that resulted from the redirect. |
| 606 WebURLRequest new_request(new_url); |
| 607 new_request.setFirstPartyForCookies(request_.firstPartyForCookies()); |
| 608 new_request.setDownloadToFile(request_.downloadToFile()); |
| 609 |
| 610 WebString referrer_string = WebString::fromUTF8("Referer"); |
| 611 WebString referrer = WebSecurityPolicy::generateReferrerHeader( |
| 612 referrer_policy_, |
| 613 new_url, |
| 614 request_.httpHeaderField(referrer_string)); |
| 615 if (!referrer.isEmpty()) |
| 616 new_request.setHTTPHeaderField(referrer_string, referrer); |
| 617 |
| 618 if (response.httpStatusCode() == 307) |
| 619 new_request.setHTTPMethod(request_.httpMethod()); |
| 620 |
| 621 client_->willSendRequest(loader_, new_request, response); |
| 622 request_ = new_request; |
| 623 *has_new_first_party_for_cookies = true; |
| 624 *new_first_party_for_cookies = request_.firstPartyForCookies(); |
| 625 |
| 626 // Only follow the redirect if WebKit left the URL unmodified. |
| 627 if (new_url == GURL(new_request.url())) |
| 628 return true; |
| 629 |
| 630 // We assume that WebKit only changes the URL to suppress a redirect, and we |
| 631 // assume that it does so by setting it to be invalid. |
| 632 DCHECK(!new_request.url().isValid()); |
| 579 return false; | 633 return false; |
| 580 | |
| 581 WebURLResponse response; | |
| 582 response.initialize(); | |
| 583 PopulateURLResponse(request_.url(), info, &response); | |
| 584 | |
| 585 // TODO(darin): We lack sufficient information to construct the actual | |
| 586 // request that resulted from the redirect. | |
| 587 WebURLRequest new_request(new_url); | |
| 588 new_request.setFirstPartyForCookies(request_.firstPartyForCookies()); | |
| 589 new_request.setDownloadToFile(request_.downloadToFile()); | |
| 590 | |
| 591 WebString referrer_string = WebString::fromUTF8("Referer"); | |
| 592 WebString referrer = WebSecurityPolicy::generateReferrerHeader( | |
| 593 referrer_policy_, | |
| 594 new_url, | |
| 595 request_.httpHeaderField(referrer_string)); | |
| 596 if (!referrer.isEmpty()) | |
| 597 new_request.setHTTPHeaderField(referrer_string, referrer); | |
| 598 | |
| 599 if (response.httpStatusCode() == 307) | |
| 600 new_request.setHTTPMethod(request_.httpMethod()); | |
| 601 | |
| 602 client_->willSendRequest(loader_, new_request, response); | |
| 603 request_ = new_request; | |
| 604 *has_new_first_party_for_cookies = true; | |
| 605 *new_first_party_for_cookies = request_.firstPartyForCookies(); | |
| 606 | |
| 607 // Only follow the redirect if WebKit left the URL unmodified. | |
| 608 if (new_url == GURL(new_request.url())) | |
| 609 return true; | |
| 610 | |
| 611 // We assume that WebKit only changes the URL to suppress a redirect, and we | |
| 612 // assume that it does so by setting it to be invalid. | |
| 613 DCHECK(!new_request.url().isValid()); | |
| 614 return false; | |
| 615 } | 634 } |
| 616 | 635 |
| 617 void WebURLLoaderImpl::Context::OnReceivedResponse( | 636 void WebURLLoaderImpl::Context::OnReceivedResponse( |
| 618 const ResourceResponseInfo& info) { | 637 const ResourceResponseInfo& info) |
| 619 if (!client_) | 638 { |
| 620 return; | 639 if (!client_) |
| 621 | 640 return; |
| 622 WebURLResponse response; | 641 |
| 623 response.initialize(); | 642 WebURLResponse response; |
| 624 PopulateURLResponse(request_.url(), info, &response); | 643 response.initialize(); |
| 625 | 644 PopulateURLResponse(request_.url(), info, &response); |
| 626 bool show_raw_listing = (GURL(request_.url()).query() == "raw"); | 645 |
| 627 | 646 bool show_raw_listing = (GURL(request_.url()).query() == "raw"); |
| 628 if (info.mime_type == "text/vnd.chromium.ftp-dir") { | 647 |
| 629 if (show_raw_listing) { | 648 if (info.mime_type == "text/vnd.chromium.ftp-dir") { |
| 630 // Set the MIME type to plain text to prevent any active content. | 649 if (show_raw_listing) { |
| 631 response.setMIMEType("text/plain"); | 650 // Set the MIME type to plain text to prevent any active content. |
| 632 } else { | 651 response.setMIMEType("text/plain"); |
| 633 // We're going to produce a parsed listing in HTML. | 652 } else { |
| 634 response.setMIMEType("text/html"); | 653 // We're going to produce a parsed listing in HTML. |
| 635 } | 654 response.setMIMEType("text/html"); |
| 636 } | 655 } |
| 637 | 656 } |
| 638 scoped_refptr<Context> protect(this); | 657 |
| 639 client_->didReceiveResponse(loader_, response); | 658 scoped_refptr<Context> protect(this); |
| 640 | 659 client_->didReceiveResponse(loader_, response); |
| 641 // We may have been cancelled after didReceiveResponse, which would leave us | 660 |
| 642 // without a client and therefore without much need to do further handling. | 661 // We may have been cancelled after didReceiveResponse, which would leave us |
| 643 if (!client_) | 662 // without a client and therefore without much need to do further handling. |
| 644 return; | 663 if (!client_) |
| 645 | 664 return; |
| 646 DCHECK(!ftp_listing_delegate_.get()); | 665 |
| 647 DCHECK(!multipart_delegate_.get()); | 666 DCHECK(!ftp_listing_delegate_.get()); |
| 648 if (info.headers.get() && info.mime_type == "multipart/x-mixed-replace") { | 667 DCHECK(!multipart_delegate_.get()); |
| 649 std::string content_type; | 668 if (info.headers.get() && info.mime_type == "multipart/x-mixed-replace") { |
| 650 info.headers->EnumerateHeader(NULL, "content-type", &content_type); | 669 std::string content_type; |
| 651 | 670 info.headers->EnumerateHeader(NULL, "content-type", &content_type); |
| 652 std::string mime_type; | 671 |
| 653 std::string charset; | 672 std::string mime_type; |
| 654 bool had_charset = false; | 673 std::string charset; |
| 655 std::string boundary; | 674 bool had_charset = false; |
| 656 net::HttpUtil::ParseContentType(content_type, &mime_type, &charset, | 675 std::string boundary; |
| 657 &had_charset, &boundary); | 676 net::HttpUtil::ParseContentType(content_type, &mime_type, &charset, |
| 658 TrimString(boundary, " \"", &boundary); | 677 &had_charset, &boundary); |
| 659 | 678 TrimString(boundary, " \"", &boundary); |
| 660 // If there's no boundary, just handle the request normally. In the gecko | 679 |
| 661 // code, nsMultiMixedConv::OnStartRequest throws an exception. | 680 // If there's no boundary, just handle the request normally. In the gec
ko |
| 662 if (!boundary.empty()) { | 681 // code, nsMultiMixedConv::OnStartRequest throws an exception. |
| 663 multipart_delegate_.reset( | 682 if (!boundary.empty()) { |
| 664 new MultipartResponseDelegate(client_, loader_, response, boundary)); | 683 multipart_delegate_.reset( |
| 665 } | 684 new MultipartResponseDelegate(client_, loader_, response, bounda
ry)); |
| 666 } else if (info.mime_type == "text/vnd.chromium.ftp-dir" && | 685 } |
| 667 !show_raw_listing) { | 686 } else if (info.mime_type == "text/vnd.chromium.ftp-dir" && !show_raw_listin
g) { |
| 668 ftp_listing_delegate_.reset( | 687 ftp_listing_delegate_.reset( |
| 669 new FtpDirectoryListingResponseDelegate(client_, loader_, response)); | 688 new FtpDirectoryListingResponseDelegate(client_, loader_, response))
; |
| 670 } | 689 } |
| 671 } | 690 |
| 672 | 691 response_url_ = response.url(); |
| 673 void WebURLLoaderImpl::Context::OnDownloadedData(int len) { | 692 } |
| 674 if (client_) | 693 |
| 675 client_->didDownloadData(loader_, len); | 694 void WebURLLoaderImpl::Context::OnDownloadedData(int len) |
| 695 { |
| 696 if (client_) |
| 697 client_->didDownloadData(loader_, len); |
| 676 } | 698 } |
| 677 | 699 |
| 678 void WebURLLoaderImpl::Context::OnReceivedData(const char* data, | 700 void WebURLLoaderImpl::Context::OnReceivedData(const char* data, |
| 679 int data_length, | 701 int data_length, |
| 680 int encoded_data_length) { | 702 int encoded_data_length) |
| 681 if (!client_) | 703 { |
| 682 return; | 704 if (!client_) |
| 683 | 705 return; |
| 684 if (ftp_listing_delegate_) { | 706 |
| 685 // The FTP listing delegate will make the appropriate calls to | 707 if (ftp_listing_delegate_) { |
| 686 // client_->didReceiveData and client_->didReceiveResponse. | 708 // The FTP listing delegate will make the appropriate calls to |
| 687 ftp_listing_delegate_->OnReceivedData(data, data_length); | 709 // client_->didReceiveData and client_->didReceiveResponse. |
| 688 } else if (multipart_delegate_) { | 710 ftp_listing_delegate_->OnReceivedData(data, data_length); |
| 689 // The multipart delegate will make the appropriate calls to | 711 } else if (multipart_delegate_) { |
| 690 // client_->didReceiveData and client_->didReceiveResponse. | 712 // The multipart delegate will make the appropriate calls to |
| 691 multipart_delegate_->OnReceivedData(data, data_length, encoded_data_length); | 713 // client_->didReceiveData and client_->didReceiveResponse. |
| 692 } else { | 714 multipart_delegate_->OnReceivedData(data, data_length, encoded_data_leng
th); |
| 693 client_->didReceiveData(loader_, data, data_length, encoded_data_length); | 715 } else { |
| 694 } | 716 client_->didReceiveData(loader_, data, data_length, encoded_data_length)
; |
| 717 } |
| 718 |
| 719 // TODO(dsjang): This logging code is just temporary. There has to |
| 720 // be a better way to connect the received data to the response_url |
| 721 // than this. |
| 722 SiteIsolationPolicy::DidReceiveData(data, data_length, response_url_); |
| 695 } | 723 } |
| 696 | 724 |
| 697 void WebURLLoaderImpl::Context::OnReceivedCachedMetadata( | 725 void WebURLLoaderImpl::Context::OnReceivedCachedMetadata( |
| 698 const char* data, int len) { | 726 const char* data, int len) |
| 699 if (client_) | 727 { |
| 700 client_->didReceiveCachedMetadata(loader_, data, len); | 728 if (client_) |
| 729 client_->didReceiveCachedMetadata(loader_, data, len); |
| 701 } | 730 } |
| 702 | 731 |
| 703 void WebURLLoaderImpl::Context::OnCompletedRequest( | 732 void WebURLLoaderImpl::Context::OnCompletedRequest( |
| 704 int error_code, | 733 int error_code, |
| 705 bool was_ignored_by_handler, | 734 bool was_ignored_by_handler, |
| 706 const std::string& security_info, | 735 const std::string& security_info, |
| 707 const base::TimeTicks& completion_time) { | 736 const base::TimeTicks& completion_time) |
| 708 if (ftp_listing_delegate_) { | 737 { |
| 709 ftp_listing_delegate_->OnCompletedRequest(); | 738 if (ftp_listing_delegate_) { |
| 710 ftp_listing_delegate_.reset(NULL); | 739 ftp_listing_delegate_->OnCompletedRequest(); |
| 711 } else if (multipart_delegate_) { | 740 ftp_listing_delegate_.reset(NULL); |
| 712 multipart_delegate_->OnCompletedRequest(); | 741 } else if (multipart_delegate_) { |
| 713 multipart_delegate_.reset(NULL); | 742 multipart_delegate_->OnCompletedRequest(); |
| 714 } | 743 multipart_delegate_.reset(NULL); |
| 715 | 744 } |
| 716 // Prevent any further IPC to the browser now that we're complete, but | 745 |
| 717 // don't delete it to keep any downloaded temp files alive. | 746 // Prevent any further IPC to the browser now that we're complete, but |
| 718 DCHECK(!completed_bridge_.get()); | 747 // don't delete it to keep any downloaded temp files alive. |
| 719 completed_bridge_.swap(bridge_); | 748 DCHECK(!completed_bridge_.get()); |
| 720 | 749 completed_bridge_.swap(bridge_); |
| 721 if (client_) { | 750 |
| 722 if (error_code != net::OK) { | 751 if (client_) { |
| 723 client_->didFail(loader_, CreateError(request_.url(), error_code)); | 752 if (error_code != net::OK) { |
| 724 } else { | 753 client_->didFail(loader_, CreateError(request_.url(), error_code)); |
| 725 client_->didFinishLoading( | 754 } else { |
| 726 loader_, (completion_time - TimeTicks()).InSecondsF()); | 755 client_->didFinishLoading( |
| 727 } | 756 loader_, (completion_time - TimeTicks()).InSecondsF()); |
| 728 } | 757 } |
| 729 | 758 } |
| 730 // We are done with the bridge now, and so we need to release the reference | 759 |
| 731 // to ourselves that we took on behalf of the bridge. This may cause our | 760 // TODO(dsjang): This logging code is just temporary. There has to |
| 732 // destruction. | 761 // be a better way to connect the received data to the response_url |
| 733 Release(); | 762 // than this. |
| 734 } | 763 SiteIsolationPolicy::DidFinishResourceLoad(response_url_); |
| 735 | 764 |
| 736 bool WebURLLoaderImpl::Context::CanHandleDataURL(const GURL& url) const { | 765 // We are done with the bridge now, and so we need to release the reference |
| 737 DCHECK(url.SchemeIs("data")); | 766 // to ourselves that we took on behalf of the bridge. This may cause our |
| 738 | 767 // destruction. |
| 739 // Optimize for the case where we can handle a data URL locally. We must | 768 Release(); |
| 740 // skip this for data URLs targetted at frames since those could trigger a | 769 } |
| 741 // download. | 770 |
| 742 // | 771 bool WebURLLoaderImpl::Context::CanHandleDataURL(const GURL& url) const |
| 743 // NOTE: We special case MIME types we can render both for performance | 772 { |
| 744 // reasons as well as to support unit tests, which do not have an underlying | 773 DCHECK(url.SchemeIs("data")); |
| 745 // ResourceLoaderBridge implementation. | 774 |
| 775 // Optimize for the case where we can handle a data URL locally. We must |
| 776 // skip this for data URLs targetted at frames since those could trigger a |
| 777 // download. |
| 778 // |
| 779 // NOTE: We special case MIME types we can render both for performance |
| 780 // reasons as well as to support unit tests, which do not have an underlying |
| 781 // ResourceLoaderBridge implementation. |
| 746 | 782 |
| 747 #if defined(OS_ANDROID) | 783 #if defined(OS_ANDROID) |
| 748 // For compatibility reasons on Android we need to expose top-level data:// | 784 // For compatibility reasons on Android we need to expose top-level data:// |
| 749 // to the browser. | 785 // to the browser. |
| 750 if (request_.targetType() == WebURLRequest::TargetIsMainFrame) | 786 if (request_.targetType() == WebURLRequest::TargetIsMainFrame) |
| 787 return false; |
| 788 #endif |
| 789 |
| 790 if (request_.targetType() != WebURLRequest::TargetIsMainFrame && request_.ta
rgetType() != WebURLRequest::TargetIsSubframe) |
| 791 return true; |
| 792 |
| 793 std::string mime_type, unused_charset; |
| 794 if (net::DataURL::Parse(url, &mime_type, &unused_charset, NULL) && net::IsSu
pportedMimeType(mime_type)) |
| 795 return true; |
| 796 |
| 751 return false; | 797 return false; |
| 752 #endif | 798 } |
| 753 | 799 |
| 754 if (request_.targetType() != WebURLRequest::TargetIsMainFrame && | 800 void WebURLLoaderImpl::Context::HandleDataURL() |
| 755 request_.targetType() != WebURLRequest::TargetIsSubframe) | 801 { |
| 756 return true; | 802 ResourceResponseInfo info; |
| 757 | 803 int error_code; |
| 758 std::string mime_type, unused_charset; | 804 std::string data; |
| 759 if (net::DataURL::Parse(url, &mime_type, &unused_charset, NULL) && | 805 |
| 760 net::IsSupportedMimeType(mime_type)) | 806 if (GetInfoFromDataURL(request_.url(), &info, &data, &error_code)) { |
| 761 return true; | 807 OnReceivedResponse(info); |
| 762 | 808 if (!data.empty()) |
| 763 return false; | 809 OnReceivedData(data.data(), data.size(), 0); |
| 764 } | 810 } |
| 765 | 811 |
| 766 void WebURLLoaderImpl::Context::HandleDataURL() { | 812 OnCompletedRequest(error_code, false, info.security_info, |
| 767 ResourceResponseInfo info; | 813 base::TimeTicks::Now()); |
| 768 int error_code; | |
| 769 std::string data; | |
| 770 | |
| 771 if (GetInfoFromDataURL(request_.url(), &info, &data, &error_code)) { | |
| 772 OnReceivedResponse(info); | |
| 773 if (!data.empty()) | |
| 774 OnReceivedData(data.data(), data.size(), 0); | |
| 775 } | |
| 776 | |
| 777 OnCompletedRequest(error_code, false, info.security_info, | |
| 778 base::TimeTicks::Now()); | |
| 779 } | 814 } |
| 780 | 815 |
| 781 // WebURLLoaderImpl ----------------------------------------------------------- | 816 // WebURLLoaderImpl ----------------------------------------------------------- |
| 782 | 817 |
| 783 WebURLLoaderImpl::WebURLLoaderImpl(WebKitPlatformSupportImpl* platform) | 818 WebURLLoaderImpl::WebURLLoaderImpl(WebKitPlatformSupportImpl* platform) |
| 784 : context_(new Context(this)), | 819 : context_(new Context(this)) |
| 785 platform_(platform) { | 820 , platform_(platform) |
| 786 } | 821 { |
| 787 | 822 } |
| 788 WebURLLoaderImpl::~WebURLLoaderImpl() { | 823 |
| 789 cancel(); | 824 WebURLLoaderImpl::~WebURLLoaderImpl() |
| 825 { |
| 826 cancel(); |
| 790 } | 827 } |
| 791 | 828 |
| 792 WebURLError WebURLLoaderImpl::CreateError(const WebURL& unreachable_url, | 829 WebURLError WebURLLoaderImpl::CreateError(const WebURL& unreachable_url, |
| 793 int reason) { | 830 int reason) |
| 794 WebURLError error; | 831 { |
| 795 error.domain = WebString::fromUTF8(net::kErrorDomain); | 832 WebURLError error; |
| 796 error.reason = reason; | 833 error.domain = WebString::fromUTF8(net::kErrorDomain); |
| 797 error.unreachableURL = unreachable_url; | 834 error.reason = reason; |
| 798 if (reason == net::ERR_ABORTED) { | 835 error.unreachableURL = unreachable_url; |
| 799 error.isCancellation = true; | 836 if (reason == net::ERR_ABORTED) { |
| 800 } else if (reason == net::ERR_TEMPORARILY_THROTTLED) { | 837 error.isCancellation = true; |
| 801 error.localizedDescription = WebString::fromUTF8( | 838 } else if (reason == net::ERR_TEMPORARILY_THROTTLED) { |
| 802 kThrottledErrorDescription); | 839 error.localizedDescription = WebString::fromUTF8( |
| 803 } | 840 kThrottledErrorDescription); |
| 804 return error; | 841 } |
| 842 return error; |
| 805 } | 843 } |
| 806 | 844 |
| 807 void WebURLLoaderImpl::loadSynchronously(const WebURLRequest& request, | 845 void WebURLLoaderImpl::loadSynchronously(const WebURLRequest& request, |
| 808 WebURLResponse& response, | 846 WebURLResponse& response, |
| 809 WebURLError& error, | 847 WebURLError& error, |
| 810 WebData& data) { | 848 WebData& data) |
| 811 ResourceLoaderBridge::SyncLoadResponse sync_load_response; | 849 { |
| 812 context_->Start(request, &sync_load_response, platform_); | 850 ResourceLoaderBridge::SyncLoadResponse sync_load_response; |
| 813 | 851 context_->Start(request, &sync_load_response, platform_); |
| 814 const GURL& final_url = sync_load_response.url; | 852 |
| 815 | 853 const GURL& final_url = sync_load_response.url; |
| 816 // TODO(tc): For file loads, we may want to include a more descriptive | 854 |
| 817 // status code or status text. | 855 // TODO(tc): For file loads, we may want to include a more descriptive |
| 818 int error_code = sync_load_response.error_code; | 856 // status code or status text. |
| 819 if (error_code != net::OK) { | 857 int error_code = sync_load_response.error_code; |
| 820 response.setURL(final_url); | 858 if (error_code != net::OK) { |
| 821 error.domain = WebString::fromUTF8(net::kErrorDomain); | 859 response.setURL(final_url); |
| 822 error.reason = error_code; | 860 error.domain = WebString::fromUTF8(net::kErrorDomain); |
| 823 error.unreachableURL = final_url; | 861 error.reason = error_code; |
| 824 return; | 862 error.unreachableURL = final_url; |
| 825 } | 863 return; |
| 826 | 864 } |
| 827 PopulateURLResponse(final_url, sync_load_response, &response); | 865 |
| 828 | 866 PopulateURLResponse(final_url, sync_load_response, &response); |
| 829 data.assign(sync_load_response.data.data(), | 867 |
| 830 sync_load_response.data.size()); | 868 data.assign(sync_load_response.data.data(), |
| 869 sync_load_response.data.size()); |
| 831 } | 870 } |
| 832 | 871 |
| 833 void WebURLLoaderImpl::loadAsynchronously(const WebURLRequest& request, | 872 void WebURLLoaderImpl::loadAsynchronously(const WebURLRequest& request, |
| 834 WebURLLoaderClient* client) { | 873 WebURLLoaderClient* client) |
| 835 DCHECK(!context_->client()); | 874 { |
| 836 | 875 DCHECK(!context_->client()); |
| 837 context_->set_client(client); | 876 |
| 838 context_->Start(request, NULL, platform_); | 877 context_->set_client(client); |
| 839 } | 878 context_->Start(request, NULL, platform_); |
| 840 | 879 } |
| 841 void WebURLLoaderImpl::cancel() { | 880 |
| 842 context_->Cancel(); | 881 void WebURLLoaderImpl::cancel() |
| 843 } | 882 { |
| 844 | 883 context_->Cancel(); |
| 845 void WebURLLoaderImpl::setDefersLoading(bool value) { | 884 } |
| 846 context_->SetDefersLoading(value); | 885 |
| 847 } | 886 void WebURLLoaderImpl::setDefersLoading(bool value) |
| 848 | 887 { |
| 849 void WebURLLoaderImpl::didChangePriority(WebURLRequest::Priority new_priority) { | 888 context_->SetDefersLoading(value); |
| 850 context_->DidChangePriority(new_priority); | 889 } |
| 851 } | 890 |
| 852 | 891 void WebURLLoaderImpl::didChangePriority(WebURLRequest::Priority new_priority) |
| 853 } // namespace webkit_glue | 892 { |
| 893 context_->DidChangePriority(new_priority); |
| 894 } |
| 895 |
| 896 } // namespace webkit_glue |
| OLD | NEW |