示例#1
0
static void appendBlobResolved(FormData* formData, const URL& url)
{
    if (!blobRegistry().isBlobRegistryImpl()) {
        LOG_ERROR("Tried to resolve a blob without a usable registry");
        return;
    }
    BlobStorageData* blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(URL(ParsedURLString, url));
    if (!blobData) {
        LOG_ERROR("Could not get blob data from a registry");
        return;
    }

    BlobDataItemList::const_iterator it = blobData->items().begin();
    const BlobDataItemList::const_iterator itend = blobData->items().end();
    for (; it != itend; ++it) {
        const BlobDataItem& blobItem = *it;
        if (blobItem.type == BlobDataItem::Data)
            formData->appendData(blobItem.data->data() + static_cast<int>(blobItem.offset), static_cast<int>(blobItem.length));
        else if (blobItem.type == BlobDataItem::File)
            formData->appendFileRange(blobItem.path, blobItem.offset, blobItem.length, blobItem.expectedModificationTime);
        else if (blobItem.type == BlobDataItem::Blob)
            appendBlobResolved(formData, blobItem.url);
        else
            ASSERT_NOT_REACHED();
    }
}
void ThreadableBlobRegistry::registerBlobURLForSlice(const URL& newURL, const URL& srcURL, long long start, long long end)
{
    if (isMainThread())
        blobRegistry().registerBlobURLForSlice(newURL, srcURL, start, end);
    else {
        callOnMainThread([newURL = newURL.isolatedCopy(), srcURL = srcURL.isolatedCopy(), start, end] {
            blobRegistry().registerBlobURLForSlice(newURL, srcURL, start, end);
        });
    }
}
void ThreadableBlobRegistry::registerFileBlobURL(const URL& url, const String& path, const String& contentType)
{
    if (isMainThread())
        blobRegistry().registerFileBlobURL(url, BlobDataFileReference::create(path), contentType);
    else {
        callOnMainThread([url = url.isolatedCopy(), path = path.isolatedCopy(), contentType = contentType.isolatedCopy()] {
            blobRegistry().registerFileBlobURL(url, BlobDataFileReference::create(path), contentType);
        });
    }
}
void ThreadableBlobRegistry::registerBlobURL(const URL& url, Vector<BlobPart> blobParts, const String& contentType)
{
    if (isMainThread())
        blobRegistry().registerBlobURL(url, WTFMove(blobParts), contentType);
    else {
        for (auto& part : blobParts)
            part.detachFromCurrentThread();
        callOnMainThread([url = url.isolatedCopy(), blobParts = WTFMove(blobParts), contentType = contentType.isolatedCopy()]() mutable {
            blobRegistry().registerBlobURL(url, WTFMove(blobParts), contentType);
        });
    }
}
void ThreadableBlobRegistry::registerBlobURLForSlice(const URL& newURL, const URL& srcURL, long long start, long long end)
{
    if (isMainThread())
        blobRegistry().registerBlobURLForSlice(newURL, srcURL, start, end);
    else {
        // BlobRegistryContext performs an isolated copy of data.
        BlobRegistryContext* context = new BlobRegistryContext(newURL, srcURL);
        callOnMainThread([context, start, end] {
            std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
            blobRegistry().registerBlobURLForSlice(blobRegistryContext->url, blobRegistryContext->srcURL, start, end);
        });
    }
}
void ThreadableBlobRegistry::registerBlobURL(const URL& url, Vector<BlobPart> blobParts, const String& contentType)
{
    if (isMainThread())
        blobRegistry().registerBlobURL(url, WTF::move(blobParts), contentType);
    else {
        // BlobRegistryContext performs an isolated copy of data.
        BlobRegistryContext* context = new BlobRegistryContext(url, WTF::move(blobParts), contentType);
        callOnMainThread([context] {
            std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
            blobRegistry().registerBlobURL(blobRegistryContext->url, WTF::move(blobRegistryContext->blobParts), blobRegistryContext->contentType);
        });
    }
}
void ThreadableBlobRegistry::unregisterBlobURL(const URL& url)
{
    if (BlobURL::getOrigin(url) == "null")
        originMap()->remove(url.string());

    if (isMainThread())
        blobRegistry().unregisterBlobURL(url);
    else {
        callOnMainThread([url = url.isolatedCopy()] {
            blobRegistry().unregisterBlobURL(url);
        });
    }
}
void ThreadableBlobRegistry::registerFileBlobURL(const URL& url, const String& path, const String& contentType)
{
    if (isMainThread())
        blobRegistry().registerFileBlobURL(url, BlobDataFileReference::create(path), contentType);
    else {
        // BlobRegistryContext performs an isolated copy of data.
        BlobRegistryContext* context = new BlobRegistryContext(url, path, contentType);
        callOnMainThread([context] {
            std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
            blobRegistry().registerFileBlobURL(blobRegistryContext->url, BlobDataFileReference::create(blobRegistryContext->path), blobRegistryContext->contentType);
        });
    }
}
void ThreadableBlobRegistry::registerBlobURL(SecurityOrigin* origin, const URL& url, const URL& srcURL)
{
    // If the blob URL contains null origin, as in the context with unique security origin or file URL, save the mapping between url and origin so that the origin can be retrived when doing security origin check.
    if (origin && BlobURL::getOrigin(url) == "null")
        originMap()->add(url.string(), origin);

    if (isMainThread())
        blobRegistry().registerBlobURL(url, srcURL);
    else {
        callOnMainThread([url = url.isolatedCopy(), srcURL = srcURL.isolatedCopy()] {
            blobRegistry().registerBlobURL(url, srcURL);
        });
    }
}
示例#10
0
unsigned long long ThreadableBlobRegistry::blobSize(const URL& url)
{
    unsigned long long resultSize;
    if (isMainThread())
        resultSize = blobRegistry().blobSize(url);
    else {
        BinarySemaphore semaphore;
        callOnMainThread([url = url.isolatedCopy(), &semaphore, &resultSize] {
            resultSize = blobRegistry().blobSize(url);
            semaphore.signal();
        });
        semaphore.wait(std::numeric_limits<double>::max());
    }
    return resultSize;
}
示例#11
0
void ThreadableBlobRegistry::unregisterBlobURL(const URL& url)
{
    if (BlobURL::getOrigin(url) == "null")
        originMap()->remove(url.string());

    if (isMainThread())
        blobRegistry().unregisterBlobURL(url);
    else {
        // BlobRegistryContext performs an isolated copy of data.
        BlobRegistryContext* context = new BlobRegistryContext(url);
        callOnMainThread([context] {
            std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
            blobRegistry().unregisterBlobURL(blobRegistryContext->url);
        });
    }
}
示例#12
0
void ThreadableBlobRegistry::registerBlobURL(SecurityOrigin* origin, const URL& url, const URL& srcURL)
{
    // If the blob URL contains null origin, as in the context with unique security origin or file URL, save the mapping between url and origin so that the origin can be retrived when doing security origin check.
    if (origin && BlobURL::getOrigin(url) == "null")
        originMap()->add(url.string(), origin);

    if (isMainThread())
        blobRegistry().registerBlobURL(url, srcURL);
    else {
        // BlobRegistryContext performs an isolated copy of data.
        BlobRegistryContext* context = new BlobRegistryContext(url, srcURL);
        callOnMainThread([context] {
            std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
            blobRegistry().registerBlobURL(blobRegistryContext->url, blobRegistryContext->srcURL);
        });
    }
}
示例#13
0
unsigned long long ThreadableBlobRegistry::blobSize(const URL& url)
{
    unsigned long long resultSize;
    if (isMainThread())
        resultSize = blobRegistry().blobSize(url);
    else {
        // BlobRegistryContext performs an isolated copy of data.
        BlobRegistryContext* context = new BlobRegistryContext(url);
        BinarySemaphore semaphore;
        callOnMainThread([context, &semaphore, &resultSize] {
            std::unique_ptr<BlobRegistryContext> blobRegistryContext(context);
            resultSize = blobRegistry().blobSize(blobRegistryContext->url);
            semaphore.signal();
        });
        semaphore.wait(std::numeric_limits<double>::max());
    }
    return resultSize;
}
void NetworkBlobRegistry::unregisterBlobURL(NetworkConnectionToWebProcess* connection, const WebCore::URL& url)
{
    blobRegistry().unregisterBlobURL(url);
    m_sandboxExtensions.remove(url.string());

    ASSERT(m_blobsForConnection.contains(connection));
    ASSERT(m_blobsForConnection.find(connection)->value.contains(url));
    m_blobsForConnection.find(connection)->value.remove(url);
}
void NetworkBlobRegistry::registerBlobURL(NetworkConnectionToWebProcess* connection, const WebCore::URL& url, const WebCore::URL& srcURL)
{
    blobRegistry().registerBlobURL(url, srcURL);
    SandboxExtensionMap::iterator iter = m_sandboxExtensions.find(srcURL.string());
    if (iter != m_sandboxExtensions.end())
        m_sandboxExtensions.add(url.string(), iter->value);

    ASSERT(m_blobsForConnection.contains(connection));
    ASSERT(m_blobsForConnection.find(connection)->value.contains(srcURL));
    m_blobsForConnection.find(connection)->value.add(url);
}
示例#16
0
NetworkDataTaskBlob::NetworkDataTaskBlob(NetworkSession& session, NetworkDataTaskClient& client, const ResourceRequest& request, ContentSniffingPolicy shouldContentSniff, const Vector<RefPtr<WebCore::BlobDataFileReference>>& fileReferences)
    : NetworkDataTask(session, client, request, DoNotAllowStoredCredentials, false)
    , m_stream(std::make_unique<AsyncFileStream>(*this))
    , m_fileReferences(fileReferences)
{
    for (auto& fileReference : m_fileReferences)
        fileReference->prepareForFileAccess();

    m_blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(request.url());

    m_session->registerNetworkDataTask(*this);
    LOG(NetworkSession, "%p - Created NetworkDataTaskBlob for %s", this, request.url().string().utf8().data());
}
void NetworkBlobRegistry::connectionToWebProcessDidClose(NetworkConnectionToWebProcess* connection)
{
    if (!m_blobsForConnection.contains(connection))
        return;

    HashSet<URL>& blobsForConnection = m_blobsForConnection.find(connection)->value;
    for (HashSet<URL>::iterator iter = blobsForConnection.begin(), end = blobsForConnection.end(); iter != end; ++iter) {
        blobRegistry().unregisterBlobURL(*iter);
        m_sandboxExtensions.remove(*iter);
    }

    m_blobsForConnection.remove(connection);
}
示例#18
0
void ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked(const URL& url, const URL& srcURL, const String& fileBackedPath)
{
    if (isMainThread())
        blobRegistry().registerBlobURLOptionallyFileBacked(url, srcURL, BlobDataFileReference::create(fileBackedPath));
    else {
        threadableQueue().append(createCrossThreadTask(ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked, url, srcURL, fileBackedPath));

        callOnMainThread([] {
            auto task = threadableQueue().tryGetMessage();
            ASSERT(task);
            task->performTask();
        });
    }
}
void NetworkBlobRegistry::registerBlobURL(NetworkConnectionToWebProcess* connection, const URL& url, std::unique_ptr<BlobData> data, const Vector<RefPtr<SandboxExtension>>& newSandboxExtensions)
{
    ASSERT(!m_sandboxExtensions.contains(url.string()));

    // Combine new extensions for File items and existing extensions for inner Blob items.
    Vector<RefPtr<SandboxExtension>> sandboxExtensions = newSandboxExtensions;
    const BlobDataItemList& items = data->items();
    for (size_t i = 0, count = items.size(); i < count; ++i) {
        if (items[i].type == BlobDataItem::Blob)
            sandboxExtensions.appendVector(m_sandboxExtensions.get(items[i].url.string()));
    }

    blobRegistry().registerBlobURL(url, std::move(data));

    if (!sandboxExtensions.isEmpty())
        m_sandboxExtensions.add(url.string(), sandboxExtensions);

    ASSERT(!m_blobsForConnection.get(connection).contains(url));
    BlobForConnectionMap::iterator mapIterator = m_blobsForConnection.find(connection);
    if (mapIterator == m_blobsForConnection.end())
        mapIterator = m_blobsForConnection.add(connection, HashSet<URL>()).iterator;
    mapIterator->value.add(url);
}
示例#20
0
void ResourceRequest::initializePlatformRequest(NetworkRequest& platformRequest, bool cookiesEnabled, bool isInitial, bool isRedirect) const
{
    // If this is the initial load, skip the request body and headers.
    if (isInitial)
        platformRequest.setRequestInitial(timeoutInterval());
    else {
        ReadOnlyLatin1String latin1URL(url().string());
        ReadOnlyLatin1String latin1HttpMethod(httpMethod());
        platformRequest.setRequestUrl(latin1URL.data(), latin1URL.length(),
                latin1HttpMethod.data(), latin1HttpMethod.length(),
                platformCachePolicyForRequest(*this),
                platformTargetTypeForRequest(*this),
                timeoutInterval());

        platformRequest.setConditional(isConditional());
        platformRequest.setSuggestedSaveName(suggestedSaveName().utf8().data());

        if (httpBody() && !httpBody()->isEmpty()) {
            const Vector<FormDataElement>& elements = httpBody()->elements();
            // Use setData for simple forms because it is slightly more efficient.
            if (elements.size() == 1 && elements[0].m_type == FormDataElement::data)
                platformRequest.setData(elements[0].m_data.data(), elements[0].m_data.size());
            else {
                for (unsigned i = 0; i < elements.size(); ++i) {
                    const FormDataElement& element = elements[i];
                    if (element.m_type == FormDataElement::data)
                        platformRequest.addMultipartData(element.m_data.data(), element.m_data.size());
                    else if (element.m_type == FormDataElement::encodedFile)
                        platformRequest.addMultipartFilename(element.m_filename.characters(), element.m_filename.length());
#if ENABLE(BLOB)
                    else if (element.m_type == FormDataElement::encodedBlob) {
                        RefPtr<BlobStorageData> blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(KURL(ParsedURLString, element.m_url));
                        if (blobData) {
                            for (size_t j = 0; j < blobData->items().size(); ++j) {
                                const BlobDataItem& blobItem = blobData->items()[j];
                                if (blobItem.type == BlobDataItem::Data)
                                    platformRequest.addMultipartData(blobItem.data->data() + static_cast<int>(blobItem.offset), static_cast<int>(blobItem.length));
                                else {
                                    ASSERT(blobItem.type == BlobDataItem::File);
                                    platformRequest.addMultipartFilename(blobItem.path.characters(), blobItem.path.length(), blobItem.offset, blobItem.length, blobItem.expectedModificationTime);
                                }
                            }
                        }
                    }
#endif
                    else
                        ASSERT_NOT_REACHED(); // unknown type
                }
            }
        }

        // When ResourceRequest is reused by CacheResourceLoader, page refreshing or redirection, its cookies may be dirtied. We won't use these cookies any more.
        bool cookieHeaderMayBeDirty = isRedirect || cachePolicy() == WebCore::ReloadIgnoringCacheData || cachePolicy() == WebCore::ReturnCacheDataElseLoad;

        for (HTTPHeaderMap::const_iterator it = httpHeaderFields().begin(); it != httpHeaderFields().end(); ++it) {
            String key = it->first;
            String value = it->second;
            if (!key.isEmpty()) {
                if (equalIgnoringCase(key, "Cookie")) {
                    // We won't use the old cookies of resourceRequest for new location because these cookies may be changed by redirection.
                    if (cookieHeaderMayBeDirty)
                        continue;
                    // We need to check the encoding and encode the cookie's value using latin1 or utf8 to support unicode data.
                    if (!value.containsOnlyLatin1()) {
                        platformRequest.addHeader("Cookie", value.utf8().data());
                        continue;
                    }
                }
                ReadOnlyLatin1String latin1Key(key);
                ReadOnlyLatin1String latin1Value(value);
                platformRequest.addHeader(latin1Key.data(), latin1Key.length(), latin1Value.data(), latin1Value.length());
            }
        }

        // If request's cookies may be dirty, they must be set again.
        // If there aren't cookies in the header list, we need trying to add cookies.
        if (cookiesEnabled && (cookieHeaderMayBeDirty || !httpHeaderFields().contains("Cookie")) && !url().isNull()) {
            // Prepare a cookie header if there are cookies related to this url.
            String cookiePairs = cookieManager().getCookie(url(), WithHttpOnlyCookies);
            if (!cookiePairs.isEmpty())
                platformRequest.addHeader("Cookie", cookiePairs.containsOnlyLatin1() ? cookiePairs.latin1().data() : cookiePairs.utf8().data());
        }

        if (!httpHeaderFields().contains("Accept-Language"))
            platformRequest.addAcceptLanguageHeader();
    }
}
static void registerStreamURLFromTask(const KURL& url, const KURL& srcURL)
{
    if (WebBlobRegistry* registry = blobRegistry())
        registry->registerStreamURL(url, srcURL);
}
示例#22
0
void ResourceRequest::initializePlatformRequest(NetworkRequest& platformRequest, bool cookiesEnabled, bool isInitial, bool isRedirect) const
{
    // If this is the initial load, skip the request body and headers.
    if (isInitial)
        platformRequest.setRequestInitial(timeoutInterval());
    else {
        platformRequest.setRequestUrl(url().string().utf8().data(),
                httpMethod().latin1().data(),
                platformCachePolicyForRequest(*this),
                platformTargetTypeForRequest(*this),
                timeoutInterval());

        platformRequest.setConditional(isConditional());

        if (httpBody() && !httpBody()->isEmpty()) {
            const Vector<FormDataElement>& elements = httpBody()->elements();
            // Use setData for simple forms because it is slightly more efficient.
            if (elements.size() == 1 && elements[0].m_type == FormDataElement::data)
                platformRequest.setData(elements[0].m_data.data(), elements[0].m_data.size());
            else {
                for (unsigned i = 0; i < elements.size(); ++i) {
                    const FormDataElement& element = elements[i];
                    if (element.m_type == FormDataElement::data)
                        platformRequest.addMultipartData(element.m_data.data(), element.m_data.size());
                    else if (element.m_type == FormDataElement::encodedFile)
                        platformRequest.addMultipartFilename(element.m_filename.characters(), element.m_filename.length());
#if ENABLE(BLOB)
                    else if (element.m_type == FormDataElement::encodedBlob) {
                        RefPtr<BlobStorageData> blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(KURL(ParsedURLString, element.m_blobURL));
                        if (blobData) {
                            for (size_t j = 0; j < blobData->items().size(); ++j) {
                                const BlobDataItem& blobItem = blobData->items()[j];
                                if (blobItem.type == BlobDataItem::Data)
                                    platformRequest.addMultipartData(blobItem.data->data() + static_cast<int>(blobItem.offset), static_cast<int>(blobItem.length));
                                else {
                                    ASSERT(blobItem.type == BlobDataItem::File);
                                    platformRequest.addMultipartFilename(blobItem.path.characters(), blobItem.path.length(), blobItem.offset, blobItem.length, blobItem.expectedModificationTime);
                                }
                            }
                        }
                    }
#endif
                    else
                        ASSERT_NOT_REACHED(); // unknown type
                }
            }
        }

        for (HTTPHeaderMap::const_iterator it = httpHeaderFields().begin(); it != httpHeaderFields().end(); ++it) {
            String key = it->first;
            String value = it->second;
            if (!key.isEmpty() && !value.isEmpty()) {
                // We need to check the encoding and encode the cookie's value using latin1 or utf8 to support unicode characters.
                if (equalIgnoringCase(key, "Cookie"))
                    platformRequest.addHeader(key.latin1().data(), value.containsOnlyLatin1() ? value.latin1().data() : value.utf8().data());
                else
                    platformRequest.addHeader(key.latin1().data(), value.latin1().data());
            }
        }
       
        // Redirection's response may contain new cookies, so add cookies again.
        // If there aren't cookies in the header list, we need trying to add cookies.
        if (cookiesEnabled && (isRedirect || !httpHeaderFields().contains("Cookie")) && !url().isNull()) {
            // Prepare a cookie header if there are cookies related to this url.
            String cookiePairs = cookieManager().getCookie(url(), WithHttpOnlyCookies);
            if (!cookiePairs.isEmpty())
                platformRequest.addHeader("Cookie", cookiePairs.containsOnlyLatin1() ? cookiePairs.latin1().data() : cookiePairs.utf8().data());
        }

        // Locale has the form "en-US". Construct accept language like "en-US, en;q=0.8".
        std::string locale = BlackBerry::Platform::Client::get()->getLocale();
        // POSIX locale has '_' instead of '-'.
        // Replace to conform to HTTP spec.
        size_t underscore = locale.find('_');
        if (underscore != std::string::npos)
            locale.replace(underscore, 1, "-");
        std::string acceptLanguage = locale + ", " + locale.substr(0, 2) + ";q=0.8";
        platformRequest.addHeader("Accept-Language", acceptLanguage.c_str());
    }
}
static void finalizeStreamTask(const KURL& url)
{
    if (WebBlobRegistry* registry = blobRegistry())
        registry->finalizeStream(url);
}
static void unregisterStreamURLTask(const KURL& url)
{
    if (WebBlobRegistry* registry = blobRegistry())
        registry->unregisterStreamURL(url);
}
static void abortStreamTask(const KURL& url)
{
    if (WebBlobRegistry* registry = blobRegistry())
        registry->abortStream(url);
}
void BlobRegistry::registerBlobData(const String& uuid, PassOwnPtr<BlobData> data)
{
    blobRegistry()->registerBlobData(uuid, WebBlobData(std::move(data)));
}
void BlobRegistry::addBlobDataRef(const String& uuid)
{
    blobRegistry()->addBlobDataRef(uuid);
}
示例#28
0
static PassRefPtr<ResourceHandle> createResourceHandle(const ResourceRequest& request, ResourceHandleClient* client)
{
    return static_cast<BlobRegistryImpl&>(blobRegistry()).createResourceHandle(request, client);
}
示例#29
0
static void loadResourceSynchronously(NetworkingContext*, const ResourceRequest& request, StoredCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data)
{
    BlobStorageData* blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(request.url());
    BlobResourceHandle::loadResourceSynchronously(blobData, request, error, response, data);
}
static void addDataToStreamTask(const KURL& url, PassRefPtr<RawData> streamData)
{
    if (WebBlobRegistry* registry = blobRegistry())
        registry->addDataToStream(url, streamData->data(), streamData->length());
}