| Index: Source/core/loader/MixedContentChecker.cpp | 
| diff --git a/Source/core/loader/MixedContentChecker.cpp b/Source/core/loader/MixedContentChecker.cpp | 
| index 62bbf611caafdbd91447449200f2bac0563471ad..fe43f73ad880e66d78223482d88fd85075240bf2 100644 | 
| --- a/Source/core/loader/MixedContentChecker.cpp | 
| +++ b/Source/core/loader/MixedContentChecker.cpp | 
| @@ -212,12 +212,15 @@ void MixedContentChecker::logToConsole(LocalFrame* frame, const KURL& url, WebUR | 
| frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, messageLevel, message)); | 
| } | 
|  | 
| -// static | 
| -bool MixedContentChecker::shouldBlockFetch(LocalFrame* frame, const ResourceRequest& resourceRequest, const KURL& url) | 
| +LocalFrame* MixedContentChecker::inWhichFrameIsThisContentMixed(LocalFrame* frame, WebURLRequest::RequestContext requestContext, WebURLRequest::FrameType frameType, const KURL& url) | 
| { | 
| // No frame, no mixed content: | 
| if (!frame) | 
| -        return false; | 
| +        return nullptr; | 
| + | 
| +    // We only care about subresource loads; top-level navigations cannot be mixed content. | 
| +    if (frameType == WebURLRequest::FrameTypeTopLevel) | 
| +        return nullptr; | 
|  | 
| // Check the top frame first. | 
| if (Frame* top = frame->tree().top()) { | 
| @@ -225,27 +228,41 @@ bool MixedContentChecker::shouldBlockFetch(LocalFrame* frame, const ResourceRequ | 
| // is in a different process from the current frame. Until that is done, we bail out | 
| // early and allow the load. | 
| if (!top->isLocalFrame()) | 
| -            return false; | 
| +            return nullptr; | 
|  | 
| LocalFrame* localTop = toLocalFrame(top); | 
| -        if (frame != localTop && shouldBlockFetch(localTop, resourceRequest, url)) | 
| -            return true; | 
| +        if (frame != localTop && inWhichFrameIsThisContentMixed(localTop, requestContext, frameType, url)) | 
| +            return localTop; | 
| } | 
|  | 
| -    // We only care about subresource loads; top-level navigations cannot be mixed content. | 
| -    if (resourceRequest.frameType() == WebURLRequest::FrameTypeTopLevel) | 
| -        return false; | 
| +    // Just count these for the moment, don't block them. | 
| +    if (Platform::current()->isReservedIPAddress(url) && !Platform::current()->isReservedIPAddress(KURL(ParsedURLString, frame->document()->securityOrigin()->toString()))) | 
| +        UseCounter::count(frame->document(), contextTypeFromContext(requestContext) == ContextTypeBlockable ? UseCounter::MixedContentPrivateIPInPublicWebsiteActive : UseCounter::MixedContentPrivateIPInPublicWebsitePassive); | 
|  | 
| // No mixed content, no problem. | 
| if (!isMixedContent(frame->document()->securityOrigin(), url)) | 
| +        return nullptr; | 
| + | 
| +    return frame; | 
| +} | 
| + | 
| +// static | 
| +bool MixedContentChecker::shouldBlockFetch(LocalFrame* frame, WebURLRequest::RequestContext requestContext, WebURLRequest::FrameType frameType, const KURL& url) | 
| +{ | 
| +    LocalFrame* effectiveFrame = inWhichFrameIsThisContentMixed(frame, requestContext, frameType, url); | 
| +    if (!effectiveFrame) | 
| return false; | 
|  | 
| -    Settings* settings = frame->settings(); | 
| -    FrameLoaderClient* client = frame->loader().client(); | 
| -    SecurityOrigin* securityOrigin = frame->document()->securityOrigin(); | 
| +    // We grab the settings and client from the frame in which the content was mixed, as it might be | 
| +    // configured to allow mixed content in a different way than the frame in which the content | 
| +    // loads (e.g. if Frame A is allowed to frame an insecure Frame B, we defer to Frame A's settings | 
| +    // when evaluating Frame B's subresource loads). Yes, this is confusing. | 
| +    Settings* settings = effectiveFrame->settings(); | 
| +    FrameLoaderClient* client = effectiveFrame->loader().client(); | 
| +    SecurityOrigin* securityOrigin = effectiveFrame->document()->securityOrigin(); | 
| bool allowed = false; | 
|  | 
| -    ContextType contextType = contextTypeFromContext(resourceRequest.requestContext()); | 
| +    ContextType contextType = contextTypeFromContext(requestContext); | 
| if (contextType == ContextTypeBlockableUnlessLax) | 
| contextType = RuntimeEnabledFeatures::laxMixedContentCheckingEnabled() ? ContextTypeOptionallyBlockable : ContextTypeBlockable; | 
|  | 
| @@ -271,7 +288,15 @@ bool MixedContentChecker::shouldBlockFetch(LocalFrame* frame, const ResourceRequ | 
| return true; | 
| }; | 
|  | 
| -    logToConsole(frame, url, resourceRequest.requestContext(), allowed); | 
| +    // While we use the |effectiveFrame| to grab the settings object, we log the console error in | 
| +    // |frame|, where the violation actually happened. | 
| +    String message = String::format( | 
| +        "Mixed Content: The page at '%s' was loaded over HTTPS, but requested an insecure %s '%s'. %s", | 
| +        frame->document()->url().elidedString().utf8().data(), typeNameFromContext(requestContext), url.elidedString().utf8().data(), | 
| +        allowed ? "This content should also be served over HTTPS." : "This request has been blocked; the content must be served over HTTPS."); | 
| +    MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLevel; | 
| +    frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, messageLevel, message)); | 
| + | 
| return !allowed; | 
| } | 
|  | 
|  |