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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
138 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) | 138 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) |
139 , m_requestStartedSeconds(0.0) | 139 , m_requestStartedSeconds(0.0) |
140 , m_corsRedirectLimit(kMaxCORSRedirects) | 140 , m_corsRedirectLimit(kMaxCORSRedirects) |
141 , m_redirectMode(request.fetchRedirectMode()) | 141 , m_redirectMode(request.fetchRedirectMode()) |
142 { | 142 { |
143 ASSERT(client); | 143 ASSERT(client); |
144 // Setting an outgoing referer is only supported in the async code path. | 144 // Setting an outgoing referer is only supported in the async code path. |
145 ASSERT(m_async || request.httpReferrer().isEmpty()); | 145 ASSERT(m_async || request.httpReferrer().isEmpty()); |
146 | 146 |
147 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == DenyCrossO riginRequests) { | 147 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == DenyCrossO riginRequests) { |
148 m_client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url ().string(), "Cross origin requests are not supported.")); | 148 ThreadableLoaderClient* client = m_client; |
149 clear(); | |
150 client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url() .string(), "Cross origin requests are not supported.")); | |
151 // |this| may be dead here. | |
149 return; | 152 return; |
150 } | 153 } |
151 | 154 |
152 m_requestStartedSeconds = monotonicallyIncreasingTime(); | 155 m_requestStartedSeconds = monotonicallyIncreasingTime(); |
153 | 156 |
154 // Save any CORS simple headers on the request here. If this request redirec ts cross-origin, we cancel the old request | 157 // Save any CORS simple headers on the request here. If this request redirec ts cross-origin, we cancel the old request |
155 // create a new one, and copy these headers. | 158 // create a new one, and copy these headers. |
156 const HTTPHeaderMap& headerMap = request.httpHeaderFields(); | 159 const HTTPHeaderMap& headerMap = request.httpHeaderFields(); |
157 for (const auto& header : headerMap) { | 160 for (const auto& header : headerMap) { |
158 if (FetchUtils::isSimpleHeader(header.key, header.value)) | 161 if (FetchUtils::isSimpleHeader(header.key, header.value)) |
(...skipping 20 matching lines...) Expand all Loading... | |
179 newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORS); | 182 newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORS); |
180 | 183 |
181 m_fallbackRequestForServiceWorker = adoptPtr(new ResourceRequest(request )); | 184 m_fallbackRequestForServiceWorker = adoptPtr(new ResourceRequest(request )); |
182 m_fallbackRequestForServiceWorker->setSkipServiceWorker(true); | 185 m_fallbackRequestForServiceWorker->setSkipServiceWorker(true); |
183 | 186 |
184 loadRequest(newRequest, m_resourceLoaderOptions); | 187 loadRequest(newRequest, m_resourceLoaderOptions); |
185 return; | 188 return; |
186 } | 189 } |
187 | 190 |
188 dispatchInitialRequest(request); | 191 dispatchInitialRequest(request); |
192 // |this| may be dead here in async mode. | |
189 } | 193 } |
190 | 194 |
191 void DocumentThreadableLoader::dispatchInitialRequest(const ResourceRequest& req uest) | 195 void DocumentThreadableLoader::dispatchInitialRequest(const ResourceRequest& req uest) |
192 { | 196 { |
193 if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossO riginRequests) { | 197 if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossO riginRequests) { |
194 loadRequest(request, m_resourceLoaderOptions); | 198 loadRequest(request, m_resourceLoaderOptions); |
195 return; | 199 return; |
196 } | 200 } |
197 | 201 |
198 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); | 202 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); |
199 | 203 |
200 makeCrossOriginAccessRequest(request); | 204 makeCrossOriginAccessRequest(request); |
205 // |this| may be dead here in async mode. | |
201 } | 206 } |
202 | 207 |
203 void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques t& request) | 208 void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques t& request) |
204 { | 209 { |
205 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); | 210 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); |
211 ASSERT(m_client); | |
212 ASSERT(!resource()); | |
206 | 213 |
207 // Cross-origin requests are only allowed certain registered schemes. | 214 // Cross-origin requests are only allowed certain registered schemes. |
208 // We would catch this when checking response headers later, but there | 215 // We would catch this when checking response headers later, but there |
209 // is no reason to send a request, preflighted or not, that's guaranteed | 216 // is no reason to send a request, preflighted or not, that's guaranteed |
210 // to be denied. | 217 // to be denied. |
211 if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protoco l())) { | 218 if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protoco l())) { |
212 m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkIntern al, 0, request.url().string(), "Cross origin requests are only supported for pro tocol schemes: " + SchemeRegistry::listOfCORSEnabledURLSchemes() + ".")); | 219 ThreadableLoaderClient* client = m_client; |
220 clear(); | |
221 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal , 0, request.url().string(), "Cross origin requests are only supported for proto col schemes: " + SchemeRegistry::listOfCORSEnabledURLSchemes() + ".")); | |
222 // |this| may be dead here in async mode. | |
213 return; | 223 return; |
214 } | 224 } |
215 | 225 |
216 // We use isSimpleOrForbiddenRequest() here since |request| may have been | 226 // We use isSimpleOrForbiddenRequest() here since |request| may have been |
217 // modified in the process of loading (not from the user's input). For | 227 // modified in the process of loading (not from the user's input). For |
218 // example, referrer. We need to accept them. For security, we must reject | 228 // example, referrer. We need to accept them. For security, we must reject |
219 // forbidden headers/methods at the point we accept user's input. Not here. | 229 // forbidden headers/methods at the point we accept user's input. Not here. |
220 if ((m_options.preflightPolicy == ConsiderPreflight && FetchUtils::isSimpleO rForbiddenRequest(request.httpMethod(), request.httpHeaderFields())) || m_option s.preflightPolicy == PreventPreflight) { | 230 if ((m_options.preflightPolicy == ConsiderPreflight && FetchUtils::isSimpleO rForbiddenRequest(request.httpMethod(), request.httpHeaderFields())) || m_option s.preflightPolicy == PreventPreflight) { |
221 ResourceRequest crossOriginRequest(request); | 231 ResourceRequest crossOriginRequest(request); |
222 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); | 232 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 double elapsedTime = monotonicallyIncreasingTime() - m_requestStartedSec onds; | 276 double elapsedTime = monotonicallyIncreasingTime() - m_requestStartedSec onds; |
267 double nextFire = timeoutMilliseconds / 1000.0; | 277 double nextFire = timeoutMilliseconds / 1000.0; |
268 double resolvedTime = std::max(nextFire - elapsedTime, 0.0); | 278 double resolvedTime = std::max(nextFire - elapsedTime, 0.0); |
269 m_timeoutTimer.startOneShot(resolvedTime, FROM_HERE); | 279 m_timeoutTimer.startOneShot(resolvedTime, FROM_HERE); |
270 } | 280 } |
271 } | 281 } |
272 | 282 |
273 void DocumentThreadableLoader::cancel() | 283 void DocumentThreadableLoader::cancel() |
274 { | 284 { |
275 cancelWithError(ResourceError()); | 285 cancelWithError(ResourceError()); |
286 // |this| may be dead here. | |
276 } | 287 } |
277 | 288 |
278 void DocumentThreadableLoader::cancelWithError(const ResourceError& error) | 289 void DocumentThreadableLoader::cancelWithError(const ResourceError& error) |
279 { | 290 { |
280 RefPtr<DocumentThreadableLoader> protect(this); | 291 // Cancel can re-enter and m_resource might be null here as a result. |
292 if (!m_client || !resource()) { | |
293 clear(); | |
294 return; | |
295 } | |
281 | 296 |
282 // Cancel can re-enter and m_resource might be null here as a result. | 297 ResourceError errorForCallback = error; |
283 if (m_client && resource()) { | 298 if (errorForCallback.isNull()) { |
284 ResourceError errorForCallback = error; | 299 // FIXME: This error is sent to the client in didFail(), so it should no t be an internal one. Use FrameLoaderClient::cancelledError() instead. |
285 if (errorForCallback.isNull()) { | 300 errorForCallback = ResourceError(errorDomainBlinkInternal, 0, resource() ->url().string(), "Load cancelled"); |
286 // FIXME: This error is sent to the client in didFail(), so it shoul d not be an internal one. Use FrameLoaderClient::cancelledError() instead. | 301 errorForCallback.setIsCancellation(true); |
287 errorForCallback = ResourceError(errorDomainBlinkInternal, 0, resour ce()->url().string(), "Load cancelled"); | |
288 errorForCallback.setIsCancellation(true); | |
289 } | |
290 m_client->didFail(errorForCallback); | |
291 } | 302 } |
292 clearResource(); | 303 |
293 m_client = 0; | 304 ThreadableLoaderClient* client = m_client; |
294 m_requestStartedSeconds = 0.0; | 305 clear(); |
306 client->didFail(errorForCallback); | |
307 // |this| may be dead here in async mode. | |
295 } | 308 } |
296 | 309 |
297 void DocumentThreadableLoader::setDefersLoading(bool value) | 310 void DocumentThreadableLoader::setDefersLoading(bool value) |
298 { | 311 { |
299 if (resource()) | 312 if (resource()) |
300 resource()->setDefersLoading(value); | 313 resource()->setDefersLoading(value); |
301 } | 314 } |
302 | 315 |
316 void DocumentThreadableLoader::clear() | |
317 { | |
318 m_client = 0; | |
319 | |
320 if (!m_async) | |
321 return; | |
322 | |
323 clearResource(); | |
324 m_timeoutTimer.stop(); | |
325 m_requestStartedSeconds = 0.0; | |
326 } | |
327 | |
303 // In this method, we can clear |request| to tell content::WebURLLoaderImpl of | 328 // In this method, we can clear |request| to tell content::WebURLLoaderImpl of |
304 // Chromium not to follow the redirect. This works only when this method is | 329 // Chromium not to follow the redirect. This works only when this method is |
305 // called by RawResource::willSendRequest(). If called by | 330 // called by RawResource::willSendRequest(). If called by |
306 // RawResource::didAddClient(), clearing |request| won't be propagated | 331 // RawResource::didAddClient(), clearing |request| won't be propagated |
307 // to content::WebURLLoaderImpl. So, this loader must also get detached from | 332 // to content::WebURLLoaderImpl. So, this loader must also get detached from |
308 // the resource by calling clearResource(). | 333 // the resource by calling clearResource(). |
309 void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ est& request, const ResourceResponse& redirectResponse) | 334 void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ est& request, const ResourceResponse& redirectResponse) |
310 { | 335 { |
311 ASSERT(m_client); | 336 ASSERT(m_client); |
312 ASSERT_UNUSED(resource, resource == this->resource()); | 337 ASSERT_UNUSED(resource, resource == this->resource()); |
313 ASSERT(m_async); | 338 ASSERT(m_async); |
314 | 339 |
315 RefPtr<DocumentThreadableLoader> protect(this); | 340 RefPtr<DocumentThreadableLoader> protect(this); |
hiroshige
2015/09/15 08:54:16
Is this |protect| needed?
(This |protect| is remov
tyoshino (SeeGerritForStatus)
2015/09/15 13:29:34
Seems accidentally re-introduced on merge.
But it
| |
316 | 341 |
317 if (m_actualRequest) { | 342 if (m_actualRequest) { |
318 reportResponseReceived(resource->identifier(), redirectResponse); | 343 reportResponseReceived(resource->identifier(), redirectResponse); |
319 | 344 |
320 clearResource(); | 345 handlePreflightFailure(redirectResponse.url().string(), "Response for pr eflight is invalid (redirect)"); |
346 // |this| may be dead here. | |
347 | |
321 request = ResourceRequest(); | 348 request = ResourceRequest(); |
322 | 349 |
323 m_requestStartedSeconds = 0.0; | |
324 | |
325 handlePreflightFailure(redirectResponse.url().string(), "Response for pr eflight is invalid (redirect)"); | |
326 | |
327 return; | 350 return; |
328 } | 351 } |
329 | 352 |
330 if (m_redirectMode == WebURLRequest::FetchRedirectModeManual) { | 353 if (m_redirectMode == WebURLRequest::FetchRedirectModeManual) { |
331 // We use |m_redirectMode| to check the original redirect mode. | 354 // We use |m_redirectMode| to check the original redirect mode. |
332 // |request| is a new request for redirect. So we don't set the redirect | 355 // |request| is a new request for redirect. So we don't set the redirect |
333 // mode of it in WebURLLoaderImpl::Context::OnReceivedRedirect(). | 356 // mode of it in WebURLLoaderImpl::Context::OnReceivedRedirect(). |
334 ASSERT(request.useStreamOnResponse()); | 357 ASSERT(request.useStreamOnResponse()); |
335 // There is no need to read the body of redirect response because there | 358 // There is no need to read the body of redirect response because there |
336 // is no way to read the body of opaque-redirect filtered response's | 359 // is no way to read the body of opaque-redirect filtered response's |
337 // internal response. | 360 // internal response. |
338 // TODO(horo): If we support any API which expose the internal body, we | 361 // TODO(horo): If we support any API which expose the internal body, we |
339 // will have to read the body. And also HTTPCache changes will be needed | 362 // will have to read the body. And also HTTPCache changes will be needed |
340 // because it doesn't store the body of redirect responses. | 363 // because it doesn't store the body of redirect responses. |
341 responseReceived(resource, redirectResponse, adoptPtr(new EmptyDataHandl e())); | 364 responseReceived(resource, redirectResponse, adoptPtr(new EmptyDataHandl e())); |
342 notifyFinished(resource); | 365 |
343 clearResource(); | 366 if (resource->errorOccurred()) { |
hiroshige
2015/09/15 08:54:17
What is the reason for calling handleError() / han
tyoshino (SeeGerritForStatus)
2015/09/15 13:29:34
Ah, after refactoring they became identical. Rever
| |
367 handleError(resource->resourceError()); | |
368 // |this| may be dead here. | |
369 } else { | |
370 handleSuccessfulActualRequestFinish(resource->identifier(), resource ->loadFinishTime()); | |
371 // |this| may be dead here. | |
372 } | |
373 | |
344 request = ResourceRequest(); | 374 request = ResourceRequest(); |
375 | |
345 return; | 376 return; |
346 } | 377 } |
347 | 378 |
348 if (m_redirectMode == WebURLRequest::FetchRedirectModeError || !isAllowedByC ontentSecurityPolicy(request.url(), ContentSecurityPolicy::DidRedirect)) { | 379 if (m_redirectMode == WebURLRequest::FetchRedirectModeError || !isAllowedByC ontentSecurityPolicy(request.url(), ContentSecurityPolicy::DidRedirect)) { |
349 m_client->didFailRedirectCheck(); | 380 ThreadableLoaderClient* client = m_client; |
381 clear(); | |
382 client->didFailRedirectCheck(); | |
383 // |this| may be dead here. | |
350 | 384 |
351 clearResource(); | |
352 request = ResourceRequest(); | 385 request = ResourceRequest(); |
353 | 386 |
354 m_requestStartedSeconds = 0.0; | |
355 return; | 387 return; |
356 } | 388 } |
357 | 389 |
358 // Allow same origin requests to continue after allowing clients to audit th e redirect. | 390 // Allow same origin requests to continue after allowing clients to audit th e redirect. |
359 if (isAllowedRedirect(request.url())) { | 391 if (isAllowedRedirect(request.url())) { |
360 if (m_client->isDocumentThreadableLoaderClient()) | 392 if (m_client->isDocumentThreadableLoaderClient()) |
361 static_cast<DocumentThreadableLoaderClient*>(m_client)->willFollowRe direct(request, redirectResponse); | 393 static_cast<DocumentThreadableLoaderClient*>(m_client)->willFollowRe direct(request, redirectResponse); |
362 return; | 394 return; |
363 } | 395 } |
364 | 396 |
365 if (m_corsRedirectLimit <= 0) { | 397 if (m_corsRedirectLimit <= 0) { |
366 m_client->didFailRedirectCheck(); | 398 ThreadableLoaderClient* client = m_client; |
399 clear(); | |
400 client->didFailRedirectCheck(); | |
401 // |this| may be dead here. | |
367 } else if (m_options.crossOriginRequestPolicy == UseAccessControl) { | 402 } else if (m_options.crossOriginRequestPolicy == UseAccessControl) { |
368 --m_corsRedirectLimit; | 403 --m_corsRedirectLimit; |
369 | 404 |
370 InspectorInstrumentation::didReceiveCORSRedirectResponse(m_document.fram e(), resource->identifier(), m_document.frame()->loader().documentLoader(), redi rectResponse, 0); | 405 InspectorInstrumentation::didReceiveCORSRedirectResponse(m_document.fram e(), resource->identifier(), m_document.frame()->loader().documentLoader(), redi rectResponse, 0); |
371 | 406 |
372 bool allowRedirect = false; | 407 bool allowRedirect = false; |
373 String accessControlErrorDescription; | 408 String accessControlErrorDescription; |
374 | 409 |
375 // Non-simple cross origin requests (both preflight and actual one) are | 410 // Non-simple cross origin requests (both preflight and actual one) are |
376 // not allowed to follow redirect. | 411 // not allowed to follow redirect. |
(...skipping 27 matching lines...) Expand all Loading... | |
404 m_forceDoNotAllowStoredCredentials = true; | 439 m_forceDoNotAllowStoredCredentials = true; |
405 | 440 |
406 // Remove any headers that may have been added by the network layer that cause access control to fail. | 441 // Remove any headers that may have been added by the network layer that cause access control to fail. |
407 request.clearHTTPReferrer(); | 442 request.clearHTTPReferrer(); |
408 request.clearHTTPOrigin(); | 443 request.clearHTTPOrigin(); |
409 request.clearHTTPUserAgent(); | 444 request.clearHTTPUserAgent(); |
410 // Add any CORS simple request headers which we previously saved fro m the original request. | 445 // Add any CORS simple request headers which we previously saved fro m the original request. |
411 for (const auto& header : m_simpleRequestHeaders) | 446 for (const auto& header : m_simpleRequestHeaders) |
412 request.setHTTPHeaderField(header.key, header.value); | 447 request.setHTTPHeaderField(header.key, header.value); |
413 makeCrossOriginAccessRequest(request); | 448 makeCrossOriginAccessRequest(request); |
449 // |this| may be dead here. | |
414 return; | 450 return; |
415 } | 451 } |
416 | 452 |
417 ResourceError error(errorDomainBlinkInternal, 0, redirectResponse.url(). string(), accessControlErrorDescription); | 453 ThreadableLoaderClient* client = m_client; |
418 m_client->didFailAccessControlCheck(error); | 454 clear(); |
455 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal , 0, redirectResponse.url().string(), accessControlErrorDescription)); | |
456 // |this| may be dead here. | |
419 } else { | 457 } else { |
420 m_client->didFailRedirectCheck(); | 458 ThreadableLoaderClient* client = m_client; |
459 clear(); | |
460 client->didFailRedirectCheck(); | |
461 // |this| may be dead here. | |
421 } | 462 } |
422 | 463 |
423 clearResource(); | |
424 request = ResourceRequest(); | 464 request = ResourceRequest(); |
425 | |
426 m_requestStartedSeconds = 0.0; | |
427 } | 465 } |
428 | 466 |
429 void DocumentThreadableLoader::dataSent(Resource* resource, unsigned long long b ytesSent, unsigned long long totalBytesToBeSent) | 467 void DocumentThreadableLoader::dataSent(Resource* resource, unsigned long long b ytesSent, unsigned long long totalBytesToBeSent) |
430 { | 468 { |
431 ASSERT(m_client); | 469 ASSERT(m_client); |
432 ASSERT_UNUSED(resource, resource == this->resource()); | 470 ASSERT_UNUSED(resource, resource == this->resource()); |
433 ASSERT(m_async); | 471 ASSERT(m_async); |
434 | 472 |
435 m_client->didSendData(bytesSent, totalBytesToBeSent); | 473 m_client->didSendData(bytesSent, totalBytesToBeSent); |
474 // |this| may be dead here. | |
436 } | 475 } |
437 | 476 |
438 void DocumentThreadableLoader::dataDownloaded(Resource* resource, int dataLength ) | 477 void DocumentThreadableLoader::dataDownloaded(Resource* resource, int dataLength ) |
439 { | 478 { |
440 ASSERT(m_client); | 479 ASSERT(m_client); |
441 ASSERT_UNUSED(resource, resource == this->resource()); | 480 ASSERT_UNUSED(resource, resource == this->resource()); |
442 ASSERT(!m_actualRequest); | 481 ASSERT(!m_actualRequest); |
443 ASSERT(m_async); | 482 ASSERT(m_async); |
444 | 483 |
445 m_client->didDownloadData(dataLength); | 484 m_client->didDownloadData(dataLength); |
485 // |this| may be dead here. | |
446 } | 486 } |
447 | 487 |
448 void DocumentThreadableLoader::didReceiveResourceTiming(Resource* resource, cons t ResourceTimingInfo& info) | 488 void DocumentThreadableLoader::didReceiveResourceTiming(Resource* resource, cons t ResourceTimingInfo& info) |
449 { | 489 { |
450 ASSERT(m_client); | 490 ASSERT(m_client); |
451 ASSERT_UNUSED(resource, resource == this->resource()); | 491 ASSERT_UNUSED(resource, resource == this->resource()); |
452 ASSERT(m_async); | 492 ASSERT(m_async); |
453 | 493 |
454 m_client->didReceiveResourceTiming(info); | 494 m_client->didReceiveResourceTiming(info); |
495 // |this| may be dead here. | |
455 } | 496 } |
456 | 497 |
457 void DocumentThreadableLoader::responseReceived(Resource* resource, const Resour ceResponse& response, PassOwnPtr<WebDataConsumerHandle> handle) | 498 void DocumentThreadableLoader::responseReceived(Resource* resource, const Resour ceResponse& response, PassOwnPtr<WebDataConsumerHandle> handle) |
458 { | 499 { |
459 ASSERT_UNUSED(resource, resource == this->resource()); | 500 ASSERT_UNUSED(resource, resource == this->resource()); |
460 ASSERT(m_async); | 501 ASSERT(m_async); |
461 | 502 |
462 if (handle) | 503 if (handle) |
463 m_isUsingDataConsumerHandle = true; | 504 m_isUsingDataConsumerHandle = true; |
464 | 505 |
465 handleResponse(resource->identifier(), response, handle); | 506 handleResponse(resource->identifier(), response, handle); |
507 // |this| may be dead here. | |
466 } | 508 } |
467 | 509 |
468 void DocumentThreadableLoader::handlePreflightResponse(const ResourceResponse& r esponse) | 510 void DocumentThreadableLoader::handlePreflightResponse(const ResourceResponse& r esponse) |
469 { | 511 { |
470 String accessControlErrorDescription; | 512 String accessControlErrorDescription; |
471 | 513 |
472 if (!passesAccessControlCheck(response, effectiveAllowCredentials(), securit yOrigin(), accessControlErrorDescription, m_requestContext)) { | 514 if (!passesAccessControlCheck(response, effectiveAllowCredentials(), securit yOrigin(), accessControlErrorDescription, m_requestContext)) { |
473 handlePreflightFailure(response.url().string(), "Response to preflight r equest doesn't pass access control check: " + accessControlErrorDescription); | 515 handlePreflightFailure(response.url().string(), "Response to preflight r equest doesn't pass access control check: " + accessControlErrorDescription); |
516 // |this| may be dead here in async mode. | |
474 return; | 517 return; |
475 } | 518 } |
476 | 519 |
477 if (!passesPreflightStatusCheck(response, accessControlErrorDescription)) { | 520 if (!passesPreflightStatusCheck(response, accessControlErrorDescription)) { |
478 handlePreflightFailure(response.url().string(), accessControlErrorDescri ption); | 521 handlePreflightFailure(response.url().string(), accessControlErrorDescri ption); |
522 // |this| may be dead here in async mode. | |
479 return; | 523 return; |
480 } | 524 } |
481 | 525 |
482 OwnPtr<CrossOriginPreflightResultCacheItem> preflightResult = adoptPtr(new C rossOriginPreflightResultCacheItem(effectiveAllowCredentials())); | 526 OwnPtr<CrossOriginPreflightResultCacheItem> preflightResult = adoptPtr(new C rossOriginPreflightResultCacheItem(effectiveAllowCredentials())); |
483 if (!preflightResult->parse(response, accessControlErrorDescription) | 527 if (!preflightResult->parse(response, accessControlErrorDescription) |
484 || !preflightResult->allowsCrossOriginMethod(m_actualRequest->httpMethod (), accessControlErrorDescription) | 528 || !preflightResult->allowsCrossOriginMethod(m_actualRequest->httpMethod (), accessControlErrorDescription) |
485 || !preflightResult->allowsCrossOriginHeaders(m_actualRequest->httpHeade rFields(), accessControlErrorDescription)) { | 529 || !preflightResult->allowsCrossOriginHeaders(m_actualRequest->httpHeade rFields(), accessControlErrorDescription)) { |
486 handlePreflightFailure(response.url().string(), accessControlErrorDescri ption); | 530 handlePreflightFailure(response.url().string(), accessControlErrorDescri ption); |
531 // |this| may be dead here in async mode. | |
487 return; | 532 return; |
488 } | 533 } |
489 | 534 |
490 CrossOriginPreflightResultCache::shared().appendEntry(securityOrigin()->toSt ring(), m_actualRequest->url(), preflightResult.release()); | 535 CrossOriginPreflightResultCache::shared().appendEntry(securityOrigin()->toSt ring(), m_actualRequest->url(), preflightResult.release()); |
491 } | 536 } |
492 | 537 |
493 void DocumentThreadableLoader::reportResponseReceived(unsigned long identifier, const ResourceResponse& response) | 538 void DocumentThreadableLoader::reportResponseReceived(unsigned long identifier, const ResourceResponse& response) |
494 { | 539 { |
495 DocumentLoader* loader = m_document.frame()->loader().documentLoader(); | 540 DocumentLoader* loader = m_document.frame()->loader().documentLoader(); |
496 TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceReceiveResponse", TRACE_E VENT_SCOPE_THREAD, "data", InspectorReceiveResponseEvent::data(identifier, m_doc ument.frame(), response)); | 541 TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceReceiveResponse", TRACE_E VENT_SCOPE_THREAD, "data", InspectorReceiveResponseEvent::data(identifier, m_doc ument.frame(), response)); |
497 LocalFrame* frame = m_document.frame(); | 542 LocalFrame* frame = m_document.frame(); |
498 InspectorInstrumentation::didReceiveResourceResponse(frame, identifier, load er, response, resource() ? resource()->loader() : 0); | 543 InspectorInstrumentation::didReceiveResourceResponse(frame, identifier, load er, response, resource() ? resource()->loader() : 0); |
499 frame->console().reportResourceResponseReceived(loader, identifier, response ); | 544 frame->console().reportResourceResponseReceived(loader, identifier, response ); |
500 } | 545 } |
501 | 546 |
502 void DocumentThreadableLoader::handleResponse(unsigned long identifier, const Re sourceResponse& response, PassOwnPtr<WebDataConsumerHandle> handle) | 547 void DocumentThreadableLoader::handleResponse(unsigned long identifier, const Re sourceResponse& response, PassOwnPtr<WebDataConsumerHandle> handle) |
503 { | 548 { |
504 ASSERT(m_client); | 549 ASSERT(m_client); |
505 | 550 |
506 if (m_actualRequest) { | 551 if (m_actualRequest) { |
507 reportResponseReceived(identifier, response); | 552 reportResponseReceived(identifier, response); |
508 handlePreflightResponse(response); | 553 handlePreflightResponse(response); |
554 // |this| may be dead here in async mode. | |
509 return; | 555 return; |
510 } | 556 } |
511 | 557 |
512 if (response.wasFetchedViaServiceWorker()) { | 558 if (response.wasFetchedViaServiceWorker()) { |
513 // It's still possible to reach here with null m_fallbackRequestForServi ceWorker | 559 // It's still possible to reach here with null m_fallbackRequestForServi ceWorker |
514 // if the request was for main resource loading (i.e. for SharedWorker), for which | 560 // if the request was for main resource loading (i.e. for SharedWorker), for which |
515 // we create DocumentLoader before the controller ServiceWorker is set. | 561 // we create DocumentLoader before the controller ServiceWorker is set. |
516 ASSERT(m_fallbackRequestForServiceWorker || m_requestContext == WebURLRe quest::RequestContextSharedWorker); | 562 ASSERT(m_fallbackRequestForServiceWorker || m_requestContext == WebURLRe quest::RequestContextSharedWorker); |
517 if (response.wasFallbackRequiredByServiceWorker()) { | 563 if (response.wasFallbackRequiredByServiceWorker()) { |
518 // At this point we must have m_fallbackRequestForServiceWorker. | 564 // At this point we must have m_fallbackRequestForServiceWorker. |
519 // (For SharedWorker the request won't be CORS or CORS-with-prefligh t, | 565 // (For SharedWorker the request won't be CORS or CORS-with-prefligh t, |
520 // therefore fallback-to-network is handled in the browser process | 566 // therefore fallback-to-network is handled in the browser process |
521 // when the ServiceWorker does not call respondWith().) | 567 // when the ServiceWorker does not call respondWith().) |
522 ASSERT(m_fallbackRequestForServiceWorker); | 568 ASSERT(m_fallbackRequestForServiceWorker); |
523 reportResponseReceived(identifier, response); | 569 reportResponseReceived(identifier, response); |
524 loadFallbackRequestForServiceWorker(); | 570 loadFallbackRequestForServiceWorker(); |
571 // |this| may be dead here in async mode. | |
525 return; | 572 return; |
526 } | 573 } |
527 m_fallbackRequestForServiceWorker = nullptr; | 574 m_fallbackRequestForServiceWorker = nullptr; |
528 m_client->didReceiveResponse(identifier, response, handle); | 575 m_client->didReceiveResponse(identifier, response, handle); |
529 return; | 576 return; |
530 } | 577 } |
531 | 578 |
532 // Even if the request met the conditions to get handled by a Service Worker | 579 // Even if the request met the conditions to get handled by a Service Worker |
533 // in the constructor of this class (and therefore | 580 // in the constructor of this class (and therefore |
534 // |m_fallbackRequestForServiceWorker| is set), the Service Worker may skip | 581 // |m_fallbackRequestForServiceWorker| is set), the Service Worker may skip |
535 // processing the request. Only if the request is same origin, the skipped | 582 // processing the request. Only if the request is same origin, the skipped |
536 // response may come here (wasFetchedViaServiceWorker() returns false) since | 583 // response may come here (wasFetchedViaServiceWorker() returns false) since |
537 // such a request doesn't have to go through the CORS algorithm by calling | 584 // such a request doesn't have to go through the CORS algorithm by calling |
538 // loadFallbackRequestForServiceWorker(). | 585 // loadFallbackRequestForServiceWorker(). |
539 // FIXME: We should use |m_sameOriginRequest| when we will support | 586 // FIXME: We should use |m_sameOriginRequest| when we will support |
540 // Suborigins (crbug.com/336894) for Service Worker. | 587 // Suborigins (crbug.com/336894) for Service Worker. |
541 ASSERT(!m_fallbackRequestForServiceWorker || securityOrigin()->canRequest(m_ fallbackRequestForServiceWorker->url())); | 588 ASSERT(!m_fallbackRequestForServiceWorker || securityOrigin()->canRequest(m_ fallbackRequestForServiceWorker->url())); |
542 m_fallbackRequestForServiceWorker = nullptr; | 589 m_fallbackRequestForServiceWorker = nullptr; |
543 | 590 |
544 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessC ontrol) { | 591 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessC ontrol) { |
545 String accessControlErrorDescription; | 592 String accessControlErrorDescription; |
546 if (!passesAccessControlCheck(response, effectiveAllowCredentials(), sec urityOrigin(), accessControlErrorDescription, m_requestContext)) { | 593 if (!passesAccessControlCheck(response, effectiveAllowCredentials(), sec urityOrigin(), accessControlErrorDescription, m_requestContext)) { |
547 reportResponseReceived(identifier, response); | 594 reportResponseReceived(identifier, response); |
548 m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkIn ternal, 0, response.url().string(), accessControlErrorDescription)); | 595 |
596 ThreadableLoaderClient* client = m_client; | |
597 clear(); | |
598 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInte rnal, 0, response.url().string(), accessControlErrorDescription)); | |
599 // |this| may be dead here. | |
549 return; | 600 return; |
550 } | 601 } |
551 } | 602 } |
552 | 603 |
553 m_client->didReceiveResponse(identifier, response, handle); | 604 m_client->didReceiveResponse(identifier, response, handle); |
554 } | 605 } |
555 | 606 |
556 void DocumentThreadableLoader::setSerializedCachedMetadata(Resource*, const char * data, size_t size) | 607 void DocumentThreadableLoader::setSerializedCachedMetadata(Resource*, const char * data, size_t size) |
557 { | 608 { |
558 if (m_actualRequest) | 609 if (m_actualRequest) |
559 return; | 610 return; |
560 m_client->didReceiveCachedMetadata(data, size); | 611 m_client->didReceiveCachedMetadata(data, size); |
612 // |this| may be dead here. | |
561 } | 613 } |
562 | 614 |
563 void DocumentThreadableLoader::dataReceived(Resource* resource, const char* data , unsigned dataLength) | 615 void DocumentThreadableLoader::dataReceived(Resource* resource, const char* data , unsigned dataLength) |
564 { | 616 { |
565 ASSERT_UNUSED(resource, resource == this->resource()); | 617 ASSERT_UNUSED(resource, resource == this->resource()); |
566 ASSERT(m_async); | 618 ASSERT(m_async); |
567 | 619 |
568 if (m_isUsingDataConsumerHandle) | 620 if (m_isUsingDataConsumerHandle) |
569 return; | 621 return; |
570 | 622 |
571 handleReceivedData(data, dataLength); | 623 handleReceivedData(data, dataLength); |
624 // |this| may be dead here. | |
572 } | 625 } |
573 | 626 |
574 void DocumentThreadableLoader::handleReceivedData(const char* data, unsigned dat aLength) | 627 void DocumentThreadableLoader::handleReceivedData(const char* data, unsigned dat aLength) |
575 { | 628 { |
576 ASSERT(m_client); | 629 ASSERT(m_client); |
577 | 630 |
578 // Preflight data should be invisible to clients. | 631 // Preflight data should be invisible to clients. |
579 if (m_actualRequest) | 632 if (m_actualRequest) |
580 return; | 633 return; |
581 | 634 |
582 ASSERT(!m_fallbackRequestForServiceWorker); | 635 ASSERT(!m_fallbackRequestForServiceWorker); |
583 | 636 |
584 m_client->didReceiveData(data, dataLength); | 637 m_client->didReceiveData(data, dataLength); |
638 // |this| may be dead here in async mode. | |
585 } | 639 } |
586 | 640 |
587 void DocumentThreadableLoader::notifyFinished(Resource* resource) | 641 void DocumentThreadableLoader::notifyFinished(Resource* resource) |
588 { | 642 { |
589 ASSERT(m_client); | 643 ASSERT(m_client); |
590 ASSERT(resource == this->resource()); | 644 ASSERT(resource == this->resource()); |
591 ASSERT(m_async); | 645 ASSERT(m_async); |
592 | 646 |
593 m_timeoutTimer.stop(); | 647 if (resource->errorOccurred()) { |
648 handleError(resource->resourceError()); | |
649 // |this| may be dead here. | |
650 } else { | |
651 handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime( )); | |
652 // |this| may be dead here. | |
653 } | |
654 } | |
594 | 655 |
595 if (resource->errorOccurred()) | 656 void DocumentThreadableLoader::handleSuccessfulActualRequestFinish(unsigned long identifier, double finishTime) |
596 m_client->didFail(resource->resourceError()); | 657 { |
597 else | 658 ThreadableLoaderClient* client = m_client; |
598 handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime( )); | 659 m_client = 0; |
660 // Don't clear the resource as the client may need to access the downloaded | |
661 // file which will be released when the resource is destoryed. | |
662 if (m_async) { | |
663 m_timeoutTimer.stop(); | |
664 m_requestStartedSeconds = 0.0; | |
665 } | |
666 client->didFinishLoading(identifier, finishTime); | |
667 // |this| may be dead here in async mode. | |
599 } | 668 } |
600 | 669 |
601 void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier, double finishTime) | 670 void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier, double finishTime) |
602 { | 671 { |
603 ASSERT(!m_fallbackRequestForServiceWorker); | 672 ASSERT(!m_fallbackRequestForServiceWorker); |
604 | 673 |
605 if (m_actualRequest) { | 674 if (!m_actualRequest) { |
606 ASSERT(!m_sameOriginRequest); | 675 handleSuccessfulActualRequestFinish(identifier, finishTime); |
607 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); | 676 // |this| may be dead here in async mode. |
608 loadActualRequest(); | 677 return; |
609 } else { | |
610 // FIXME: Should prevent timeout from being overridden after finished lo ading, without | |
611 // resetting m_requestStartedSeconds to 0.0 | |
612 m_client->didFinishLoading(identifier, finishTime); | |
613 } | 678 } |
679 | |
680 // FIXME: Timeout should be applied to whole fetch, not for each of | |
681 // preflight and actual request. | |
682 m_timeoutTimer.stop(); | |
683 ASSERT(!m_sameOriginRequest); | |
684 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); | |
685 loadActualRequest(); | |
614 } | 686 } |
615 | 687 |
616 void DocumentThreadableLoader::didTimeout(Timer<DocumentThreadableLoader>* timer ) | 688 void DocumentThreadableLoader::didTimeout(Timer<DocumentThreadableLoader>* timer ) |
617 { | 689 { |
618 ASSERT_UNUSED(timer, timer == &m_timeoutTimer); | 690 ASSERT_UNUSED(timer, timer == &m_timeoutTimer); |
619 | 691 |
620 // Using values from net/base/net_error_list.h ERR_TIMED_OUT, | 692 // Using values from net/base/net_error_list.h ERR_TIMED_OUT, |
621 // Same as existing FIXME above - this error should be coming from FrameLoad erClient to be identifiable. | 693 // Same as existing FIXME above - this error should be coming from FrameLoad erClient to be identifiable. |
622 static const int timeoutError = -7; | 694 static const int timeoutError = -7; |
623 ResourceError error("net", timeoutError, resource()->url(), String()); | 695 ResourceError error("net", timeoutError, resource()->url(), String()); |
624 error.setIsTimeout(true); | 696 error.setIsTimeout(true); |
625 cancelWithError(error); | 697 cancelWithError(error); |
698 // |this| may be dead here. | |
626 } | 699 } |
627 | 700 |
628 void DocumentThreadableLoader::loadFallbackRequestForServiceWorker() | 701 void DocumentThreadableLoader::loadFallbackRequestForServiceWorker() |
629 { | 702 { |
630 clearResource(); | 703 clearResource(); |
631 OwnPtr<ResourceRequest> fallbackRequest(m_fallbackRequestForServiceWorker.re lease()); | 704 OwnPtr<ResourceRequest> fallbackRequest(m_fallbackRequestForServiceWorker.re lease()); |
632 dispatchInitialRequest(*fallbackRequest); | 705 dispatchInitialRequest(*fallbackRequest); |
706 // |this| may be dead here in async mode. | |
633 } | 707 } |
634 | 708 |
635 void DocumentThreadableLoader::loadActualRequest() | 709 void DocumentThreadableLoader::loadActualRequest() |
636 { | 710 { |
637 OwnPtr<ResourceRequest> actualRequest; | 711 OwnPtr<ResourceRequest> actualRequest; |
638 actualRequest.swap(m_actualRequest); | 712 actualRequest.swap(m_actualRequest); |
639 OwnPtr<ResourceLoaderOptions> actualOptions; | 713 OwnPtr<ResourceLoaderOptions> actualOptions; |
640 actualOptions.swap(m_actualOptions); | 714 actualOptions.swap(m_actualOptions); |
641 | 715 |
642 actualRequest->setHTTPOrigin(securityOrigin()->toAtomicString()); | 716 actualRequest->setHTTPOrigin(securityOrigin()->toAtomicString()); |
643 | 717 |
644 clearResource(); | 718 clearResource(); |
645 | 719 |
646 loadRequest(*actualRequest, *actualOptions); | 720 loadRequest(*actualRequest, *actualOptions); |
647 } | 721 } |
648 | 722 |
649 void DocumentThreadableLoader::handlePreflightFailure(const String& url, const S tring& errorDescription) | 723 void DocumentThreadableLoader::handlePreflightFailure(const String& url, const S tring& errorDescription) |
650 { | 724 { |
651 ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription); | 725 ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription); |
652 | 726 |
653 // Prevent handleSuccessfulFinish() from bypassing access check. | 727 // Prevent handleSuccessfulFinish() from bypassing access check. |
654 m_actualRequest = nullptr; | 728 m_actualRequest = nullptr; |
655 | 729 |
656 // FIXME: Should prevent timeout from being overridden after preflight failu re, without | 730 ThreadableLoaderClient* client = m_client; |
657 // resetting m_requestStartedSeconds to 0.0 | 731 clear(); |
658 m_client->didFailAccessControlCheck(error); | 732 client->didFailAccessControlCheck(error); |
733 // |this| may be dead here in async mode. | |
734 } | |
735 | |
736 void DocumentThreadableLoader::handleError(const ResourceError& error) | |
737 { | |
738 // Copy the ResourceError instance to make it sure that the | |
739 // ResourceError outlive the resource for convenience. | |
hiroshige
2015/09/15 08:54:16
This sounds as if |copiedError| *always* outlive t
tyoshino (SeeGerritForStatus)
2015/09/15 13:29:34
Good point and nice rephrasing. Done
| |
740 ResourceError copiedError = error; | |
741 | |
742 ThreadableLoaderClient* client = m_client; | |
743 clear(); | |
744 client->didFail(copiedError); | |
745 // |this| may be dead here. | |
659 } | 746 } |
660 | 747 |
661 void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Resou rceLoaderOptions resourceLoaderOptions) | 748 void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Resou rceLoaderOptions resourceLoaderOptions) |
662 { | 749 { |
663 // Any credential should have been removed from the cross-site requests. | 750 // Any credential should have been removed from the cross-site requests. |
664 const KURL& requestURL = request.url(); | 751 const KURL& requestURL = request.url(); |
665 ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); | 752 ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); |
666 ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty()); | 753 ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty()); |
667 | 754 |
668 // Update resourceLoaderOptions with enforced values. | 755 // Update resourceLoaderOptions with enforced values. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
716 // FIXME: A synchronous request does not tell us whether a redirect happened or not, so we guess by comparing the | 803 // FIXME: A synchronous request does not tell us whether a redirect happened or not, so we guess by comparing the |
717 // 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 | 804 // 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 |
718 // requested. Also comparing the request and response URLs as strings will f ail if the requestURL still has its credentials. | 805 // requested. Also comparing the request and response URLs as strings will f ail if the requestURL still has its credentials. |
719 if (requestURL != response.url() && (!isAllowedByContentSecurityPolicy(respo nse.url(), ContentSecurityPolicy::DidRedirect) || !isAllowedRedirect(response.ur l()))) { | 806 if (requestURL != response.url() && (!isAllowedByContentSecurityPolicy(respo nse.url(), ContentSecurityPolicy::DidRedirect) || !isAllowedRedirect(response.ur l()))) { |
720 m_client->didFailRedirectCheck(); | 807 m_client->didFailRedirectCheck(); |
721 return; | 808 return; |
722 } | 809 } |
723 | 810 |
724 handleResponse(identifier, response, nullptr); | 811 handleResponse(identifier, response, nullptr); |
725 | 812 |
813 // handleResponse() may detect an error. In such a case (check |m_client| | |
814 // as it gets reset by clear() call), skip the rest. | |
815 // | |
816 // |this| is alive here since loadResourceSynchronously() keeps it alive | |
817 // until the end of the function. | |
818 if (!m_client) | |
819 return; | |
820 | |
726 SharedBuffer* data = resource->resourceBuffer(); | 821 SharedBuffer* data = resource->resourceBuffer(); |
727 if (data) | 822 if (data) |
728 handleReceivedData(data->data(), data->size()); | 823 handleReceivedData(data->data(), data->size()); |
729 | 824 |
hiroshige
2015/09/15 08:54:17
Do we need "if (!m_client) return" also here for c
tyoshino (SeeGerritForStatus)
2015/09/15 13:29:35
Right! We need to take care of cancel().
| |
730 handleSuccessfulFinish(identifier, 0.0); | 825 handleSuccessfulFinish(identifier, 0.0); |
731 } | 826 } |
732 | 827 |
733 bool DocumentThreadableLoader::isAllowedRedirect(const KURL& url) const | 828 bool DocumentThreadableLoader::isAllowedRedirect(const KURL& url) const |
734 { | 829 { |
735 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) | 830 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) |
736 return true; | 831 return true; |
737 | 832 |
738 return m_sameOriginRequest && securityOrigin()->canRequest(url); | 833 return m_sameOriginRequest && securityOrigin()->canRequest(url); |
739 } | 834 } |
(...skipping 11 matching lines...) Expand all Loading... | |
751 return DoNotAllowStoredCredentials; | 846 return DoNotAllowStoredCredentials; |
752 return m_resourceLoaderOptions.allowCredentials; | 847 return m_resourceLoaderOptions.allowCredentials; |
753 } | 848 } |
754 | 849 |
755 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const | 850 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const |
756 { | 851 { |
757 return m_securityOrigin ? m_securityOrigin.get() : m_document.securityOrigin (); | 852 return m_securityOrigin ? m_securityOrigin.get() : m_document.securityOrigin (); |
758 } | 853 } |
759 | 854 |
760 } // namespace blink | 855 } // namespace blink |
OLD | NEW |