OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. |
3 * Copyright (C) 2013, Intel Corporation | 3 * Copyright (C) 2013, Intel Corporation |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
72 : m_client(client) | 72 : m_client(client) |
73 , m_document(document) | 73 , m_document(document) |
74 , m_options(options) | 74 , m_options(options) |
75 , m_resourceLoaderOptions(resourceLoaderOptions) | 75 , m_resourceLoaderOptions(resourceLoaderOptions) |
76 , m_forceDoNotAllowStoredCredentials(false) | 76 , m_forceDoNotAllowStoredCredentials(false) |
77 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) | 77 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) |
78 , m_sameOriginRequest(securityOrigin()->canRequest(request.url())) | 78 , m_sameOriginRequest(securityOrigin()->canRequest(request.url())) |
79 , m_simpleRequest(true) | 79 , m_simpleRequest(true) |
80 , m_async(blockingBehavior == LoadAsynchronously) | 80 , m_async(blockingBehavior == LoadAsynchronously) |
81 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) | 81 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) |
82 , m_requestStartedSeconds(0.0) | |
82 { | 83 { |
83 ASSERT(client); | 84 ASSERT(client); |
84 // Setting an outgoing referer is only supported in the async code path. | 85 // Setting an outgoing referer is only supported in the async code path. |
85 ASSERT(m_async || request.httpReferrer().isEmpty()); | 86 ASSERT(m_async || request.httpReferrer().isEmpty()); |
86 | 87 |
88 m_requestStartedSeconds = monotonicallyIncreasingTime(); | |
89 | |
87 // Save any CORS simple headers on the request here. If this request redirec ts cross-origin, we cancel the old request | 90 // Save any CORS simple headers on the request here. If this request redirec ts cross-origin, we cancel the old request |
88 // create a new one, and copy these headers. | 91 // create a new one, and copy these headers. |
89 const HTTPHeaderMap& headerMap = request.httpHeaderFields(); | 92 const HTTPHeaderMap& headerMap = request.httpHeaderFields(); |
90 HTTPHeaderMap::const_iterator end = headerMap.end(); | 93 HTTPHeaderMap::const_iterator end = headerMap.end(); |
91 for (HTTPHeaderMap::const_iterator it = headerMap.begin(); it != end; ++it) { | 94 for (HTTPHeaderMap::const_iterator it = headerMap.begin(); it != end; ++it) { |
92 if (isOnAccessControlSimpleRequestHeaderWhitelist(it->key, it->value)) | 95 if (isOnAccessControlSimpleRequestHeaderWhitelist(it->key, it->value)) |
93 m_simpleRequestHeaders.add(it->key, it->value); | 96 m_simpleRequestHeaders.add(it->key, it->value); |
94 } | 97 } |
95 | 98 |
96 if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossO riginRequests) { | 99 if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossO riginRequests) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
140 preflightOptions.allowCredentials = DoNotAllowStoredCredentials; | 143 preflightOptions.allowCredentials = DoNotAllowStoredCredentials; |
141 loadRequest(preflightRequest, preflightOptions); | 144 loadRequest(preflightRequest, preflightOptions); |
142 } | 145 } |
143 } | 146 } |
144 } | 147 } |
145 | 148 |
146 DocumentThreadableLoader::~DocumentThreadableLoader() | 149 DocumentThreadableLoader::~DocumentThreadableLoader() |
147 { | 150 { |
148 } | 151 } |
149 | 152 |
153 void DocumentThreadableLoader::overrideTimeout(unsigned long timeoutMilliseconds ) | |
154 { | |
155 if (!m_async) | |
156 return; | |
157 m_timeoutTimer.stop(); | |
158 // At the time of this method's implementation, it is only ever called by | |
159 // XMLHttpRequest, when the timeout attribute is set after sending the | |
160 // request. | |
161 // | |
162 // The XHR request says to resolve the time relative to when the request | |
163 // was initially sent, however other uses of this method may need to | |
164 // behave differently, in which case this should be re-arranged somehow. | |
165 if (timeoutMilliseconds && m_requestStartedSeconds > 0.0) { | |
166 double elapsedTime = monotonicallyIncreasingTime() - m_requestStartedSec onds; | |
167 double nextFire = timeoutMilliseconds / 1000.0; | |
168 double resolvedTime = std::max(nextFire - elapsedTime, 0.0); | |
169 m_timeoutTimer.startOneShot(resolvedTime, FROM_HERE); | |
170 } | |
171 } | |
172 | |
150 void DocumentThreadableLoader::cancel() | 173 void DocumentThreadableLoader::cancel() |
151 { | 174 { |
152 cancelWithError(ResourceError()); | 175 cancelWithError(ResourceError()); |
153 } | 176 } |
154 | 177 |
155 void DocumentThreadableLoader::cancelWithError(const ResourceError& error) | 178 void DocumentThreadableLoader::cancelWithError(const ResourceError& error) |
156 { | 179 { |
157 RefPtr<DocumentThreadableLoader> protect(this); | 180 RefPtr<DocumentThreadableLoader> protect(this); |
158 | 181 |
159 // Cancel can re-enter and m_resource might be null here as a result. | 182 // Cancel can re-enter and m_resource might be null here as a result. |
160 if (m_client && resource()) { | 183 if (m_client && resource()) { |
161 ResourceError errorForCallback = error; | 184 ResourceError errorForCallback = error; |
162 if (errorForCallback.isNull()) { | 185 if (errorForCallback.isNull()) { |
163 // FIXME: This error is sent to the client in didFail(), so it shoul d not be an internal one. Use FrameLoaderClient::cancelledError() instead. | 186 // FIXME: This error is sent to the client in didFail(), so it shoul d not be an internal one. Use FrameLoaderClient::cancelledError() instead. |
164 errorForCallback = ResourceError(errorDomainBlinkInternal, 0, resour ce()->url().string(), "Load cancelled"); | 187 errorForCallback = ResourceError(errorDomainBlinkInternal, 0, resour ce()->url().string(), "Load cancelled"); |
165 errorForCallback.setIsCancellation(true); | 188 errorForCallback.setIsCancellation(true); |
166 } | 189 } |
167 m_client->didFail(errorForCallback); | 190 m_client->didFail(errorForCallback); |
168 } | 191 } |
169 clearResource(); | 192 clearResource(); |
170 m_client = 0; | 193 m_client = 0; |
194 m_requestStartedSeconds = 0.0; | |
171 } | 195 } |
172 | 196 |
173 void DocumentThreadableLoader::setDefersLoading(bool value) | 197 void DocumentThreadableLoader::setDefersLoading(bool value) |
174 { | 198 { |
175 if (resource()) | 199 if (resource()) |
176 resource()->setDefersLoading(value); | 200 resource()->setDefersLoading(value); |
177 } | 201 } |
178 | 202 |
179 void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ est& request, const ResourceResponse& redirectResponse) | 203 void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ est& request, const ResourceResponse& redirectResponse) |
180 { | 204 { |
181 ASSERT(m_client); | 205 ASSERT(m_client); |
182 ASSERT_UNUSED(resource, resource == this->resource()); | 206 ASSERT_UNUSED(resource, resource == this->resource()); |
183 | 207 |
184 RefPtr<DocumentThreadableLoader> protect(this); | 208 RefPtr<DocumentThreadableLoader> protect(this); |
185 if (!isAllowedByPolicy(request.url())) { | 209 if (!isAllowedByPolicy(request.url())) { |
186 m_client->didFailRedirectCheck(); | 210 m_client->didFailRedirectCheck(); |
187 request = ResourceRequest(); | 211 request = ResourceRequest(); |
212 m_requestStartedSeconds = 0.0; | |
188 return; | 213 return; |
189 } | 214 } |
190 | 215 |
191 // Allow same origin requests to continue after allowing clients to audit th e redirect. | 216 // Allow same origin requests to continue after allowing clients to audit th e redirect. |
192 if (isAllowedRedirect(request.url())) { | 217 if (isAllowedRedirect(request.url())) { |
193 if (m_client->isDocumentThreadableLoaderClient()) | 218 if (m_client->isDocumentThreadableLoaderClient()) |
194 static_cast<DocumentThreadableLoaderClient*>(m_client)->willSendRequ est(request, redirectResponse); | 219 static_cast<DocumentThreadableLoaderClient*>(m_client)->willSendRequ est(request, redirectResponse); |
195 return; | 220 return; |
196 } | 221 } |
197 | 222 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
244 makeCrossOriginAccessRequest(request); | 269 makeCrossOriginAccessRequest(request); |
245 return; | 270 return; |
246 } | 271 } |
247 | 272 |
248 ResourceError error(errorDomainBlinkInternal, 0, redirectResponse.url(). string(), accessControlErrorDescription); | 273 ResourceError error(errorDomainBlinkInternal, 0, redirectResponse.url(). string(), accessControlErrorDescription); |
249 m_client->didFailAccessControlCheck(error); | 274 m_client->didFailAccessControlCheck(error); |
250 } else { | 275 } else { |
251 m_client->didFailRedirectCheck(); | 276 m_client->didFailRedirectCheck(); |
252 } | 277 } |
253 request = ResourceRequest(); | 278 request = ResourceRequest(); |
279 m_requestStartedSeconds = 0.0; | |
254 } | 280 } |
255 | 281 |
256 void DocumentThreadableLoader::dataSent(Resource* resource, unsigned long long b ytesSent, unsigned long long totalBytesToBeSent) | 282 void DocumentThreadableLoader::dataSent(Resource* resource, unsigned long long b ytesSent, unsigned long long totalBytesToBeSent) |
257 { | 283 { |
258 ASSERT(m_client); | 284 ASSERT(m_client); |
259 ASSERT_UNUSED(resource, resource == this->resource()); | 285 ASSERT_UNUSED(resource, resource == this->resource()); |
260 m_client->didSendData(bytesSent, totalBytesToBeSent); | 286 m_client->didSendData(bytesSent, totalBytesToBeSent); |
261 } | 287 } |
262 | 288 |
263 void DocumentThreadableLoader::dataDownloaded(Resource* resource, int dataLength ) | 289 void DocumentThreadableLoader::dataDownloaded(Resource* resource, int dataLength ) |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
355 else | 381 else |
356 handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime( )); | 382 handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime( )); |
357 } | 383 } |
358 | 384 |
359 void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier, double finishTime) | 385 void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier, double finishTime) |
360 { | 386 { |
361 if (m_actualRequest) { | 387 if (m_actualRequest) { |
362 ASSERT(!m_sameOriginRequest); | 388 ASSERT(!m_sameOriginRequest); |
363 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); | 389 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); |
364 loadActualRequest(); | 390 loadActualRequest(); |
365 } else | 391 } else { |
366 m_client->didFinishLoading(identifier, finishTime); | 392 m_client->didFinishLoading(identifier, finishTime); |
393 m_requestStartedSeconds = 0.0; | |
abarth-chromium
2014/06/22 00:22:48
There's no reason to believe |this| is still alive
caitp (gmail)
2014/06/22 00:56:14
Given that this is a non-static method, there prob
caitp (gmail)
2014/06/22 00:58:19
Unless you mean that `didFinishLoading()` might ki
tyoshino (SeeGerritForStatus)
2014/06/23 08:00:02
Sorry that I didn't catch this. Right, didFinishLo
caitp (gmail)
2014/06/23 15:55:44
It would have been hard to notice =)
I'm not sure
tyoshino (SeeGerritForStatus)
2014/06/24 05:55:34
Feel free to postpone this and leave FIXME explain
| |
394 } | |
367 } | 395 } |
368 | 396 |
369 void DocumentThreadableLoader::didTimeout(Timer<DocumentThreadableLoader>* timer ) | 397 void DocumentThreadableLoader::didTimeout(Timer<DocumentThreadableLoader>* timer ) |
370 { | 398 { |
371 ASSERT_UNUSED(timer, timer == &m_timeoutTimer); | 399 ASSERT_UNUSED(timer, timer == &m_timeoutTimer); |
372 | 400 |
373 // Using values from net/base/net_error_list.h ERR_TIMED_OUT, | 401 // Using values from net/base/net_error_list.h ERR_TIMED_OUT, |
374 // Same as existing FIXME above - this error should be coming from FrameLoad erClient to be identifiable. | 402 // Same as existing FIXME above - this error should be coming from FrameLoad erClient to be identifiable. |
375 static const int timeoutError = -7; | 403 static const int timeoutError = -7; |
376 ResourceError error("net", timeoutError, resource()->url(), String()); | 404 ResourceError error("net", timeoutError, resource()->url(), String()); |
(...skipping 16 matching lines...) Expand all Loading... | |
393 } | 421 } |
394 | 422 |
395 void DocumentThreadableLoader::handlePreflightFailure(const String& url, const S tring& errorDescription) | 423 void DocumentThreadableLoader::handlePreflightFailure(const String& url, const S tring& errorDescription) |
396 { | 424 { |
397 ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription); | 425 ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription); |
398 | 426 |
399 // Prevent handleSuccessfulFinish() from bypassing access check. | 427 // Prevent handleSuccessfulFinish() from bypassing access check. |
400 m_actualRequest = nullptr; | 428 m_actualRequest = nullptr; |
401 | 429 |
402 m_client->didFailAccessControlCheck(error); | 430 m_client->didFailAccessControlCheck(error); |
431 m_requestStartedSeconds = 0.0; | |
tyoshino (SeeGerritForStatus)
2014/06/23 08:00:02
ditto
| |
403 } | 432 } |
404 | 433 |
405 void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Resou rceLoaderOptions resourceLoaderOptions) | 434 void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Resou rceLoaderOptions resourceLoaderOptions) |
406 { | 435 { |
407 // Any credential should have been removed from the cross-site requests. | 436 // Any credential should have been removed from the cross-site requests. |
408 const KURL& requestURL = request.url(); | 437 const KURL& requestURL = request.url(); |
409 ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); | 438 ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); |
410 ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty()); | 439 ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty()); |
411 | 440 |
412 // Update resourceLoaderOptions with enforced values. | 441 // Update resourceLoaderOptions with enforced values. |
(...skipping 25 matching lines...) Expand all Loading... | |
438 FetchRequest fetchRequest(request, m_options.initiator, resourceLoaderOption s); | 467 FetchRequest fetchRequest(request, m_options.initiator, resourceLoaderOption s); |
439 ResourcePtr<Resource> resource = m_document.fetcher()->fetchSynchronously(fe tchRequest); | 468 ResourcePtr<Resource> resource = m_document.fetcher()->fetchSynchronously(fe tchRequest); |
440 ResourceResponse response = resource ? resource->response() : ResourceRespon se(); | 469 ResourceResponse response = resource ? resource->response() : ResourceRespon se(); |
441 unsigned long identifier = resource ? resource->identifier() : std::numeric_ limits<unsigned long>::max(); | 470 unsigned long identifier = resource ? resource->identifier() : std::numeric_ limits<unsigned long>::max(); |
442 ResourceError error = resource ? resource->resourceError() : ResourceError() ; | 471 ResourceError error = resource ? resource->resourceError() : ResourceError() ; |
443 | 472 |
444 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(&m _document, identifier, m_client); | 473 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(&m _document, identifier, m_client); |
445 | 474 |
446 if (!resource) { | 475 if (!resource) { |
447 m_client->didFail(error); | 476 m_client->didFail(error); |
477 m_requestStartedSeconds = 0.0; // Unnecessary for synchronous request, b ut for API consistency. | |
448 return; | 478 return; |
449 } | 479 } |
450 | 480 |
451 // No exception for file:/// resources, see <rdar://problem/4962298>. | 481 // No exception for file:/// resources, see <rdar://problem/4962298>. |
452 // Also, if we have an HTTP response, then it wasn't a network error in fact . | 482 // Also, if we have an HTTP response, then it wasn't a network error in fact . |
453 if (!error.isNull() && !requestURL.isLocalFile() && response.httpStatusCode( ) <= 0) { | 483 if (!error.isNull() && !requestURL.isLocalFile() && response.httpStatusCode( ) <= 0) { |
454 m_client->didFail(error); | 484 m_client->didFail(error); |
455 return; | 485 return; |
456 } | 486 } |
457 | 487 |
458 // FIXME: A synchronous request does not tell us whether a redirect happened or not, so we guess by comparing the | 488 // FIXME: A synchronous request does not tell us whether a redirect happened or not, so we guess by comparing the |
459 // request and response URLs. This isn't a perfect test though, since a serv er can serve a redirect to the same URL that was | 489 // request and response URLs. This isn't a perfect test though, since a serv er can serve a redirect to the same URL that was |
460 // requested. Also comparing the request and response URLs as strings will f ail if the requestURL still has its credentials. | 490 // requested. Also comparing the request and response URLs as strings will f ail if the requestURL still has its credentials. |
461 if (requestURL != response.url() && (!isAllowedByPolicy(response.url()) || ! isAllowedRedirect(response.url()))) { | 491 if (requestURL != response.url() && (!isAllowedByPolicy(response.url()) || ! isAllowedRedirect(response.url()))) { |
462 m_client->didFailRedirectCheck(); | 492 m_client->didFailRedirectCheck(); |
493 m_requestStartedSeconds = 0.0; // Unnecessary for synchronous request, b ut for API consistency. | |
463 return; | 494 return; |
464 } | 495 } |
465 | 496 |
466 handleResponse(identifier, response); | 497 handleResponse(identifier, response); |
467 | 498 |
468 SharedBuffer* data = resource->resourceBuffer(); | 499 SharedBuffer* data = resource->resourceBuffer(); |
469 if (data) | 500 if (data) |
470 handleReceivedData(data->data(), data->size()); | 501 handleReceivedData(data->data(), data->size()); |
471 | 502 |
472 handleSuccessfulFinish(identifier, 0.0); | 503 handleSuccessfulFinish(identifier, 0.0); |
(...skipping 20 matching lines...) Expand all Loading... | |
493 return DoNotAllowStoredCredentials; | 524 return DoNotAllowStoredCredentials; |
494 return m_resourceLoaderOptions.allowCredentials; | 525 return m_resourceLoaderOptions.allowCredentials; |
495 } | 526 } |
496 | 527 |
497 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const | 528 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const |
498 { | 529 { |
499 return m_securityOrigin ? m_securityOrigin.get() : m_document.securityOrigin (); | 530 return m_securityOrigin ? m_securityOrigin.get() : m_document.securityOrigin (); |
500 } | 531 } |
501 | 532 |
502 } // namespace WebCore | 533 } // namespace WebCore |
OLD | NEW |