| 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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 m_requestStartedSeconds = 0.0; | 408 m_requestStartedSeconds = 0.0; |
| 409 clearResource(); | 409 clearResource(); |
| 410 } | 410 } |
| 411 | 411 |
| 412 // In this method, we can clear |request| to tell content::WebURLLoaderImpl of | 412 // In this method, we can clear |request| to tell content::WebURLLoaderImpl of |
| 413 // Chromium not to follow the redirect. This works only when this method is | 413 // Chromium not to follow the redirect. This works only when this method is |
| 414 // called by RawResource::willSendRequest(). If called by | 414 // called by RawResource::willSendRequest(). If called by |
| 415 // RawResource::didAddClient(), clearing |request| won't be propagated | 415 // RawResource::didAddClient(), clearing |request| won't be propagated |
| 416 // to content::WebURLLoaderImpl. So, this loader must also get detached from | 416 // to content::WebURLLoaderImpl. So, this loader must also get detached from |
| 417 // the resource by calling clearResource(). | 417 // the resource by calling clearResource(). |
| 418 void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ
est& request, const ResourceResponse& redirectResponse) | 418 bool DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ
est& request, const ResourceResponse& redirectResponse) |
| 419 { | 419 { |
| 420 ASSERT(m_client); | 420 ASSERT(m_client); |
| 421 ASSERT_UNUSED(resource, resource == this->resource()); | 421 ASSERT_UNUSED(resource, resource == this->resource()); |
| 422 ASSERT(m_async); | 422 ASSERT(m_async); |
| 423 | 423 |
| 424 m_checker.redirectReceived(); | 424 m_checker.redirectReceived(); |
| 425 | 425 |
| 426 if (!m_actualRequest.isNull()) { | 426 if (!m_actualRequest.isNull()) { |
| 427 reportResponseReceived(resource->identifier(), redirectResponse); | 427 reportResponseReceived(resource->identifier(), redirectResponse); |
| 428 | 428 |
| 429 handlePreflightFailure(redirectResponse.url().getString(), "Response for
preflight is invalid (redirect)"); | 429 handlePreflightFailure(redirectResponse.url().getString(), "Response for
preflight is invalid (redirect)"); |
| 430 | 430 |
| 431 request = ResourceRequest(); | 431 return false; |
| 432 | |
| 433 return; | |
| 434 } | 432 } |
| 435 | 433 |
| 436 if (m_redirectMode == WebURLRequest::FetchRedirectModeManual) { | 434 if (m_redirectMode == WebURLRequest::FetchRedirectModeManual) { |
| 437 // Keep |this| alive even if the client release a reference in | 435 // Keep |this| alive even if the client release a reference in |
| 438 // responseReceived(). | 436 // responseReceived(). |
| 439 WeakPtr<DocumentThreadableLoader> self(m_weakFactory.createWeakPtr()); | 437 WeakPtr<DocumentThreadableLoader> self(m_weakFactory.createWeakPtr()); |
| 440 | 438 |
| 441 // We use |m_redirectMode| to check the original redirect mode. | 439 // We use |m_redirectMode| to check the original redirect mode. |
| 442 // |request| is a new request for redirect. So we don't set the redirect | 440 // |request| is a new request for redirect. So we don't set the redirect |
| 443 // mode of it in WebURLLoaderImpl::Context::OnReceivedRedirect(). | 441 // mode of it in WebURLLoaderImpl::Context::OnReceivedRedirect(). |
| 444 ASSERT(request.useStreamOnResponse()); | 442 ASSERT(request.useStreamOnResponse()); |
| 445 // There is no need to read the body of redirect response because there | 443 // There is no need to read the body of redirect response because there |
| 446 // is no way to read the body of opaque-redirect filtered response's | 444 // is no way to read the body of opaque-redirect filtered response's |
| 447 // internal response. | 445 // internal response. |
| 448 // TODO(horo): If we support any API which expose the internal body, we | 446 // TODO(horo): If we support any API which expose the internal body, we |
| 449 // will have to read the body. And also HTTPCache changes will be needed | 447 // will have to read the body. And also HTTPCache changes will be needed |
| 450 // because it doesn't store the body of redirect responses. | 448 // because it doesn't store the body of redirect responses. |
| 451 responseReceived(resource, redirectResponse, wrapUnique(new EmptyDataHan
dle())); | 449 responseReceived(resource, redirectResponse, wrapUnique(new EmptyDataHan
dle())); |
| 452 | 450 |
| 453 if (!self) { | 451 if (!self) { |
| 454 request = ResourceRequest(); | 452 return false; |
| 455 return; | |
| 456 } | 453 } |
| 457 | 454 |
| 458 if (m_client) { | 455 if (m_client) { |
| 459 ASSERT(m_actualRequest.isNull()); | 456 ASSERT(m_actualRequest.isNull()); |
| 460 notifyFinished(resource); | 457 notifyFinished(resource); |
| 461 } | 458 } |
| 462 | 459 |
| 463 request = ResourceRequest(); | 460 return false; |
| 464 | |
| 465 return; | |
| 466 } | 461 } |
| 467 | 462 |
| 468 if (m_redirectMode == WebURLRequest::FetchRedirectModeError) { | 463 if (m_redirectMode == WebURLRequest::FetchRedirectModeError) { |
| 469 ThreadableLoaderClient* client = m_client; | 464 ThreadableLoaderClient* client = m_client; |
| 470 clear(); | 465 clear(); |
| 471 client->didFailRedirectCheck(); | 466 client->didFailRedirectCheck(); |
| 472 | 467 |
| 473 request = ResourceRequest(); | 468 return false; |
| 474 | |
| 475 return; | |
| 476 } | 469 } |
| 477 | 470 |
| 478 // Allow same origin requests to continue after allowing clients to audit th
e redirect. | 471 // Allow same origin requests to continue after allowing clients to audit th
e redirect. |
| 479 if (isAllowedRedirect(request.url())) { | 472 if (isAllowedRedirect(request.url())) { |
| 480 if (m_client->isDocumentThreadableLoaderClient()) | 473 if (m_client->isDocumentThreadableLoaderClient()) |
| 481 static_cast<DocumentThreadableLoaderClient*>(m_client)->willFollowRe
direct(request, redirectResponse); | 474 return static_cast<DocumentThreadableLoaderClient*>(m_client)->willF
ollowRedirect(request, redirectResponse); |
| 482 return; | 475 return true; |
| 483 } | 476 } |
| 484 | 477 |
| 485 if (m_corsRedirectLimit <= 0) { | 478 if (m_corsRedirectLimit <= 0) { |
| 486 ThreadableLoaderClient* client = m_client; | 479 ThreadableLoaderClient* client = m_client; |
| 487 clear(); | 480 clear(); |
| 488 client->didFailRedirectCheck(); | 481 client->didFailRedirectCheck(); |
| 489 request = ResourceRequest(); | 482 return false; |
| 490 return; | |
| 491 } | 483 } |
| 492 | 484 |
| 493 --m_corsRedirectLimit; | 485 --m_corsRedirectLimit; |
| 494 | 486 |
| 495 InspectorInstrumentation::didReceiveCORSRedirectResponse(document().frame(),
resource->identifier(), document().frame()->loader().documentLoader(), redirect
Response, resource); | 487 InspectorInstrumentation::didReceiveCORSRedirectResponse(document().frame(),
resource->identifier(), document().frame()->loader().documentLoader(), redirect
Response, resource); |
| 496 | 488 |
| 497 bool allowRedirect = false; | 489 bool allowRedirect = false; |
| 498 String accessControlErrorDescription; | 490 String accessControlErrorDescription; |
| 499 | 491 |
| 500 if (m_crossOriginNonSimpleRequest) { | 492 if (m_crossOriginNonSimpleRequest) { |
| 501 // Non-simple cross origin requests (both preflight and actual one) are | 493 // Non-simple cross origin requests (both preflight and actual one) are |
| 502 // not allowed to follow redirect. | 494 // not allowed to follow redirect. |
| 503 accessControlErrorDescription = "Redirect from '" + redirectResponse.url
().getString()+ "' to '" + request.url().getString() + "' has been blocked by CO
RS policy: Request requires preflight, which is disallowed to follow cross-origi
n redirect."; | 495 accessControlErrorDescription = "Redirect from '" + redirectResponse.url
().getString()+ "' to '" + request.url().getString() + "' has been blocked by CO
RS policy: Request requires preflight, which is disallowed to follow cross-origi
n redirect."; |
| 504 } else if (!CrossOriginAccessControl::isLegalRedirectLocation(request.url(),
accessControlErrorDescription)) { | 496 } else if (!CrossOriginAccessControl::isLegalRedirectLocation(request.url(),
accessControlErrorDescription)) { |
| 505 accessControlErrorDescription = "Redirect from '" + redirectResponse.url
().getString() + "' has been blocked by CORS policy: " + accessControlErrorDescr
iption; | 497 accessControlErrorDescription = "Redirect from '" + redirectResponse.url
().getString() + "' has been blocked by CORS policy: " + accessControlErrorDescr
iption; |
| 506 } else if (!m_sameOriginRequest && !passesAccessControlCheck(redirectRespons
e, effectiveAllowCredentials(), getSecurityOrigin(), accessControlErrorDescripti
on, m_requestContext)) { | 498 } else if (!m_sameOriginRequest && !passesAccessControlCheck(redirectRespons
e, effectiveAllowCredentials(), getSecurityOrigin(), accessControlErrorDescripti
on, m_requestContext)) { |
| 507 // The redirect response must pass the access control check if the | 499 // The redirect response must pass the access control check if the |
| 508 // original request was not same-origin. | 500 // original request was not same-origin. |
| 509 accessControlErrorDescription = "Redirect from '" + redirectResponse.url
().getString()+ "' to '" + request.url().getString() + "' has been blocked by CO
RS policy: " + accessControlErrorDescription; | 501 accessControlErrorDescription = "Redirect from '" + redirectResponse.url
().getString()+ "' to '" + request.url().getString() + "' has been blocked by CO
RS policy: " + accessControlErrorDescription; |
| 510 } else { | 502 } else { |
| 511 allowRedirect = true; | 503 allowRedirect = true; |
| 512 } | 504 } |
| 513 | 505 |
| 514 if (!allowRedirect) { | 506 if (!allowRedirect) { |
| 515 ThreadableLoaderClient* client = m_client; | 507 ThreadableLoaderClient* client = m_client; |
| 516 clear(); | 508 clear(); |
| 517 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal
, 0, redirectResponse.url().getString(), accessControlErrorDescription)); | 509 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal
, 0, redirectResponse.url().getString(), accessControlErrorDescription)); |
| 518 request = ResourceRequest(); | 510 return false; |
| 519 return; | |
| 520 } | 511 } |
| 521 | 512 |
| 522 // FIXME: consider combining this with CORS redirect handling performed by | 513 // FIXME: consider combining this with CORS redirect handling performed by |
| 523 // CrossOriginAccessControl::handleRedirect(). | 514 // CrossOriginAccessControl::handleRedirect(). |
| 524 clearResource(); | 515 clearResource(); |
| 525 | 516 |
| 526 // If the original request wasn't same-origin, then if the request URL origi
n is not same origin with the original URL origin, | 517 // If the original request wasn't same-origin, then if the request URL origi
n is not same origin with the original URL origin, |
| 527 // set the source origin to a globally unique identifier. (If the original r
equest was same-origin, the origin of the new request | 518 // set the source origin to a globally unique identifier. (If the original r
equest was same-origin, the origin of the new request |
| 528 // should be the original URL origin.) | 519 // should be the original URL origin.) |
| 529 if (!m_sameOriginRequest) { | 520 if (!m_sameOriginRequest) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 546 | 537 |
| 547 // Remove any headers that may have been added by the network layer that cau
se access control to fail. | 538 // Remove any headers that may have been added by the network layer that cau
se access control to fail. |
| 548 request.clearHTTPReferrer(); | 539 request.clearHTTPReferrer(); |
| 549 request.clearHTTPOrigin(); | 540 request.clearHTTPOrigin(); |
| 550 request.clearHTTPUserAgent(); | 541 request.clearHTTPUserAgent(); |
| 551 // Add any CORS simple request headers which we previously saved from the or
iginal request. | 542 // Add any CORS simple request headers which we previously saved from the or
iginal request. |
| 552 for (const auto& header : m_simpleRequestHeaders) | 543 for (const auto& header : m_simpleRequestHeaders) |
| 553 request.setHTTPHeaderField(header.key, header.value); | 544 request.setHTTPHeaderField(header.key, header.value); |
| 554 makeCrossOriginAccessRequest(request); | 545 makeCrossOriginAccessRequest(request); |
| 555 // |this| may be dead here. | 546 // |this| may be dead here. |
| 547 |
| 548 return true; |
| 556 } | 549 } |
| 557 | 550 |
| 558 void DocumentThreadableLoader::redirectBlocked() | 551 void DocumentThreadableLoader::redirectBlocked() |
| 559 { | 552 { |
| 560 m_checker.redirectBlocked(); | 553 m_checker.redirectBlocked(); |
| 561 | 554 |
| 562 // Tells the client that a redirect was received but not followed (for an un
known reason). | 555 // Tells the client that a redirect was received but not followed (for an un
known reason). |
| 563 ThreadableLoaderClient* client = m_client; | 556 ThreadableLoaderClient* client = m_client; |
| 564 clear(); | 557 clear(); |
| 565 client->didFailRedirectCheck(); | 558 client->didFailRedirectCheck(); |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 987 | 980 |
| 988 DEFINE_TRACE(DocumentThreadableLoader) | 981 DEFINE_TRACE(DocumentThreadableLoader) |
| 989 { | 982 { |
| 990 visitor->trace(m_resource); | 983 visitor->trace(m_resource); |
| 991 visitor->trace(m_document); | 984 visitor->trace(m_document); |
| 992 ThreadableLoader::trace(visitor); | 985 ThreadableLoader::trace(visitor); |
| 993 RawResourceClient::trace(visitor); | 986 RawResourceClient::trace(visitor); |
| 994 } | 987 } |
| 995 | 988 |
| 996 } // namespace blink | 989 } // namespace blink |
| OLD | NEW |