Ejemplo n.º 1
0
SoupURI* ResourceRequest::soupURI() const
{
    // WebKit does not support fragment identifiers in data URLs, but soup does.
    // Before passing the URL to soup, we should make sure to urlencode any '#'
    // characters, so that soup does not interpret them as fragment identifiers.
    // See http://wkbug.com/68089
    if (m_url.protocolIsData()) {
        String urlString = m_url.string();
        urlString.replace("#", "%23");
        return soup_uri_new(urlString.utf8().data());
    }

    KURL url = m_url;
    url.removeFragmentIdentifier();
    SoupURI* uri = soup_uri_new(url.string().utf8().data());

    // Versions of libsoup prior to 2.42 have a soup_uri_new that will convert empty passwords that are not
    // prefixed by a colon into null. Some parts of soup like the SoupAuthenticationManager will only be active
    // when both the username and password are non-null. When we have credentials, empty usernames and passwords
    // should be empty strings instead of null.
    if (!url.user().isEmpty() || !url.pass().isEmpty()) {
        soup_uri_set_user(uri, url.user().utf8().data());
        soup_uri_set_password(uri, url.pass().utf8().data());
    }
    return uri;
}
Ejemplo n.º 2
0
AtomicURL::AtomicURL( const KURL &url )
{
    if( url.isEmpty() )
        return;

    QString s = url.protocol() + "://";
    QString host = url.host();
    if( url.hasUser() )
    {
        s += url.user();
        host.prepend("@");
    }
    if( url.hasPass() )
        s += ':' + url.pass();
    if( url.port() )
        host += QString(":") + QString::number( url.port() );

    m_beginning = s + host;
    m_directory = url.directory();
    m_filename = url.fileName();
    m_end = url.query();
    if( url.hasRef() )
        m_end += QString("#") + url.ref();
    if (url != this->url())
    {
        debug() << "from: " << url << endl;
        debug() << "to:   " << this->url() << endl;
    }
}
bool DocumentThreadableLoader::checkCrossOriginAccessRedirectionUrl(const KURL& requestUrl, String& errorDescription)
{
    if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(requestUrl.protocol())) {
        errorDescription = "The request was redirected to a URL ('" + requestUrl.string() + "') which has a disallowed scheme for cross-origin requests.";
        return false;
    }

    if (!(requestUrl.user().isEmpty() && requestUrl.pass().isEmpty())) {
        errorDescription = "The request was redirected to a URL ('" + requestUrl.string() + "') containing userinfo, which is disallowed for cross-origin requests.";
        return false;
    }

    return true;
}
bool CrossOriginAccessControl::isLegalRedirectLocation(const KURL& requestURL, String& errorDescription)
{
    // CORS restrictions imposed on Location: URL -- http://www.w3.org/TR/cors/#redirect-steps (steps 2 + 3.)
    if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(requestURL.protocol())) {
        errorDescription = "The request was redirected to a URL ('" + requestURL.string() + "') which has a disallowed scheme for cross-origin requests.";
        return false;
    }

    if (!(requestURL.user().isEmpty() && requestURL.pass().isEmpty())) {
        errorDescription = "The request was redirected to a URL ('" + requestURL.string() + "') containing userinfo, which is disallowed for cross-origin requests.";
        return false;
    }

    return true;
}
Ejemplo n.º 5
0
void KMWIppSelect::initPrinter(KMPrinter *p)
{
	// storage variables
	QString	host, login, password;
	int	port;

	// save config
	host = CupsInfos::self()->host();
	login = CupsInfos::self()->login();
	password = CupsInfos::self()->password();
	port = CupsInfos::self()->port();

	m_list->clear();

	// retrieve printer list
	KURL	url = p->device();
	CupsInfos::self()->setHost(url.host());
	CupsInfos::self()->setLogin(url.user());
	CupsInfos::self()->setPassword(url.pass());
	CupsInfos::self()->setPort(url.port());
	IppRequest	req;
	QString		uri;
	req.setOperation(CUPS_GET_PRINTERS);
	uri = QString::fromLatin1("ipp://%1/printers/").arg(CupsInfos::self()->hostaddr());
	req.addURI(IPP_TAG_OPERATION,"printer-uri",uri);
	req.addKeyword(IPP_TAG_OPERATION,"requested-attributes",QString::fromLatin1("printer-name"));
	if (req.doRequest("/printers/"))
	{
		ipp_attribute_t	*attr = req.first();
		while (attr)
		{
			if (attr->name && strcmp(attr->name,"printer-name") == 0)
				m_list->insertItem(SmallIcon("kdeprint_printer"),QString::fromLatin1(attr->values[0].string.text));
			attr = attr->next;
		}
		m_list->sort();
	}

	// restore config
	CupsInfos::self()->setHost(host);
	CupsInfos::self()->setLogin(login);
	CupsInfos::self()->setPassword(password);
	CupsInfos::self()->setPort(port);
}
Ejemplo n.º 6
0
void Groupwise::getCalendar(const KURL &url)
{
    QString u = soapUrl(url);

    QString user = url.user();
    QString pass = url.pass();

    debugMessage("URL: " + u);
    debugMessage("User: "******"Password: "******"UTC"));

    kdDebug() << "Login" << endl;
    if(!server.login())
    {
        errorMessage(i18n("Unable to login: "******"Read calendar" << endl;
        if(!server.readCalendarSynchronous(&calendar))
        {
            errorMessage(i18n("Unable to read calendar data: ") + server.errorText());
        }
        kdDebug() << "Logout" << endl;
        server.logout();
    }

    KCal::ICalFormat format;

    QString ical = format.toString(&calendar);

    data(ical.utf8());

    finished();
}
ResourceRequestBlockedReason FrameFetchContext::canRequestInternal(Resource::Type type, const ResourceRequest& resourceRequest, const KURL& url, const ResourceLoaderOptions& options, bool forPreload, FetchRequest::OriginRestriction originRestriction, ResourceRequest::RedirectStatus redirectStatus) const
{
    if (InspectorInstrumentation::shouldBlockRequest(frame(), resourceRequest))
        return ResourceRequestBlockedReasonInspector;

    SecurityOrigin* securityOrigin = options.securityOrigin.get();
    if (!securityOrigin && m_document)
        securityOrigin = m_document->getSecurityOrigin();

    if (originRestriction != FetchRequest::NoOriginRestriction && securityOrigin && !securityOrigin->canDisplay(url)) {
        if (!forPreload)
            FrameLoader::reportLocalLoadFailed(frame(), url.elidedString());
        WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource URL was not allowed by SecurityOrigin::canDisplay");
        return ResourceRequestBlockedReasonOther;
    }

    // Some types of resources can be loaded only from the same origin. Other
    // types of resources, like Images, Scripts, and CSS, can be loaded from
    // any URL.
    switch (type) {
    case Resource::MainResource:
    case Resource::Image:
    case Resource::CSSStyleSheet:
    case Resource::Script:
    case Resource::Font:
    case Resource::Raw:
    case Resource::LinkPrefetch:
    case Resource::LinkPreload:
    case Resource::TextTrack:
    case Resource::ImportResource:
    case Resource::Media:
    case Resource::Manifest:
        // By default these types of resources can be loaded from any origin.
        // FIXME: Are we sure about Resource::Font?
        if (originRestriction == FetchRequest::RestrictToSameOrigin && !securityOrigin->canRequest(url)) {
            printAccessDeniedMessage(url);
            return ResourceRequestBlockedReasonOrigin;
        }
        break;
    case Resource::XSLStyleSheet:
        ASSERT(RuntimeEnabledFeatures::xsltEnabled());
    case Resource::SVGDocument:
        if (!securityOrigin->canRequest(url)) {
            printAccessDeniedMessage(url);
            return ResourceRequestBlockedReasonOrigin;
        }
        break;
    }

    // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved.
    bool shouldBypassMainWorldCSP = frame()->script().shouldBypassMainWorldCSP() || options.contentSecurityPolicyOption == DoNotCheckContentSecurityPolicy;

    // Don't send CSP messages for preloads, we might never actually display those items.
    ContentSecurityPolicy::ReportingStatus cspReporting = forPreload ?
        ContentSecurityPolicy::SuppressReport : ContentSecurityPolicy::SendReport;

    if (m_document) {
        DCHECK(m_document->contentSecurityPolicy());
        if (!shouldBypassMainWorldCSP && !m_document->contentSecurityPolicy()->allowRequest(resourceRequest.requestContext(), url, options.contentSecurityPolicyNonce, redirectStatus, cspReporting))
            return ResourceRequestBlockedReasonCSP;
    }

    if (type == Resource::Script || type == Resource::ImportResource) {
        ASSERT(frame());
        if (!frame()->loader().client()->allowScriptFromSource(!frame()->settings() || frame()->settings()->scriptEnabled(), url)) {
            frame()->loader().client()->didNotAllowScript();
            // TODO(estark): Use a different ResourceRequestBlockedReason
            // here, since this check has nothing to do with
            // CSP. https://crbug.com/600795
            return ResourceRequestBlockedReasonCSP;
        }
    } else if (type == Resource::Media || type == Resource::TextTrack) {
        ASSERT(frame());
        if (!frame()->loader().client()->allowMedia(url))
            return ResourceRequestBlockedReasonOther;
    }

    // SVG Images have unique security rules that prevent all subresource requests
    // except for data urls.
    if (type != Resource::MainResource && frame()->chromeClient().isSVGImageChromeClient() && !url.protocolIsData())
        return ResourceRequestBlockedReasonOrigin;

    // Measure the number of legacy URL schemes ('ftp://') and the number of embedded-credential
    // ('http://*****:*****@...') resources embedded as subresources. in the hopes that we can
    // block them at some point in the future.
    if (resourceRequest.frameType() != WebURLRequest::FrameTypeTopLevel) {
        ASSERT(frame()->document());
        if (SchemeRegistry::shouldTreatURLSchemeAsLegacy(url.protocol()) && !SchemeRegistry::shouldTreatURLSchemeAsLegacy(frame()->document()->getSecurityOrigin()->protocol()))
            UseCounter::count(frame()->document(), UseCounter::LegacyProtocolEmbeddedAsSubresource);
        if (!url.user().isEmpty() || !url.pass().isEmpty())
            UseCounter::count(frame()->document(), UseCounter::RequestedSubresourceWithEmbeddedCredentials);
    }

    // Check for mixed content. We do this second-to-last so that when folks block
    // mixed content with a CSP policy, they don't get a warning. They'll still
    // get a warning in the console about CSP blocking the load.
    MixedContentChecker::ReportingStatus mixedContentReporting = forPreload ?
        MixedContentChecker::SuppressReport : MixedContentChecker::SendReport;
    if (MixedContentChecker::shouldBlockFetch(frame(), resourceRequest, url, mixedContentReporting))
        return ResourceRequestBlockedReasonMixedContent;

    // Let the client have the final say into whether or not the load should proceed.
    DocumentLoader* documentLoader = masterDocumentLoader();
    if (documentLoader && documentLoader->subresourceFilter() && type != Resource::MainResource && type != Resource::ImportResource && !documentLoader->subresourceFilter()->allowLoad(url, resourceRequest.requestContext()))
        return ResourceRequestBlockedReasonSubresourceFilter;

    return ResourceRequestBlockedReasonNone;
}
Ejemplo n.º 8
0
void Groupwise::updateAddressbook(const KURL &url)
{
    kdDebug() << "Groupwise::updateAddressbook() " << url << endl;
    QString u = soapUrl(url);

    QString user = url.user();
    QString pass = url.pass();

    debugMessage("update AB URL: " + u);
    debugMessage("update AB User: "******"update AB Password: "******"?")
    {
        errorMessage(i18n("No addressbook IDs given."));
        return;
    }
    else
    {
        QStringList ids;

        query = query.mid(1);
        QStringList queryItems = QStringList::split("&", query);
        QStringList::ConstIterator it;
        for(it = queryItems.begin(); it != queryItems.end(); ++it)
        {
            QStringList item = QStringList::split("=", (*it));
            if(item.count() == 2 && item[ 0 ] == "addressbookid")
            {
                ids.append(item[ 1 ]);
            }
            if(item.count() == 2 && item[ 0 ] == "lastSeqNo")
                lastSequenceNumber = item[ 1 ].toULong();
            if(item.count() == 2 && item[ 0 ] == "PORebuildTime")
                lastPORebuildTime = item[ 1 ].toULong();
        }

        debugMessage("update IDs: " + ids.join(","));

        GroupwiseServer server(u, user, pass, 0);
        connect(&server, SIGNAL(errorMessage(const QString &, bool)),
                SLOT(slotServerErrorMessage(const QString &, bool)));
        connect(&server, SIGNAL(gotAddressees(const KABC::Addressee::List)),
                SLOT(slotReadReceiveAddressees(const KABC::Addressee::List)));

        kdDebug() << "  Login" << endl;
        if(!server.login())
        {
            errorMessage(i18n("Unable to login: "******"  Updating Addressbook" << endl;
            if(!server.updateAddressBooks(ids, lastSequenceNumber + 1, lastPORebuildTime))
            {
                error(KIO::ERR_NO_CONTENT, server.errorText());
                //errorMessage( i18n("Unable to update addressbook data: ") + server.errorText() );
            }
            kdDebug() << "  Logout" << endl;
            server.logout();
            finished();
        }
    }
}
Ejemplo n.º 9
0
void Groupwise::getAddressbook(const KURL &url)
{
    QString u = soapUrl(url);

    QString user = url.user();
    QString pass = url.pass();

    debugMessage("URL: " + u);
    debugMessage("User: "******"Password: "******"?")
    {
        errorMessage(i18n("No addressbook IDs given."));
    }
    else
    {
        QStringList ids;

        query = query.mid(1);
        QStringList queryItems = QStringList::split("&", query);
        QStringList::ConstIterator it;
        for(it = queryItems.begin(); it != queryItems.end(); ++it)
        {
            QStringList item = QStringList::split("=", (*it));
            if(item.count() == 2 && item[ 0 ] == "addressbookid")
            {
                ids.append(item[ 1 ]);
            }
        }

        debugMessage("IDs: " + ids.join(","));

        GroupwiseServer server(u, user, pass, 0);

        connect(&server, SIGNAL(readAddressBookTotalSize(int)),
                SLOT(slotReadAddressBookTotalSize(int)));
        connect(&server, SIGNAL(readAddressBookProcessedSize(int)),
                SLOT(slotReadAddressBookProcessedSize(int)));
        connect(&server, SIGNAL(errorMessage(const QString &, bool)),
                SLOT(slotServerErrorMessage(const QString &, bool)));
        connect(&server, SIGNAL(gotAddressees(const KABC::Addressee::List)),
                SLOT(slotReadReceiveAddressees(const KABC::Addressee::List)));

        kdDebug() << "Login" << endl;
        if(!server.login())
        {
            errorMessage(i18n("Unable to login: "******"Read Addressbook" << endl;
            if(!server.readAddressBooksSynchronous(ids))
            {
                errorMessage(i18n("Unable to read addressbook data: ") + server.errorText());
            }
            kdDebug() << "Logout" << endl;
            server.logout();
            finished();
        }
    }
}
Ejemplo n.º 10
0
void Groupwise::getFreeBusy(const KURL &url)
{
    QString file = url.filename();
    if(file.right(4) != ".ifb")
    {
        QString error = i18n("Illegal filename. File has to have '.ifb' suffix.");
        errorMessage(error);
    }
    else
    {
        QString email = file.left(file.length() - 4);
        debugMessage("Email: " + email);

        // Sanitise local Nuernberg email addresses
        kdDebug() << "Email before sanitizing: " << email << endl;
        email = email.replace(QRegExp("\\.EMEA5-1\\.EMEA5"), "");
        email = email.replace(QRegExp("\\.Suse.INTERNET"), "");
        kdDebug() << "Email after sanitizing: " << email << endl;

        QString u = soapUrl(url);

        QString user = url.user();
        QString pass = url.pass();

        debugMessage("URL: " + u);
        debugMessage("User: "******"Password: "******"Need username and password to read Free/Busy information."));
        }
        else
        {
            GroupwiseServer server(u, user, pass, 0);

            // FIXME: Read range from configuration or URL parameters.
            QDate start = QDate::currentDate().addDays(-3);
            QDate end = QDate::currentDate().addDays(60);

            fb->setDtStart(start);
            fb->setDtEnd(end);

            kdDebug() << "Login" << endl;

            if(!server.login())
            {
                errorMessage(i18n("Unable to login: "******"Read free/busy" << endl;
                if(!server.readFreeBusy(email, start, end, fb))
                {
                    errorMessage(i18n("Unable to read free/busy data: ") + server.errorText());
                }
                kdDebug() << "Read free/busy" << endl;
                server.logout();
            }
        }

#if 0
        QDateTime s = QDateTime(QDate(2004, 9, 27), QTime(10, 0));
        QDateTime e = QDateTime(QDate(2004, 9, 27), QTime(11, 0));

        fb->addPeriod(s, e);
#endif

        // FIXME: This does not take into account the time zone!
        KCal::ICalFormat format;

        QString ical = format.createScheduleMessage(fb, KCal::Scheduler::Publish);

        data(ical.utf8());

        finished();
    }
}
ResourceRequestBlockedReason FrameFetchContext::canRequestInternal(Resource::Type type, const ResourceRequest& resourceRequest, const KURL& url, const ResourceLoaderOptions& options, bool forPreload, FetchRequest::OriginRestriction originRestriction) const
{
    InstrumentingAgents* agents = InspectorInstrumentation::instrumentingAgentsFor(frame());
    if (agents && agents->inspectorResourceAgent()) {
        if (agents->inspectorResourceAgent()->shouldBlockRequest(resourceRequest))
            return ResourceRequestBlockedReasonInspector;
    }

    SecurityOrigin* securityOrigin = options.securityOrigin.get();
    if (!securityOrigin && m_document)
        securityOrigin = m_document->securityOrigin();

    if (originRestriction != FetchRequest::NoOriginRestriction && securityOrigin && !securityOrigin->canDisplay(url)) {
        if (!forPreload)
            FrameLoader::reportLocalLoadFailed(frame(), url.elidedString());
        WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource URL was not allowed by SecurityOrigin::canDisplay");
        return ResourceRequestBlockedReasonOther;
    }

    // Some types of resources can be loaded only from the same origin. Other
    // types of resources, like Images, Scripts, and CSS, can be loaded from
    // any URL.
    switch (type) {
    case Resource::MainResource:
    case Resource::Image:
    case Resource::CSSStyleSheet:
    case Resource::Script:
    case Resource::Font:
    case Resource::Raw:
    case Resource::LinkPrefetch:
    case Resource::LinkSubresource:
    case Resource::LinkPreload:
    case Resource::TextTrack:
    case Resource::ImportResource:
    case Resource::Media:
        // By default these types of resources can be loaded from any origin.
        // FIXME: Are we sure about Resource::Font?
        if (originRestriction == FetchRequest::RestrictToSameOrigin && !securityOrigin->canRequest(url)) {
            printAccessDeniedMessage(url);
            return ResourceRequestBlockedReasonOrigin;
        }
        break;
    case Resource::XSLStyleSheet:
        ASSERT(RuntimeEnabledFeatures::xsltEnabled());
    case Resource::SVGDocument:
        if (!securityOrigin->canRequest(url)) {
            printAccessDeniedMessage(url);
            return ResourceRequestBlockedReasonOrigin;
        }
        break;
    }

    // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved.
    bool shouldBypassMainWorldCSP = frame()->script().shouldBypassMainWorldCSP() || options.contentSecurityPolicyOption == DoNotCheckContentSecurityPolicy;

    // Don't send CSP messages for preloads, we might never actually display those items.
    ContentSecurityPolicy::ReportingStatus cspReporting = forPreload ?
        ContentSecurityPolicy::SuppressReport : ContentSecurityPolicy::SendReport;

    // As of CSP2, for requests that are the results of redirects, the match
    // algorithm should ignore the path component of the URL.
    ContentSecurityPolicy::RedirectStatus redirectStatus = resourceRequest.followedRedirect() ? ContentSecurityPolicy::DidRedirect : ContentSecurityPolicy::DidNotRedirect;

    // m_document can be null, but not in any of the cases where csp is actually used below.
    // ImageResourceTest.MultipartImage crashes w/o the m_document null check.
    // I believe it's the Resource::Raw case.
    const ContentSecurityPolicy* csp = m_document ? m_document->contentSecurityPolicy() : nullptr;

    // FIXME: This would be cleaner if moved this switch into an allowFromSource()
    // helper on this object which took a Resource::Type, then this block would
    // collapse to about 10 lines for handling Raw and Script special cases.
    switch (type) {
    case Resource::XSLStyleSheet:
        ASSERT(RuntimeEnabledFeatures::xsltEnabled());
        ASSERT(ContentSecurityPolicy::isScriptResource(resourceRequest));
        if (!shouldBypassMainWorldCSP && !csp->allowScriptFromSource(url, redirectStatus, cspReporting))
            return ResourceRequestBlockedReasonCSP;
        break;
    case Resource::Script:
    case Resource::ImportResource:
        ASSERT(ContentSecurityPolicy::isScriptResource(resourceRequest));
        if (!shouldBypassMainWorldCSP && !csp->allowScriptFromSource(url, redirectStatus, cspReporting))
            return ResourceRequestBlockedReasonCSP;

        if (!frame()->loader().client()->allowScriptFromSource(!frame()->settings() || frame()->settings()->scriptEnabled(), url)) {
            frame()->loader().client()->didNotAllowScript();
            return ResourceRequestBlockedReasonCSP;
        }
        break;
    case Resource::CSSStyleSheet:
        ASSERT(ContentSecurityPolicy::isStyleResource(resourceRequest));
        if (!shouldBypassMainWorldCSP && !csp->allowStyleFromSource(url, redirectStatus, cspReporting))
            return ResourceRequestBlockedReasonCSP;
        break;
    case Resource::SVGDocument:
    case Resource::Image:
        ASSERT(ContentSecurityPolicy::isImageResource(resourceRequest));
        if (!shouldBypassMainWorldCSP && !csp->allowImageFromSource(url, redirectStatus, cspReporting))
            return ResourceRequestBlockedReasonCSP;
        break;
    case Resource::Font: {
        ASSERT(ContentSecurityPolicy::isFontResource(resourceRequest));
        if (!shouldBypassMainWorldCSP && !csp->allowFontFromSource(url, redirectStatus, cspReporting))
            return ResourceRequestBlockedReasonCSP;
        break;
    }
    case Resource::MainResource:
    case Resource::Raw:
    case Resource::LinkPrefetch:
    case Resource::LinkSubresource:
    case Resource::LinkPreload:
        break;
    case Resource::Media:
    case Resource::TextTrack:
        ASSERT(ContentSecurityPolicy::isMediaResource(resourceRequest));
        if (!shouldBypassMainWorldCSP && !csp->allowMediaFromSource(url, redirectStatus, cspReporting))
            return ResourceRequestBlockedReasonCSP;

        if (!frame()->loader().client()->allowMedia(url))
            return ResourceRequestBlockedReasonOther;
        break;
    }

    // SVG Images have unique security rules that prevent all subresource requests
    // except for data urls.
    if (type != Resource::MainResource && frame()->chromeClient().isSVGImageChromeClient() && !url.protocolIsData())
        return ResourceRequestBlockedReasonOrigin;

    // FIXME: Once we use RequestContext for CSP (http://crbug.com/390497), remove this extra check.
    if (resourceRequest.requestContext() == WebURLRequest::RequestContextManifest) {
        if (!shouldBypassMainWorldCSP && !csp->allowManifestFromSource(url, redirectStatus, cspReporting))
            return ResourceRequestBlockedReasonCSP;
    }

    // Measure the number of legacy URL schemes ('ftp://') and the number of embedded-credential
    // ('http://*****:*****@...') resources embedded as subresources. in the hopes that we can
    // block them at some point in the future.
    if (resourceRequest.frameType() != WebURLRequest::FrameTypeTopLevel) {
        ASSERT(frame()->document());
        if (SchemeRegistry::shouldTreatURLSchemeAsLegacy(url.protocol()) && !SchemeRegistry::shouldTreatURLSchemeAsLegacy(frame()->document()->securityOrigin()->protocol()))
            UseCounter::count(frame()->document(), UseCounter::LegacyProtocolEmbeddedAsSubresource);
        if (!url.user().isEmpty() || !url.pass().isEmpty())
            UseCounter::count(frame()->document(), UseCounter::RequestedSubresourceWithEmbeddedCredentials);
    }

    // Measure the number of pages that load resources after a redirect
    // when a CSP is active, to see if implementing CSP
    // 'unsafe-redirect' is feasible.
    if (csp && csp->isActive() && resourceRequest.frameType() != WebURLRequest::FrameTypeTopLevel && resourceRequest.frameType() != WebURLRequest::FrameTypeAuxiliary && redirectStatus == ContentSecurityPolicy::DidRedirect) {
        ASSERT(frame()->document());
        UseCounter::count(frame()->document(), UseCounter::ResourceLoadedAfterRedirectWithCSP);
    }

    // Last of all, check for mixed content. We do this last so that when
    // folks block mixed content with a CSP policy, they don't get a warning.
    // They'll still get a warning in the console about CSP blocking the load.
    MixedContentChecker::ReportingStatus mixedContentReporting = forPreload ?
        MixedContentChecker::SuppressReport : MixedContentChecker::SendReport;
    if (MixedContentChecker::shouldBlockFetch(MixedContentChecker::effectiveFrameForFrameType(frame(), resourceRequest.frameType()), resourceRequest, url, mixedContentReporting))
        return ResourceRequestBlockedReasonMixedContent;

    return ResourceRequestBlockedReasonNone;
}