| /* |
| * Copyright (C) 2022 Apple Inc. All rights reserved. |
| * Copyright (C) 2009 Google Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following disclaimer |
| * in the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name of Google Inc. nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "config.h" |
| #include "ThreadableLoader.h" |
| |
| #include "CachedResourceRequestInitiators.h" |
| #include "Document.h" |
| #include "DocumentLoader.h" |
| #include "DocumentThreadableLoader.h" |
| #include "ResourceError.h" |
| #include "ScriptExecutionContext.h" |
| #include "WorkerGlobalScope.h" |
| #include "WorkerRunLoop.h" |
| #include "WorkerThreadableLoader.h" |
| #include "WorkletGlobalScope.h" |
| |
| namespace WebCore { |
| |
| ThreadableLoaderOptions::ThreadableLoaderOptions() |
| { |
| mode = FetchOptions::Mode::SameOrigin; |
| } |
| |
| ThreadableLoaderOptions::~ThreadableLoaderOptions() = default; |
| |
| ThreadableLoaderOptions::ThreadableLoaderOptions(FetchOptions&& baseOptions) |
| : ResourceLoaderOptions { WTFMove(baseOptions) } |
| { |
| } |
| |
| ThreadableLoaderOptions::ThreadableLoaderOptions(const ResourceLoaderOptions& baseOptions, ContentSecurityPolicyEnforcement contentSecurityPolicyEnforcement, String&& initiator, ResponseFilteringPolicy filteringPolicy) |
| : ResourceLoaderOptions(baseOptions) |
| , contentSecurityPolicyEnforcement(contentSecurityPolicyEnforcement) |
| , initiator(WTFMove(initiator)) |
| , filteringPolicy(filteringPolicy) |
| { |
| } |
| |
| ThreadableLoaderOptions ThreadableLoaderOptions::isolatedCopy() const |
| { |
| ThreadableLoaderOptions copy; |
| |
| // FetchOptions |
| copy.destination = this->destination; |
| copy.mode = this->mode; |
| copy.credentials = this->credentials; |
| copy.cache = this->cache; |
| copy.redirect = this->redirect; |
| copy.referrerPolicy = this->referrerPolicy; |
| copy.integrity = this->integrity.isolatedCopy(); |
| copy.keepAlive = this->keepAlive; |
| copy.clientIdentifier = this->clientIdentifier; |
| |
| // ResourceLoaderOptions |
| copy.sendLoadCallbacks = this->sendLoadCallbacks; |
| copy.sniffContent = this->sniffContent; |
| copy.dataBufferingPolicy = this->dataBufferingPolicy; |
| copy.storedCredentialsPolicy = this->storedCredentialsPolicy; |
| copy.securityCheck = this->securityCheck; |
| copy.certificateInfoPolicy = this->certificateInfoPolicy; |
| copy.contentSecurityPolicyImposition = this->contentSecurityPolicyImposition; |
| copy.defersLoadingPolicy = this->defersLoadingPolicy; |
| copy.cachingPolicy = this->cachingPolicy; |
| copy.sameOriginDataURLFlag = this->sameOriginDataURLFlag; |
| copy.initiatorContext = this->initiatorContext; |
| copy.clientCredentialPolicy = this->clientCredentialPolicy; |
| copy.maxRedirectCount = this->maxRedirectCount; |
| copy.preflightPolicy = this->preflightPolicy; |
| copy.navigationPreloadIdentifier = this->navigationPreloadIdentifier; |
| |
| // ThreadableLoaderOptions |
| copy.contentSecurityPolicyEnforcement = this->contentSecurityPolicyEnforcement; |
| copy.initiator = this->initiator.isolatedCopy(); |
| copy.filteringPolicy = this->filteringPolicy; |
| |
| return copy; |
| } |
| |
| |
| RefPtr<ThreadableLoader> ThreadableLoader::create(ScriptExecutionContext& context, ThreadableLoaderClient& client, ResourceRequest&& request, const ThreadableLoaderOptions& options, String&& referrer, String&& taskMode) |
| { |
| Document* document = nullptr; |
| if (is<WorkletGlobalScope>(context)) |
| document = downcast<WorkletGlobalScope>(context).responsibleDocument(); |
| else if (is<Document>(context)) |
| document = &downcast<Document>(context); |
| |
| if (auto* documentLoader = document ? document->loader() : nullptr) |
| request.setIsAppInitiated(documentLoader->lastNavigationWasAppInitiated()); |
| |
| if (is<WorkerGlobalScope>(context) || (is<WorkletGlobalScope>(context) && downcast<WorkletGlobalScope>(context).workerOrWorkletThread())) |
| return WorkerThreadableLoader::create(static_cast<WorkerOrWorkletGlobalScope&>(context), client, WTFMove(taskMode), WTFMove(request), options, WTFMove(referrer)); |
| |
| return DocumentThreadableLoader::create(*document, client, WTFMove(request), options, WTFMove(referrer)); |
| } |
| |
| void ThreadableLoader::loadResourceSynchronously(ScriptExecutionContext& context, ResourceRequest&& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options) |
| { |
| auto resourceURL = request.url(); |
| if (is<WorkerGlobalScope>(context)) |
| WorkerThreadableLoader::loadResourceSynchronously(downcast<WorkerGlobalScope>(context), WTFMove(request), client, options); |
| else |
| DocumentThreadableLoader::loadResourceSynchronously(downcast<Document>(context), WTFMove(request), client, options); |
| context.didLoadResourceSynchronously(resourceURL); |
| } |
| |
| void ThreadableLoader::logError(ScriptExecutionContext& context, const ResourceError& error, const String& initiator) |
| { |
| if (error.isCancellation()) |
| return; |
| |
| // FIXME: Some errors are returned with null URLs. This leads to poor console messages. We should do better for these errors. |
| if (error.failingURL().isNull()) |
| return; |
| |
| // We further reduce logging to some errors. |
| // FIXME: Log more errors when making so do not make some layout tests flaky. |
| if (error.domain() != errorDomainWebKitInternal && error.domain() != errorDomainWebKitServiceWorker && !error.isAccessControl()) |
| return; |
| |
| const char* messageStart; |
| if (initiator == cachedResourceRequestInitiators().eventsource) |
| messageStart = "EventSource cannot load "; |
| else if (initiator == cachedResourceRequestInitiators().fetch) |
| messageStart = "Fetch API cannot load "; |
| else if (initiator == cachedResourceRequestInitiators().xmlhttprequest) |
| messageStart = "XMLHttpRequest cannot load "; |
| else |
| messageStart = "Cannot load "; |
| |
| String messageEnd = error.isAccessControl() ? " due to access control checks."_s : "."_s; |
| context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, makeString(messageStart, error.failingURL().string(), messageEnd)); |
| } |
| |
| } // namespace WebCore |