void appendAsyncCallStack(ExecutionContext* executionContext, ScriptCallStack* callStack) { InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(executionContext); if (!instrumentingAgents) return; if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent()) callStack->setAsyncCallStack(debuggerAgent->currentAsyncStackTraceForConsole()); }
void InspectorInstrumentation::didRecalculateStyleImpl(const InspectorInstrumentationCookie& cookie) { if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie)) timelineAgent->didRecalculateStyle(); InstrumentingAgents* instrumentingAgents = cookie.first; if (!instrumentingAgents) return; if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) resourceAgent->didRecalculateStyle(); }
void willDestroyResourceImpl(Resource* cachedResource) { if (!instrumentingAgentsSet) return; HashSet<InstrumentingAgents*>::iterator end = instrumentingAgentsSet->end(); for (HashSet<InstrumentingAgents*>::iterator it = instrumentingAgentsSet->begin(); it != end; ++it) { InstrumentingAgents* instrumentingAgents = *it; if (InspectorResourceAgent* inspectorResourceAgent = instrumentingAgents->inspectorResourceAgent()) inspectorResourceAgent->willDestroyResource(cachedResource); } }
void InspectorInstrumentation::willEvaluateWorkerScript(WorkerContext* workerContext, int workerThreadStartMode) { if (workerThreadStartMode != PauseWorkerContextOnStart) return; InstrumentingAgents* instrumentingAgents = instrumentationForWorkerContext(workerContext); if (!instrumentingAgents) return; #if ENABLE(JAVASCRIPT_DEBUGGER) if (InspectorRuntimeAgent* runtimeAgent = instrumentingAgents->inspectorRuntimeAgent()) runtimeAgent->pauseWorkerContext(workerContext); #endif }
void InspectorInstrumentation::didReceiveResourceResponseImpl(const InspectorInstrumentationCookie& cookie, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response) { if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie)) timelineAgent->didReceiveResourceResponse(); if (!loader) return; InstrumentingAgents* instrumentingAgents = cookie.first; if (!instrumentingAgents) return; if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent()) resourceAgent->didReceiveResponse(identifier, loader, response); if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent()) consoleAgent->didReceiveResponse(identifier, response); // This should come AFTER resource notification, front-end relies on this. }
Vector<String> Internals::consoleMessageArgumentCounts(Document* document) const { InstrumentingAgents* instrumentingAgents = instrumentationForPage(document->page()); if (!instrumentingAgents) return Vector<String>(); InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent(); if (!consoleAgent) return Vector<String>(); Vector<unsigned> counts = consoleAgent->consoleMessageArgumentCounts(); Vector<String> result(counts.size()); for (size_t i = 0; i < counts.size(); i++) result[i] = String::number(counts[i]); return result; }
bool timelineAgentEnabled(ExecutionContext* executionContext) { InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(executionContext); return instrumentingAgents && instrumentingAgents->inspectorTimelineAgent(); }
bool consoleAgentEnabled(ExecutionContext* executionContext) { InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(executionContext); InspectorConsoleAgent* consoleAgent = instrumentingAgents ? instrumentingAgents->inspectorConsoleAgent() : 0; return consoleAgent && consoleAgent->enabled(); }
bool canvasAgentEnabled(ExecutionContext* executionContext) { InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(executionContext); return instrumentingAgents && instrumentingAgents->inspectorCanvasAgent(); }
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; }