15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 3521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * Copyright (C) 2013, Intel Corporation 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/DocumentThreadableLoader.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h" 368abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include "core/fetch/CrossOriginAccessControl.h" 37e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/FetchRequest.h" 388abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include "core/fetch/Resource.h" 39e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ResourceFetcher.h" 40bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/frame/ContentSecurityPolicy.h" 41bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/frame/Frame.h" 4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorInstrumentation.h" 4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/CrossOriginPreflightResultCache.h" 4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/DocumentThreadableLoaderClient.h" 4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/FrameLoader.h" 4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/ThreadableLoaderClient.h" 471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/SharedBuffer.h" 48bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/network/ResourceRequest.h" 4951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/SchemeRegistry.h" 5051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/SecurityOrigin.h" 51e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "wtf/Assertions.h" 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentThreadableLoader::loadResourceSynchronously(Document* document, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options) 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The loader will be deleted as soon as this function exits. 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, &client, LoadSynchronously, request, options)); 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(loader->hasOneRef()); 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document* document, ThreadableLoaderClient* client, const ResourceRequest& request, const ThreadableLoaderOptions& options) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, client, LoadAsynchronously, request, options)); 65e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) if (!loader->resource()) 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loader = 0; 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return loader.release(); 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DocumentThreadableLoader::DocumentThreadableLoader(Document* document, ThreadableLoaderClient* client, BlockingBehavior blockingBehavior, const ResourceRequest& request, const ThreadableLoaderOptions& options) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_client(client) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_document(document) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_options(options) 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_sameOriginRequest(securityOrigin()->canRequest(request.url())) 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_simpleRequest(true) 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_async(blockingBehavior == LoadAsynchronously) 77521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(document); 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(client); 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Setting an outgoing referer is only supported in the async code path. 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_async || request.httpReferrer().isEmpty()); 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) { 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loadRequest(request, DoSecurityCheck); 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_options.crossOriginRequestPolicy == DenyCrossOriginRequests) { 90a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url().string(), "Cross origin requests are not supported.")); 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) makeCrossOriginAccessRequest(request); 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceRequest& request) 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OwnPtr<ResourceRequest> crossOriginRequest = adoptPtr(new ResourceRequest(request)); 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1030019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch if ((m_options.preflightPolicy == ConsiderPreflight && isSimpleCrossOriginAccessRequest(crossOriginRequest->httpMethod(), crossOriginRequest->httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight) { 1040019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch updateRequestForAccessControl(*crossOriginRequest, securityOrigin(), m_options.allowCredentials); 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) makeSimpleCrossOriginAccessRequest(*crossOriginRequest); 1060019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch } else { 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_simpleRequest = false; 1080019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch // Do not set the Origin header for preflight requests. 1090019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch updateRequestForAccessControl(*crossOriginRequest, 0, m_options.allowCredentials); 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_actualRequest = crossOriginRequest.release(); 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (CrossOriginPreflightResultCache::shared().canSkipPreflight(securityOrigin()->toString(), m_actualRequest->url(), m_options.allowCredentials, m_actualRequest->httpMethod(), m_actualRequest->httpHeaderFields())) 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) preflightSuccess(); 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) makeCrossOriginAccessRequestWithPreflight(*m_actualRequest); 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest(const ResourceRequest& request) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_options.preflightPolicy != ForcePreflight); 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_options.preflightPolicy == PreventPreflight || isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields())); 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Cross-origin requests are only allowed for HTTP and registered schemes. We would catch this when checking response headers later, but there is no reason to send a request that's guaranteed to be denied. 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())) { 126a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, request.url().string(), "Cross origin requests are only supported for HTTP.")); 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loadRequest(request, DoSecurityCheck); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight(const ResourceRequest& request) 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ResourceRequest preflightRequest = createAccessControlPreflightRequest(request, securityOrigin()); 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loadRequest(preflightRequest, DoSecurityCheck); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DocumentThreadableLoader::~DocumentThreadableLoader() 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentThreadableLoader::cancel() 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 145521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) cancelWithError(ResourceError()); 146521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 147521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 148521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void DocumentThreadableLoader::cancelWithError(const ResourceError& error) 149521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<DocumentThreadableLoader> protect(this); 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Cancel can re-enter and m_resource might be null here as a result. 153e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) if (m_client && resource()) { 154521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) ResourceError errorForCallback = error; 155521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (errorForCallback.isNull()) { 156521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // FIXME: This error is sent to the client in didFail(), so it should not be an internal one. Use FrameLoaderClient::cancelledError() instead. 157e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) errorForCallback = ResourceError(errorDomainBlinkInternal, 0, resource()->url().string(), "Load cancelled"); 158521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) errorForCallback.setIsCancellation(true); 159521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 160e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) didFail(resource()->identifier(), errorForCallback); 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clearResource(); 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_client = 0; 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentThreadableLoader::setDefersLoading(bool value) 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 168e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) if (resource()) 169e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) resource()->setDefersLoading(value); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 172fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequest& request, const ResourceResponse& redirectResponse) 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_client); 175e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) ASSERT_UNUSED(resource, resource == this->resource()); 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<DocumentThreadableLoader> protect(this); 178e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (!isAllowedByPolicy(request.url())) { 179e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) m_client->didFailRedirectCheck(); 180e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) request = ResourceRequest(); 181e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return; 182e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } 183e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Allow same origin requests to continue after allowing clients to audit the redirect. 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isAllowedRedirect(request.url())) { 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_client->isDocumentThreadableLoaderClient()) 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static_cast<DocumentThreadableLoaderClient*>(m_client)->willSendRequest(request, redirectResponse); 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // When using access control, only simple cross origin requests are allowed to redirect. The new request URL must have a supported 192e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // scheme and not contain the userinfo production. In addition, the redirect response must pass the access control check if the 193e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // original request was not same-origin. 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_options.crossOriginRequestPolicy == UseAccessControl) { 195c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 196f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) InspectorInstrumentation::didReceiveCORSRedirectResponse(m_document->frame(), resource->identifier(), m_document->frame()->loader().documentLoader(), redirectResponse, 0); 197c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool allowRedirect = false; 199c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) String accessControlErrorDescription; 200c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_simpleRequest) { 202c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) allowRedirect = checkCrossOriginAccessRedirectionUrl(request.url(), accessControlErrorDescription) 203e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) && (m_sameOriginRequest || passesAccessControlCheck(redirectResponse, m_options.allowCredentials, securityOrigin(), accessControlErrorDescription)); 204c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } else { 205c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) accessControlErrorDescription = "The request was redirected to '"+ request.url().string() + "', which is disallowed for cross-origin requests that require preflight."; 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (allowRedirect) { 209e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) clearResource(); 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 21193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) RefPtr<SecurityOrigin> originalOrigin = SecurityOrigin::create(redirectResponse.url()); 21293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) RefPtr<SecurityOrigin> requestOrigin = SecurityOrigin::create(request.url()); 213e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // If the original request wasn't same-origin, then if the request URL origin is not same origin with the original URL origin, 214e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // set the source origin to a globally unique identifier. (If the original request was same-origin, the origin of the new request 215e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // should be the original URL origin.) 216e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (!m_sameOriginRequest && !originalOrigin->isSameSchemeHostPort(requestOrigin.get())) 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_options.securityOrigin = SecurityOrigin::createUnique(); 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Force any subsequent requests to use these checks. 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_sameOriginRequest = false; 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 221e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // Since the request is no longer same-origin, if the user didn't request credentials in 222e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // the first place, update our state so we neither request them nor expect they must be allowed. 223e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (m_options.credentialsRequested == ClientDidNotRequestCredentials) 224e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) m_options.allowCredentials = DoNotAllowStoredCredentials; 225e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Remove any headers that may have been added by the network layer that cause access control to fail. 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request.clearHTTPContentType(); 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request.clearHTTPReferrer(); 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request.clearHTTPOrigin(); 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request.clearHTTPUserAgent(); 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request.clearHTTPAccept(); 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) makeCrossOriginAccessRequest(request); 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 236a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) ResourceError error(errorDomainBlinkInternal, 0, redirectResponse.url().string(), accessControlErrorDescription); 237c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) m_client->didFailAccessControlCheck(error); 238c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } else { 239c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) m_client->didFailRedirectCheck(); 240c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request = ResourceRequest(); 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 244fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid DocumentThreadableLoader::dataSent(Resource* resource, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_client); 247e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) ASSERT_UNUSED(resource, resource == this->resource()); 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_client->didSendData(bytesSent, totalBytesToBeSent); 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 251fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid DocumentThreadableLoader::dataDownloaded(Resource* resource, int dataLength) 25253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 25353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) ASSERT(m_client); 254e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) ASSERT_UNUSED(resource, resource == this->resource()); 25553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) ASSERT(!m_actualRequest); 25653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 25753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) m_client->didDownloadData(dataLength); 25853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 25953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 260fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid DocumentThreadableLoader::responseReceived(Resource* resource, const ResourceResponse& response) 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 262e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) ASSERT_UNUSED(resource, resource == this->resource()); 263e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) didReceiveResponse(resource->identifier(), response); 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, const ResourceResponse& response) 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_client); 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 270926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) String accessControlErrorDescription; 271926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_actualRequest) { 272f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) DocumentLoader* loader = m_document->frame()->loader().documentLoader(); 273e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) InspectorInstrumentation::didReceiveResourceResponse(m_document->frame(), identifier, loader, response, resource() ? resource()->loader() : 0); 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!passesAccessControlCheck(response, m_options.allowCredentials, securityOrigin(), accessControlErrorDescription)) { 27693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) preflightFailure(identifier, response.url().string(), accessControlErrorDescription); 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 280f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (!passesPreflightStatusCheck(response, accessControlErrorDescription)) { 281f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) preflightFailure(identifier, response.url().string(), accessControlErrorDescription); 282f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return; 283f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) } 284f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OwnPtr<CrossOriginPreflightResultCacheItem> preflightResult = adoptPtr(new CrossOriginPreflightResultCacheItem(m_options.allowCredentials)); 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!preflightResult->parse(response, accessControlErrorDescription) 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || !preflightResult->allowsCrossOriginMethod(m_actualRequest->httpMethod(), accessControlErrorDescription) 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || !preflightResult->allowsCrossOriginHeaders(m_actualRequest->httpHeaderFields(), accessControlErrorDescription)) { 28993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) preflightFailure(identifier, response.url().string(), accessControlErrorDescription); 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CrossOriginPreflightResultCache::shared().appendEntry(securityOrigin()->toString(), m_actualRequest->url(), preflightResult.release()); 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessControl) { 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!passesAccessControlCheck(response, m_options.allowCredentials, securityOrigin(), accessControlErrorDescription)) { 297a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, response.url().string(), accessControlErrorDescription)); 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_client->didReceiveResponse(identifier, response); 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 306fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid DocumentThreadableLoader::dataReceived(Resource* resource, const char* data, int dataLength) 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 308e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) ASSERT(resource == this->resource()); 309e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) didReceiveData(resource->identifier(), data, dataLength); 310926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 312926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DocumentThreadableLoader::didReceiveData(unsigned long identifier, const char* data, int dataLength) 313926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 314926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_client); 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Preflight data should be invisible to clients. 317926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_actualRequest) { 318926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) InspectorInstrumentation::didReceiveData(m_document->frame(), identifier, 0, 0, dataLength); 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 320926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_client->didReceiveData(data, dataLength); 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 325fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid DocumentThreadableLoader::notifyFinished(Resource* resource) 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_client); 328e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) ASSERT(resource == this->resource()); 329521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 330521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_timeoutTimer.stop(); 33102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 332e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) if (resource->errorOccurred()) 333e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) didFail(resource->identifier(), resource->resourceError()); 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 335e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) didFinishLoading(resource->identifier(), resource->loadFinishTime()); 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentThreadableLoader::didFinishLoading(unsigned long identifier, double finishTime) 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 340926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_actualRequest) { 341f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) InspectorInstrumentation::didFinishLoading(m_document->frame(), identifier, m_document->frame()->loader().documentLoader(), finishTime); 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_sameOriginRequest); 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) preflightSuccess(); 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_client->didFinishLoading(identifier, finishTime); 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 349926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DocumentThreadableLoader::didFail(unsigned long identifier, const ResourceError& error) 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 351926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_actualRequest) 352f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) InspectorInstrumentation::didFailLoading(m_document->frame(), identifier, m_document->frame()->loader().documentLoader(), error); 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_client->didFail(error); 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 357521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void DocumentThreadableLoader::didTimeout(Timer<DocumentThreadableLoader>* timer) 358521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 359521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) ASSERT_UNUSED(timer, timer == &m_timeoutTimer); 360521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 361521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Using values from net/base/net_error_list.h ERR_TIMED_OUT, 362521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Same as existing FIXME above - this error should be coming from FrameLoaderClient to be identifiable. 363521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) static const int timeoutError = -7; 364e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) ResourceError error("net", timeoutError, resource()->url(), String()); 365521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) error.setIsTimeout(true); 366521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) cancelWithError(error); 367521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 368521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentThreadableLoader::preflightSuccess() 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OwnPtr<ResourceRequest> actualRequest; 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) actualRequest.swap(m_actualRequest); 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) actualRequest->setHTTPOrigin(securityOrigin()->toString()); 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clearResource(); 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // It should be ok to skip the security check since we already asked about the preflight request. 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loadRequest(*actualRequest, SkipSecurityCheck); 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 382926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void DocumentThreadableLoader::preflightFailure(unsigned long identifier, const String& url, const String& errorDescription) 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 384a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription); 385926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_actualRequest) 386f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) InspectorInstrumentation::didFailLoading(m_document->frame(), identifier, m_document->frame()->loader().documentLoader(), error); 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_actualRequest = nullptr; // Prevent didFinishLoading() from bypassing access check. 388926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_client->didFailAccessControlCheck(error); 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, SecurityCheckPolicy securityCheck) 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Any credential should have been removed from the cross-site requests. 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const KURL& requestURL = request.url(); 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_options.securityCheck = securityCheck; 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty()); 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3998abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ThreadableLoaderOptions options = m_options; 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_async) { 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) options.crossOriginCredentialPolicy = DoNotAskClientForCrossOriginCredentials; 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_actualRequest) { 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Don't sniff content or send load callbacks for the preflight request. 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) options.sendLoadCallbacks = DoNotSendCallbacks; 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) options.sniffContent = DoNotSniffContent; 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Keep buffering the data for the preflight request. 407926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) options.dataBufferingPolicy = BufferData; 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 410521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (m_options.timeoutMilliseconds > 0) 411521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0); 412521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 4133464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch FetchRequest newRequest(request, m_options.initiator, options); 414e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) ASSERT(!resource()); 415e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) setResource(m_document->fetcher()->fetchRawResource(newRequest)); 416e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) if (resource() && resource()->loader()) { 417e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) unsigned long identifier = resource()->identifier(); 418e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client); 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 42281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) 42306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) FetchRequest fetchRequest(request, m_options.initiator, options); 42406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ResourcePtr<Resource> resource = m_document->fetcher()->fetchSynchronously(fetchRequest); 42506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ResourceResponse response = resource ? resource->response() : ResourceResponse(); 42606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) unsigned long identifier = resource ? resource->identifier() : std::numeric_limits<unsigned long>::max(); 42706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ResourceError error = resource ? resource->resourceError() : ResourceError(); 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client); 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 43106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (!resource) { 43206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) m_client->didFail(error); 43306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return; 43406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } 43506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // No exception for file:/// resources, see <rdar://problem/4962298>. 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Also, if we have an HTTP response, then it wasn't a network error in fact. 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!error.isNull() && !requestURL.isLocalFile() && response.httpStatusCode() <= 0) { 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_client->didFail(error); 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 44306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // FIXME: A synchronous request does not tell us whether a redirect happened or not, so we guess by comparing the 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // request and response URLs. This isn't a perfect test though, since a server can serve a redirect to the same URL that was 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // requested. Also comparing the request and response URLs as strings will fail if the requestURL still has its credentials. 446e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (requestURL != response.url() && (!isAllowedByPolicy(response.url()) || !isAllowedRedirect(response.url()))) { 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_client->didFailRedirectCheck(); 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) didReceiveResponse(identifier, response); 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 45306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) SharedBuffer* data = resource->resourceBuffer(); 45406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (data) 45506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) didReceiveData(identifier, data->data(), data->size()); 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) didFinishLoading(identifier, 0.0); 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 460e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool DocumentThreadableLoader::isAllowedRedirect(const KURL& url) const 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_sameOriginRequest && securityOrigin()->canRequest(url); 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 468e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool DocumentThreadableLoader::isAllowedByPolicy(const KURL& url) const 469e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 470e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (m_options.contentSecurityPolicyEnforcement != EnforceConnectSrcDirective) 471e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return true; 472e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return m_document->contentSecurityPolicy()->allowConnectToSource(url); 473e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 474e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SecurityOrigin* DocumentThreadableLoader::securityOrigin() const 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_options.securityOrigin ? m_options.securityOrigin.get() : m_document->securityOrigin(); 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 480c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)bool DocumentThreadableLoader::checkCrossOriginAccessRedirectionUrl(const KURL& requestUrl, String& errorDescription) 481c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles){ 482c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(requestUrl.protocol())) { 483c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) errorDescription = "The request was redirected to a URL ('" + requestUrl.string() + "') which has a disallowed scheme for cross-origin requests."; 484c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return false; 485c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 486c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 487c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) if (!(requestUrl.user().isEmpty() && requestUrl.pass().isEmpty())) { 488c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) errorDescription = "The request was redirected to a URL ('" + requestUrl.string() + "') containing userinfo, which is disallowed for cross-origin requests."; 489c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return false; 490c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 491c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 492c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return true; 493c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)} 494c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 496