void ContentExtensionsBackend::processContentExtensionRulesForLoad(ResourceRequest& request, ResourceType resourceType, DocumentLoader& initiatingDocumentLoader)
{
    Document* currentDocument = nullptr;
    URL mainDocumentURL;

    if (initiatingDocumentLoader.frame()) {
        currentDocument = initiatingDocumentLoader.frame()->document();

        if (Document* mainDocument = initiatingDocumentLoader.frame()->mainFrame().document())
            mainDocumentURL = mainDocument->url();
    }

    ResourceLoadInfo resourceLoadInfo = { request.url(), mainDocumentURL, resourceType };
    Vector<ContentExtensions::Action> actions = actionsForResourceLoad(resourceLoadInfo);

    StringBuilder css;
    bool willBlockLoad = false;
    for (const auto& action : actions) {
        switch (action.type()) {
        case ContentExtensions::ActionType::BlockLoad:
            willBlockLoad = true;
            break;
        case ContentExtensions::ActionType::BlockCookies:
            request.setAllowCookies(false);
            break;
        case ContentExtensions::ActionType::CSSDisplayNoneSelector:
            if (resourceType == ResourceType::Document)
                initiatingDocumentLoader.addPendingContentExtensionDisplayNoneSelector(action.extensionIdentifier(), action.stringArgument(), action.actionID());
            else if (currentDocument)
                currentDocument->styleSheetCollection().addDisplayNoneSelector(action.extensionIdentifier(), action.stringArgument(), action.actionID());
            break;
        case ContentExtensions::ActionType::CSSDisplayNoneStyleSheet: {
            StyleSheetContents* styleSheetContents = globalDisplayNoneStyleSheet(action.stringArgument());
            if (styleSheetContents) {
                if (resourceType == ResourceType::Document)
                    initiatingDocumentLoader.addPendingContentExtensionSheet(action.stringArgument(), *styleSheetContents);
                else if (currentDocument)
                    currentDocument->styleSheetCollection().maybeAddContentExtensionSheet(action.stringArgument(), *styleSheetContents);
            }
            break;
        }
        case ContentExtensions::ActionType::IgnorePreviousRules:
        case ContentExtensions::ActionType::InvalidAction:
            RELEASE_ASSERT_NOT_REACHED();
        }
    }

    if (willBlockLoad) {
        if (currentDocument)
            currentDocument->addConsoleMessage(MessageSource::ContentBlocker, MessageLevel::Info, makeString("Content blocker prevented frame displaying ", mainDocumentURL.string(), " from loading a resource from ", request.url().string()));
        request = ResourceRequest();
    }
}
void InspectorNetworkAgent::didLoadResourceFromMemoryCache(DocumentLoader& loader, CachedResource& resource)
{
    String loaderId = m_pageAgent->loaderId(&loader);
    String frameId = m_pageAgent->frameId(loader.frame());
    unsigned long identifier = loader.frame()->page()->progress().createUniqueIdentifier();
    String requestId = IdentifiersFactory::requestId(identifier);
    m_resourcesData->resourceCreated(requestId, loaderId);
    m_resourcesData->addCachedResource(requestId, &resource);

    RefPtr<Inspector::Protocol::Network::Initiator> initiatorObject = buildInitiatorObject(loader.frame() ? loader.frame()->document() : nullptr);

    m_frontendDispatcher->requestServedFromMemoryCache(requestId, frameId, loaderId, loader.url().string(), timestamp(), initiatorObject, buildObjectForCachedResource(&resource, &loader));
}
static bool contentExtensionsEnabled(const DocumentLoader& documentLoader)
{
    if (auto frame = documentLoader.frame()) {
        if (frame->isMainFrame())
            return documentLoader.userContentExtensionsEnabled();
        if (auto mainDocumentLoader = frame->mainFrame().loader().documentLoader())
            return mainDocumentLoader->userContentExtensionsEnabled();
    }

    return true;
}
void InspectorNetworkAgent::didReceiveResponse(unsigned long identifier, DocumentLoader& loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
{
    if (m_hiddenRequestIdentifiers.contains(identifier))
        return;

    String requestId = IdentifiersFactory::requestId(identifier);
    RefPtr<Inspector::Protocol::Network::Response> resourceResponse = buildObjectForResourceResponse(response, &loader);

    bool isNotModified = response.httpStatusCode() == 304;

    CachedResource* cachedResource = nullptr;
    if (resourceLoader && resourceLoader->isSubresourceLoader() && !isNotModified)
        cachedResource = static_cast<SubresourceLoader*>(resourceLoader)->cachedResource();
    if (!cachedResource)
        cachedResource = InspectorPageAgent::cachedResource(loader.frame(), response.url());

    if (cachedResource) {
        // Use mime type from cached resource in case the one in response is empty.
        if (resourceResponse && response.mimeType().isEmpty())
            resourceResponse->setString(Inspector::Protocol::Network::Response::MimeType, cachedResource->response().mimeType());
        m_resourcesData->addCachedResource(requestId, cachedResource);
    }

    InspectorPageAgent::ResourceType type = m_resourcesData->resourceType(requestId);
    InspectorPageAgent::ResourceType newType = cachedResource ? InspectorPageAgent::cachedResourceType(*cachedResource) : type;

    // FIXME: XHRResource is returned for CachedResource::RawResource, it should be OtherResource unless it truly is an XHR.
    // RawResource is used for loading worker scripts, and those should stay as ScriptResource and not change to XHRResource.
    if (type != newType && newType != InspectorPageAgent::XHRResource && newType != InspectorPageAgent::OtherResource)
        type = newType;

    m_resourcesData->responseReceived(requestId, m_pageAgent->frameId(loader.frame()), response);
    m_resourcesData->setResourceType(requestId, type);

    m_frontendDispatcher->responseReceived(requestId, m_pageAgent->frameId(loader.frame()), m_pageAgent->loaderId(&loader), timestamp(), InspectorPageAgent::resourceTypeJson(type), resourceResponse);

    // If we revalidated the resource and got Not modified, send content length following didReceiveResponse
    // as there will be no calls to didReceiveData from the network stack.
    if (isNotModified && cachedResource && cachedResource->encodedSize())
        didReceiveData(identifier, nullptr, cachedResource->encodedSize(), 0);
}
void InspectorNetworkAgent::willSendRequest(unsigned long identifier, DocumentLoader& loader, ResourceRequest& request, const ResourceResponse& redirectResponse)
{
    if (request.hiddenFromInspector()) {
        m_hiddenRequestIdentifiers.add(identifier);
        return;
    }

    String requestId = IdentifiersFactory::requestId(identifier);
    m_resourcesData->resourceCreated(requestId, m_pageAgent->loaderId(&loader));

    CachedResource* cachedResource = InspectorPageAgent::cachedResource(loader.frame(), request.url());
    InspectorPageAgent::ResourceType type = cachedResource ? InspectorPageAgent::cachedResourceType(*cachedResource) : m_resourcesData->resourceType(requestId);
    if (type == InspectorPageAgent::OtherResource) {
        if (m_loadingXHRSynchronously)
            type = InspectorPageAgent::XHRResource;
        else if (equalIgnoringFragmentIdentifier(request.url(), loader.frameLoader()->icon().url()))
            type = InspectorPageAgent::ImageResource;
        else if (equalIgnoringFragmentIdentifier(request.url(), loader.url()) && !loader.isCommitted())
            type = InspectorPageAgent::DocumentResource;
    }

    m_resourcesData->setResourceType(requestId, type);

    for (auto& entry : m_extraRequestHeaders)
        request.setHTTPHeaderField(entry.key, entry.value);

    request.setReportLoadTiming(true);
    request.setReportRawHeaders(true);

    if (m_cacheDisabled) {
        request.setHTTPHeaderField(HTTPHeaderName::Pragma, "no-cache");
        request.setCachePolicy(ReloadIgnoringCacheData);
        request.setHTTPHeaderField(HTTPHeaderName::CacheControl, "no-cache");
    }

    Inspector::Protocol::Page::ResourceType resourceType = InspectorPageAgent::resourceTypeJson(type);

    RefPtr<Inspector::Protocol::Network::Initiator> initiatorObject = buildInitiatorObject(loader.frame() ? loader.frame()->document() : nullptr);
    m_frontendDispatcher->requestWillBeSent(requestId, m_pageAgent->frameId(loader.frame()), m_pageAgent->loaderId(&loader), loader.url().string(), buildObjectForResourceRequest(request), timestamp(), initiatorObject, buildObjectForResourceResponse(redirectResponse, &loader), type != InspectorPageAgent::OtherResource ? &resourceType : nullptr);
}
Beispiel #6
0
void InspectorInstrumentation::loadEventFiredImpl(InstrumentingAgents* instrumentingAgents, Frame* frame, const KURL& url)
{
    DocumentLoader* documentLoader = frame->loader()->documentLoader();
    ASSERT(documentLoader);

    if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent())
        domAgent->loadEventFired(documentLoader->frame()->document());

    if (frame->page()->mainFrame() != frame || url != documentLoader->requestURL())
        return;

    if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent())
        timelineAgent->didMarkLoadEvent();

    if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent())
        pageAgent->loadEventFired();
}
void InspectorNetworkAgent::didFailLoading(unsigned long identifier, DocumentLoader& loader, const ResourceError& error)
{
    if (m_hiddenRequestIdentifiers.remove(identifier))
        return;

    String requestId = IdentifiersFactory::requestId(identifier);

    if (m_resourcesData->resourceType(requestId) == InspectorPageAgent::DocumentResource) {
        Frame* frame = loader.frame();
        if (frame && frame->loader().documentLoader() && frame->document()) {
            m_resourcesData->addResourceSharedBuffer(requestId,
                frame->loader().documentLoader()->mainResourceData(),
                frame->document()->encoding());
        }
    }

    bool canceled = error.isCancellation();
    m_frontendDispatcher->loadingFailed(requestId, timestamp(), error.localizedDescription(), canceled ? &canceled : nullptr);
}
void InspectorNetworkAgent::didFinishLoading(unsigned long identifier, DocumentLoader& loader, double finishTime)
{
    if (m_hiddenRequestIdentifiers.remove(identifier))
        return;

    String requestId = IdentifiersFactory::requestId(identifier);
    if (m_resourcesData->resourceType(requestId) == InspectorPageAgent::DocumentResource)
        m_resourcesData->addResourceSharedBuffer(requestId, loader.frameLoader()->documentLoader()->mainResourceData(), loader.frame()->document()->encoding());

    m_resourcesData->maybeDecodeDataToContent(requestId);

    // FIXME: The finishTime that is passed in is from the NetworkProcess and is more accurate.
    // However, all other times passed to the Inspector are generated from the web process. Mixing
    // times from different processes can cause the finish time to be earlier than the response
    // received time due to inter-process communication lag.
    finishTime = timestamp();

    String sourceMappingURL;
    NetworkResourcesData::ResourceData const* resourceData = m_resourcesData->data(requestId);
    if (resourceData && resourceData->cachedResource())
        sourceMappingURL = InspectorPageAgent::sourceMapURLForResource(resourceData->cachedResource());

    m_frontendDispatcher->loadingFinished(requestId, finishTime, !sourceMappingURL.isEmpty() ? &sourceMappingURL : nullptr);
}
BlockedStatus ContentExtensionsBackend::processContentExtensionRulesForLoad(const URL& url, ResourceType resourceType, DocumentLoader& initiatingDocumentLoader)
{
    if (m_contentExtensions.isEmpty())
        return { };

    Document* currentDocument = nullptr;
    URL mainDocumentURL;

    if (Frame* frame = initiatingDocumentLoader.frame()) {
        currentDocument = frame->document();

        if (initiatingDocumentLoader.isLoadingMainResource()
            && frame->isMainFrame()
            && resourceType == ResourceType::Document)
            mainDocumentURL = url;
        else if (Document* mainDocument = frame->mainFrame().document())
            mainDocumentURL = mainDocument->url();
    }

    ResourceLoadInfo resourceLoadInfo = { url, mainDocumentURL, resourceType };
    Vector<ContentExtensions::Action> actions = actionsForResourceLoad(resourceLoadInfo);

    bool willBlockLoad = false;
    bool willBlockCookies = false;
    bool willMakeHTTPS = false;
    for (const auto& action : actions) {
        switch (action.type()) {
        case ContentExtensions::ActionType::BlockLoad:
            willBlockLoad = true;
            break;
        case ContentExtensions::ActionType::BlockCookies:
            willBlockCookies = true;
            break;
        case ContentExtensions::ActionType::CSSDisplayNoneSelector:
            if (resourceType == ResourceType::Document)
                initiatingDocumentLoader.addPendingContentExtensionDisplayNoneSelector(action.extensionIdentifier(), action.stringArgument(), action.actionID());
            else if (currentDocument)
                currentDocument->extensionStyleSheets().addDisplayNoneSelector(action.extensionIdentifier(), action.stringArgument(), action.actionID());
            break;
        case ContentExtensions::ActionType::CSSDisplayNoneStyleSheet: {
            StyleSheetContents* styleSheetContents = globalDisplayNoneStyleSheet(action.stringArgument());
            if (styleSheetContents) {
                if (resourceType == ResourceType::Document)
                    initiatingDocumentLoader.addPendingContentExtensionSheet(action.stringArgument(), *styleSheetContents);
                else if (currentDocument)
                    currentDocument->extensionStyleSheets().maybeAddContentExtensionSheet(action.stringArgument(), *styleSheetContents);
            }
            break;
        }
        case ContentExtensions::ActionType::MakeHTTPS: {
            if ((url.protocolIs("http") || url.protocolIs("ws"))
                && (!url.port() || isDefaultPortForProtocol(url.port().value(), url.protocol())))
                willMakeHTTPS = true;
            break;
        }
        case ContentExtensions::ActionType::IgnorePreviousRules:
        case ContentExtensions::ActionType::InvalidAction:
            RELEASE_ASSERT_NOT_REACHED();
        }
    }

    if (currentDocument) {
        if (willMakeHTTPS) {
            ASSERT(url.protocolIs("http") || url.protocolIs("ws"));
            String newProtocol = url.protocolIs("http") ? ASCIILiteral("https") : ASCIILiteral("wss");
            currentDocument->addConsoleMessage(MessageSource::ContentBlocker, MessageLevel::Info, makeString("Content blocker promoted URL from ", url.string(), " to ", newProtocol));
        }
        if (willBlockLoad)
            currentDocument->addConsoleMessage(MessageSource::ContentBlocker, MessageLevel::Info, makeString("Content blocker prevented frame displaying ", mainDocumentURL.string(), " from loading a resource from ", url.string()));
    }
    return { willBlockLoad, willBlockCookies, willMakeHTTPS };
}
BlockedStatus ContentExtensionsBackend::processContentExtensionRulesForLoad(ResourceRequest& request, ResourceType resourceType, DocumentLoader& initiatingDocumentLoader)
{
    Document* currentDocument = nullptr;
    URL mainDocumentURL;

    if (Frame* frame = initiatingDocumentLoader.frame()) {
        currentDocument = frame->document();

        if (initiatingDocumentLoader.isLoadingMainResource()
            && frame->isMainFrame()
            && resourceType == ResourceType::Document)
            mainDocumentURL = request.url();
        else if (Document* mainDocument = frame->mainFrame().document())
            mainDocumentURL = mainDocument->url();
    }

    ResourceLoadInfo resourceLoadInfo = { request.url(), mainDocumentURL, resourceType };
    Vector<ContentExtensions::Action> actions = actionsForResourceLoad(resourceLoadInfo);

    bool willBlockLoad = false;
    for (const auto& action : actions) {
        switch (action.type()) {
        case ContentExtensions::ActionType::BlockLoad:
            willBlockLoad = true;
            break;
        case ContentExtensions::ActionType::BlockCookies:
            request.setAllowCookies(false);
            break;
        case ContentExtensions::ActionType::CSSDisplayNoneSelector:
            if (resourceType == ResourceType::Document)
                initiatingDocumentLoader.addPendingContentExtensionDisplayNoneSelector(action.extensionIdentifier(), action.stringArgument(), action.actionID());
            else if (currentDocument)
                currentDocument->extensionStyleSheets().addDisplayNoneSelector(action.extensionIdentifier(), action.stringArgument(), action.actionID());
            break;
        case ContentExtensions::ActionType::CSSDisplayNoneStyleSheet: {
            StyleSheetContents* styleSheetContents = globalDisplayNoneStyleSheet(action.stringArgument());
            if (styleSheetContents) {
                if (resourceType == ResourceType::Document)
                    initiatingDocumentLoader.addPendingContentExtensionSheet(action.stringArgument(), *styleSheetContents);
                else if (currentDocument)
                    currentDocument->extensionStyleSheets().maybeAddContentExtensionSheet(action.stringArgument(), *styleSheetContents);
            }
            break;
        }
        case ContentExtensions::ActionType::MakeHTTPS: {
            const URL originalURL = request.url();
            if (originalURL.protocolIs("http") && (!originalURL.hasPort() || isDefaultPortForProtocol(originalURL.port(), originalURL.protocol()))) {
                URL newURL = originalURL;
                newURL.setProtocol("https");
                if (originalURL.hasPort())
                    newURL.setPort(defaultPortForProtocol("https"));
                request.setURL(newURL);

                if (resourceType == ResourceType::Document && initiatingDocumentLoader.isLoadingMainResource()) {
                    // This is to make sure the correct 'new' URL shows in the location bar.
                    initiatingDocumentLoader.request().setURL(newURL);
                    initiatingDocumentLoader.frameLoader()->client().dispatchDidChangeProvisionalURL();
                }
                if (currentDocument)
                    currentDocument->addConsoleMessage(MessageSource::ContentBlocker, MessageLevel::Info, makeString("Content blocker promoted URL from ", originalURL.string(), " to ", newURL.string()));
            }
            break;
        }
        case ContentExtensions::ActionType::IgnorePreviousRules:
        case ContentExtensions::ActionType::InvalidAction:
            RELEASE_ASSERT_NOT_REACHED();
        }
    }

    if (willBlockLoad) {
        if (currentDocument)
            currentDocument->addConsoleMessage(MessageSource::ContentBlocker, MessageLevel::Info, makeString("Content blocker prevented frame displaying ", mainDocumentURL.string(), " from loading a resource from ", request.url().string()));
        return BlockedStatus::Blocked;
    }
    return BlockedStatus::NotBlocked;
}