| /* |
| * Copyright (C) 2014 Igalia S.L |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. 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. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 "MediaResourceLoader.h" |
| |
| #if ENABLE(VIDEO) |
| |
| #include "CachedRawResource.h" |
| #include "CachedResourceLoader.h" |
| #include "CachedResourceRequest.h" |
| #include "CrossOriginAccessControl.h" |
| #include "Document.h" |
| #include "SecurityOrigin.h" |
| #include <wtf/NeverDestroyed.h> |
| |
| namespace WebCore { |
| |
| MediaResourceLoader::MediaResourceLoader(Document& document, const String& crossOriginMode, std::unique_ptr<PlatformMediaResourceLoaderClient> client) |
| : PlatformMediaResourceLoader(WTF::move(client)) |
| , m_document(document) |
| , m_crossOriginMode(crossOriginMode) |
| , m_didPassAccessControlCheck(false) |
| { |
| } |
| |
| MediaResourceLoader::~MediaResourceLoader() |
| { |
| stop(); |
| } |
| |
| bool MediaResourceLoader::start(const ResourceRequest& request, LoadOptions options) |
| { |
| if (m_resource) |
| return false; |
| |
| DataBufferingPolicy bufferingPolicy = options & LoadOption::BufferData ? WebCore::BufferData : WebCore::DoNotBufferData; |
| RequestOriginPolicy corsPolicy = !m_crossOriginMode.isNull() ? PotentiallyCrossOriginEnabled : UseDefaultOriginRestrictionsForType; |
| StoredCredentials allowCredentials = m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; |
| |
| // ContentSecurityPolicyImposition::DoPolicyCheck is a placeholder value. It does not affect the request since Content Security Policy does not apply to raw resources. |
| CachedResourceRequest cacheRequest(request, ResourceLoaderOptions(SendCallbacks, DoNotSniffContent, bufferingPolicy, allowCredentials, DoNotAskClientForCrossOriginCredentials, DoSecurityCheck, corsPolicy, DoNotIncludeCertificateInfo, ContentSecurityPolicyImposition::DoPolicyCheck, DefersLoadingPolicy::AllowDefersLoading)); |
| |
| if (!m_crossOriginMode.isNull()) |
| updateRequestForAccessControl(cacheRequest.mutableResourceRequest(), m_document.securityOrigin(), allowCredentials); |
| |
| m_didPassAccessControlCheck = false; |
| |
| m_resource = m_document.cachedResourceLoader().requestRawResource(cacheRequest); |
| if (!m_resource) |
| return false; |
| |
| m_resource->addClient(this); |
| return true; |
| } |
| |
| void MediaResourceLoader::stop() |
| { |
| if (!m_resource) |
| return; |
| |
| m_resource->removeClient(this); |
| m_resource = nullptr; |
| } |
| |
| void MediaResourceLoader::setDefersLoading(bool defersLoading) |
| { |
| if (m_resource) |
| m_resource->setDefersLoading(defersLoading); |
| } |
| |
| void MediaResourceLoader::responseReceived(CachedResource* resource, const ResourceResponse& response) |
| { |
| ASSERT_UNUSED(resource, resource == m_resource); |
| |
| RefPtr<MediaResourceLoader> protect(this); |
| if (!m_crossOriginMode.isNull() && !resource->passesSameOriginPolicyCheck(*m_document.securityOrigin())) { |
| static NeverDestroyed<const String> consoleMessage("Cross-origin media resource load denied by Cross-Origin Resource Sharing policy."); |
| m_document.addConsoleMessage(MessageSource::Security, MessageLevel::Error, consoleMessage.get()); |
| m_didPassAccessControlCheck = false; |
| m_client->accessControlCheckFailed(ResourceError(errorDomainWebKitInternal, 0, response.url().string(), consoleMessage.get())); |
| stop(); |
| return; |
| } |
| |
| m_didPassAccessControlCheck = !m_crossOriginMode.isNull(); |
| m_client->responseReceived(response); |
| } |
| |
| void MediaResourceLoader::dataReceived(CachedResource* resource, const char* data, int dataLength) |
| { |
| ASSERT_UNUSED(resource, resource == m_resource); |
| |
| RefPtr<MediaResourceLoader> protect(this); |
| m_client->dataReceived(data, dataLength); |
| } |
| |
| void MediaResourceLoader::notifyFinished(CachedResource* resource) |
| { |
| ASSERT(resource == m_resource); |
| |
| RefPtr<MediaResourceLoader> protect(this); |
| if (resource->loadFailedOrCanceled()) |
| m_client->loadFailed(resource->resourceError()); |
| else |
| m_client->loadFinished(); |
| stop(); |
| } |
| |
| #if USE(SOUP) |
| char* MediaResourceLoader::getOrCreateReadBuffer(CachedResource* resource, size_t requestedSize, size_t& actualSize) |
| { |
| ASSERT_UNUSED(resource, resource == m_resource); |
| return m_client->getOrCreateReadBuffer(requestedSize, actualSize); |
| } |
| #endif |
| |
| } // namespace WebCore |
| |
| #endif |