Bug 1510241 - Proxy HttpChannel MIME blocking message to the child process. r=flod,dragana
authorTom Schuster <evilpies@gmail.com>
Thu, 27 Dec 2018 06:25:51 +0000
changeset 511953 28a22fe8900402db17bb6eef75d764e239c9276d
parent 511952 d6c5ea714d9dcfe4c96c86dc1c5b5c0abd19b6f2
child 511954 7afd23e41eeb4f62a9145e3cdd4b616206620244
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflod, dragana
bugs1510241
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1510241 - Proxy HttpChannel MIME blocking message to the child process. r=flod,dragana Differential Revision: https://phabricator.services.mozilla.com/D14858
dom/locales/en-US/chrome/security/security.properties
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParent.h
netwerk/protocol/http/InterceptedHttpChannel.cpp
netwerk/protocol/http/InterceptedHttpChannel.h
netwerk/protocol/http/NullHttpChannel.cpp
netwerk/protocol/http/PHttpChannel.ipdl
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpChannel.h
netwerk/protocol/http/nsIHttpChannel.idl
netwerk/protocol/viewsource/nsViewSourceChannel.cpp
--- a/dom/locales/en-US/chrome/security/security.properties
+++ b/dom/locales/en-US/chrome/security/security.properties
@@ -75,21 +75,21 @@ UnsupportedHashAlg=Unsupported hash algorithm in the integrity attribute: “%1$S”
 # LOCALIZATION NOTE: Do not translate "integrity"
 NoValidMetadata=The integrity attribute does not contain any valid metadata.
 
 # LOCALIZATION NOTE: Do not translate "RC4".
 WeakCipherSuiteWarning=This site uses the cipher RC4 for encryption, which is deprecated and insecure.
 
 #XCTO: nosniff
 # LOCALIZATION NOTE: Do not translate "X-Content-Type-Options: nosniff".
-MimeTypeMismatch=The resource from “%1$S” was blocked due to MIME type mismatch (X-Content-Type-Options: nosniff).
+MimeTypeMismatch2=The resource from “%1$S” was blocked due to MIME type (“%2$S”) mismatch (X-Content-Type-Options: nosniff).
 # LOCALIZATION NOTE: Do not translate "X-Content-Type-Options" and also do not trasnlate "nosniff".
 XCTOHeaderValueMissing=X-Content-Type-Options header warning: value was “%1$S”; did you mean to send “nosniff”?
 
-BlockScriptWithWrongMimeType=Script from “%1$S” was blocked because of a disallowed MIME type.
+BlockScriptWithWrongMimeType2=Script from “%1$S” was blocked because of a disallowed MIME type (“%2$S”).
 
 # LOCALIZATION NOTE: Do not translate "data: URI".
 BlockTopLevelDataURINavigation=Navigation to toplevel data: URI not allowed (Blocked loading of: “%1$S”)
 BlockSubresourceRedirectToData=Redirecting to insecure data: URI not allowed (Blocked loading of: “%1$S”)
 
 BlockSubresourceFTP=Loading FTP subresource within http(s) page not allowed (Blocked loading of: “%1$S”)
 
 # LOCALIZATION NOTE (BrowserUpgradeInsecureDisplayRequest):
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -44,21 +44,22 @@
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/net/ChannelDiverterChild.h"
 #include "mozilla/net/DNS.h"
 #include "SerializedLoadContext.h"
 #include "nsInputStreamPump.h"
 #include "InterceptedChannel.h"
 #include "mozIThirdPartyUtil.h"
 #include "nsContentSecurityManager.h"
+#include "nsICompressConvStats.h"
 #include "nsIDeprecationWarner.h"
-#include "nsICompressConvStats.h"
 #include "nsIDocument.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsIEventTarget.h"
+#include "nsIScriptError.h"
 #include "nsRedirectHistoryEntry.h"
 #include "nsSocketTransportService2.h"
 #include "nsStreamUtils.h"
 #include "nsThreadUtils.h"
 #include "nsCORSListenerProxy.h"
 #include "nsApplicationCache.h"
 #include "TrackingDummyChannel.h"
 
@@ -3780,16 +3781,43 @@ HttpChannelChild::LogBlockedCORSRequest(
     bool privateBrowsing =
         !!mLoadInfo->GetOriginAttributes().mPrivateBrowsingId;
     nsCORSListenerProxy::LogBlockedCORSRequest(innerWindowID, privateBrowsing,
                                                aMessage, aCategory);
   }
   return NS_OK;
 }
 
+mozilla::ipc::IPCResult HttpChannelChild::RecvLogMimeTypeMismatch(
+    const nsCString& aMessageName, const bool& aWarning, const nsString& aURL,
+    const nsString& aContentType) {
+  Unused << LogMimeTypeMismatch(aMessageName, aWarning, aURL, aContentType);
+  return IPC_OK();
+}
+
+NS_IMETHODIMP
+HttpChannelChild::LogMimeTypeMismatch(const nsACString& aMessageName,
+                                      bool aWarning, const nsAString& aURL,
+                                      const nsAString& aContentType) {
+  nsCOMPtr<nsIDocument> doc;
+  if (mLoadInfo) {
+    mLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
+  }
+
+  nsAutoString url(aURL);
+  nsAutoString contentType(aContentType);
+  const char16_t* params[] = { url.get(), contentType.get() };
+  nsContentUtils::ReportToConsole(
+      aWarning ? nsIScriptError::warningFlag : nsIScriptError::errorFlag,
+      NS_LITERAL_CSTRING("MIMEMISMATCH"), doc,
+      nsContentUtils::eSECURITY_PROPERTIES, nsCString(aMessageName).get(),
+      params, ArrayLength(params));
+  return NS_OK;
+}
+
 void HttpChannelChild::MaybeCallSynthesizedCallback() {
   if (!mSynthesizedCallback) {
     return;
   }
 
   mSynthesizedCallback->BodyComplete(mStatus);
   mSynthesizedCallback = nullptr;
 }
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -199,16 +199,23 @@ class HttpChannelChild final : public PH
   // Get event target for processing network events.
   already_AddRefed<nsIEventTarget> GetNeckoTarget() override;
 
   virtual mozilla::ipc::IPCResult RecvLogBlockedCORSRequest(
       const nsString& aMessage, const nsCString& aCategory) override;
   NS_IMETHOD LogBlockedCORSRequest(const nsAString& aMessage,
                                    const nsACString& aCategory) override;
 
+  virtual mozilla::ipc::IPCResult RecvLogMimeTypeMismatch(
+      const nsCString& aMessageName, const bool& aWarning, const nsString& aURL,
+      const nsString& aContentType) override;
+  NS_IMETHOD LogMimeTypeMismatch(const nsACString& aMessageName, bool aWarning,
+                                 const nsAString& aURL,
+                                 const nsAString& aContentType) override;
+
  private:
   nsresult AsyncCallImpl(void (HttpChannelChild::*funcPtr)(),
                          nsRunnableMethod<HttpChannelChild>** retval);
 
   class OverrideRunnable : public Runnable {
    public:
     OverrideRunnable(HttpChannelChild* aChannel, HttpChannelChild* aNewChannel,
                      InterceptStreamListener* aListener, nsIInputStream* aInput,
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -2391,10 +2391,22 @@ nsresult HttpChannelParent::LogBlockedCO
                                                   const nsACString& aCategory) {
   if (mIPCClosed || NS_WARN_IF(!SendLogBlockedCORSRequest(
                         nsString(aMessage), nsCString(aCategory)))) {
     return NS_ERROR_UNEXPECTED;
   }
   return NS_OK;
 }
 
+nsresult HttpChannelParent::LogMimeTypeMismatch(const nsACString& aMessageName,
+                                                bool aWarning,
+                                                const nsAString& aURL,
+                                                const nsAString& aContentType) {
+  if (mIPCClosed || NS_WARN_IF(!SendLogMimeTypeMismatch(
+                        nsCString(aMessageName), aWarning, nsString(aURL),
+                        nsString(aContentType)))) {
+    return NS_ERROR_UNEXPECTED;
+  }
+  return NS_OK;
+}
+
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -211,16 +211,19 @@ class HttpChannelParent final : public n
 
   friend class HttpChannelParentListener;
   RefPtr<mozilla::dom::TabParent> mTabParent;
 
   MOZ_MUST_USE nsresult ReportSecurityMessage(
       const nsAString& aMessageTag, const nsAString& aMessageCategory) override;
   nsresult LogBlockedCORSRequest(const nsAString& aMessage,
                                  const nsACString& aCategory) override;
+  nsresult LogMimeTypeMismatch(const nsACString& aMessageName, bool aWarning,
+                               const nsAString& aURL,
+                               const nsAString& aContentType) override;
 
   // Calls SendDeleteSelf and sets mIPCClosed to true because we should not
   // send any more messages after that. Bug 1274886
   MOZ_MUST_USE bool DoSendDeleteSelf();
   // Called to notify the parent channel to not send any more IPC messages.
   virtual mozilla::ipc::IPCResult RecvDeletingChannel() override;
   virtual mozilla::ipc::IPCResult RecvFinishInterceptedRedirect() override;
 
--- a/netwerk/protocol/http/InterceptedHttpChannel.cpp
+++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp
@@ -550,16 +550,24 @@ InterceptedHttpChannel::AsyncOpen2(nsISt
 NS_IMETHODIMP
 InterceptedHttpChannel::LogBlockedCORSRequest(const nsAString& aMessage,
                                               const nsACString& aCategory) {
   // Synthetic responses should not trigger CORS blocking.
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
+InterceptedHttpChannel::LogMimeTypeMismatch(const nsACString& aMessageName,
+                                            bool aWarning,
+                                            const nsAString& aURL,
+                                            const nsAString& aContentType) {
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
 InterceptedHttpChannel::SetupFallbackChannel(const char* aFallbackKey) {
   // AppCache should not be used with service worker intercepted channels.
   // This should never be called.
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 InterceptedHttpChannel::SetPriority(int32_t aPriority) {
--- a/netwerk/protocol/http/InterceptedHttpChannel.h
+++ b/netwerk/protocol/http/InterceptedHttpChannel.h
@@ -153,16 +153,21 @@ class InterceptedHttpChannel final
   NS_IMETHOD
   AsyncOpen2(nsIStreamListener* aListener) override;
 
   NS_IMETHOD
   LogBlockedCORSRequest(const nsAString& aMessage,
                         const nsACString& aCategory) override;
 
   NS_IMETHOD
+  LogMimeTypeMismatch(const nsACString& aMessageName, bool aWarning,
+                      const nsAString& aURL,
+                      const nsAString& aContentType) override;
+
+  NS_IMETHOD
   SetupFallbackChannel(const char* aFallbackKey) override;
 
   NS_IMETHOD
   SetPriority(int32_t aPriority) override;
 
   NS_IMETHOD
   SetClassFlags(uint32_t aClassFlags) override;
 
--- a/netwerk/protocol/http/NullHttpChannel.cpp
+++ b/netwerk/protocol/http/NullHttpChannel.cpp
@@ -785,16 +785,23 @@ NullHttpChannel::SetIsMainDocumentChanne
 
 NS_IMETHODIMP
 NullHttpChannel::LogBlockedCORSRequest(const nsAString &aMessage,
                                        const nsACString &aCategory) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
+NullHttpChannel::LogMimeTypeMismatch(const nsACString &aMessageName,
+                                     bool aWarning, const nsAString &aURL,
+                                     const nsAString &aContentType) {
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
 NullHttpChannel::SetReportResourceTiming(bool enabled) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullHttpChannel::GetReportResourceTiming(bool *_retval) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -164,16 +164,21 @@ child:
   // Tell the child to issue a deprecation warning.
   async IssueDeprecationWarning(uint32_t warning, bool asError);
 
   // When CORS blocks the request in the parent process, it doesn't have the
   // correct window ID, so send the message to the child for logging to the web
   // console.
   async LogBlockedCORSRequest(nsString message, nsCString category);
 
+  async LogMimeTypeMismatch(nsCString messageName,
+                            bool warning,
+                            nsString url,
+                            nsString contentType);
+
   async AttachStreamFilter(Endpoint<PStreamFilterParent> aEndpoint);
 
   // See ADivertableParentChannel::CancelDiversion
   async CancelDiversion();
 
   async OriginalCacheInputStreamAvailable(OptionalIPCStream stream);
 both:
   // After receiving this message, the parent also calls
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -399,16 +399,27 @@ NS_IMETHODIMP
 nsHttpChannel::LogBlockedCORSRequest(const nsAString &aMessage,
                                      const nsACString &aCategory) {
   if (mWarningReporter) {
     return mWarningReporter->LogBlockedCORSRequest(aMessage, aCategory);
   }
   return NS_ERROR_UNEXPECTED;
 }
 
+NS_IMETHODIMP
+nsHttpChannel::LogMimeTypeMismatch(const nsACString &aMessageName,
+                                   bool aWarning, const nsAString &aURL,
+                                   const nsAString &aContentType) {
+  if (mWarningReporter) {
+    return mWarningReporter->LogMimeTypeMismatch(aMessageName, aWarning, aURL,
+                                                 aContentType);
+  }
+  return NS_ERROR_UNEXPECTED;
+}
+
 //-----------------------------------------------------------------------------
 // nsHttpChannel <private>
 //-----------------------------------------------------------------------------
 
 nsresult nsHttpChannel::PrepareToConnect() {
   LOG(("nsHttpChannel::PrepareToConnect [this=%p]\n", this));
 
   AddCookiesToRequest();
@@ -1201,32 +1212,28 @@ nsresult nsHttpChannel::SetupTransaction
 
   rv = nsInputStreamPump::Create(getter_AddRefs(mTransactionPump),
                                  responseStream);
   return rv;
 }
 
 // Helper Function to report messages to the console when loading
 // a resource was blocked due to a MIME type mismatch.
-void ReportTypeBlocking(nsIURI *aURI, nsILoadInfo *aLoadInfo,
-                        const char *aMessageName) {
-  NS_ConvertUTF8toUTF16 specUTF16(aURI->GetSpecOrDefault());
-  const char16_t *params[] = {specUTF16.get()};
-  nsCOMPtr<nsIDocument> doc;
-  if (aLoadInfo) {
-    aLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
-  }
-  nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
-                                  NS_LITERAL_CSTRING("MIMEMISMATCH"), doc,
-                                  nsContentUtils::eSECURITY_PROPERTIES,
-                                  aMessageName, params, ArrayLength(params));
+void ReportTypeBlocking(nsHttpChannel *aChannel, const char *aMessageName,
+                        nsIURI *aURI, const nsACString &aContentType) {
+  NS_ConvertUTF8toUTF16 spec(aURI->GetSpecOrDefault());
+  NS_ConvertUTF8toUTF16 contentType(aContentType);
+
+  aChannel->LogMimeTypeMismatch(nsCString(aMessageName), false, spec,
+                                contentType);
 }
 
 // Check and potentially enforce X-Content-Type-Options: nosniff
-nsresult ProcessXCTO(nsIURI *aURI, nsHttpResponseHead *aResponseHead,
+nsresult ProcessXCTO(nsHttpChannel *aChannel, nsIURI *aURI,
+                     nsHttpResponseHead *aResponseHead,
                      nsILoadInfo *aLoadInfo) {
   if (!aURI || !aResponseHead || !aLoadInfo) {
     // if there is no uri, no response head or no loadInfo, then there is
     // nothing to do
     return NS_OK;
   }
 
   // 1) Query the XCTO header and check if 'nosniff' is the first value.
@@ -1271,34 +1278,35 @@ nsresult ProcessXCTO(nsIURI *aURI, nsHtt
   aResponseHead->ContentType(contentType);
 
   // 3) Compare the expected MIME type with the actual type
   if (aLoadInfo->GetExternalContentPolicyType() ==
       nsIContentPolicy::TYPE_STYLESHEET) {
     if (contentType.EqualsLiteral(TEXT_CSS)) {
       return NS_OK;
     }
-    ReportTypeBlocking(aURI, aLoadInfo, "MimeTypeMismatch");
+    ReportTypeBlocking(aChannel, "MimeTypeMismatch2", aURI, contentType);
     return NS_ERROR_CORRUPTED_CONTENT;
   }
 
   if (aLoadInfo->GetExternalContentPolicyType() ==
       nsIContentPolicy::TYPE_SCRIPT) {
     if (nsContentUtils::IsJavascriptMIMEType(
             NS_ConvertUTF8toUTF16(contentType))) {
       return NS_OK;
     }
-    ReportTypeBlocking(aURI, aLoadInfo, "MimeTypeMismatch");
+    ReportTypeBlocking(aChannel, "MimeTypeMismatch2", aURI, contentType);
     return NS_ERROR_CORRUPTED_CONTENT;
   }
   return NS_OK;
 }
 
 // Ensure that a load of type script has correct MIME type
-nsresult EnsureMIMEOfScript(nsIURI *aURI, nsHttpResponseHead *aResponseHead,
+nsresult EnsureMIMEOfScript(nsHttpChannel *aChannel, nsIURI *aURI,
+                            nsHttpResponseHead *aResponseHead,
                             nsILoadInfo *aLoadInfo) {
   if (!aURI || !aResponseHead || !aLoadInfo) {
     // if there is no uri, no response head or no loadInfo, then there is
     // nothing to do
     return NS_OK;
   }
 
   if (aLoadInfo->GetExternalContentPolicyType() !=
@@ -1420,17 +1428,18 @@ nsresult EnsureMIMEOfScript(nsIURI *aURI
                                    "security.block_script_with_wrong_mime");
     }
 
     // Do not block the load if the feature is not enabled.
     if (!sCachedBlockScriptWithWrongMime) {
       return NS_OK;
     }
 
-    ReportTypeBlocking(aURI, aLoadInfo, "BlockScriptWithWrongMimeType");
+    ReportTypeBlocking(aChannel, "BlockScriptWithWrongMimeType2", aURI,
+                       contentType);
     return NS_ERROR_CORRUPTED_CONTENT;
   }
 
   if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/plain"))) {
     // script load has type text/plain
     AccumulateCategorical(
         Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_plain);
     return NS_OK;
@@ -1527,20 +1536,20 @@ nsresult nsHttpChannel::CallOnStartReque
     if (mListener) {
       nsCOMPtr<nsIStreamListener> deleteProtector(mListener);
       deleteProtector->OnStartRequest(this, mListenerContext);
     }
 
     mOnStartRequestCalled = true;
   });
 
-  nsresult rv = EnsureMIMEOfScript(mURI, mResponseHead, mLoadInfo);
+  nsresult rv = EnsureMIMEOfScript(this, mURI, mResponseHead, mLoadInfo);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = ProcessXCTO(mURI, mResponseHead, mLoadInfo);
+  rv = ProcessXCTO(this, mURI, mResponseHead, mLoadInfo);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Allow consumers to override our content type
   if (mLoadFlags & LOAD_CALL_CONTENT_SNIFFERS) {
     // NOTE: We can have both a txn pump and a cache pump when the cache
     // content is partial. In that case, we need to read from the cache,
     // because that's the one that has the initial contents. If that fails
     // then give the transaction pump a shot.
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -46,18 +46,21 @@ namespace net {
 
 class nsChannelClassifier;
 class Http2PushedStream;
 
 class HttpChannelSecurityWarningReporter : public nsISupports {
  public:
   virtual MOZ_MUST_USE nsresult ReportSecurityMessage(
       const nsAString &aMessageTag, const nsAString &aMessageCategory) = 0;
-  virtual nsresult LogBlockedCORSRequest(const nsAString &aMessage,
-                                         const nsACString &aCategory) = 0;
+  virtual MOZ_MUST_USE nsresult LogBlockedCORSRequest(
+      const nsAString &aMessage, const nsACString &aCategory) = 0;
+  virtual MOZ_MUST_USE nsresult
+  LogMimeTypeMismatch(const nsACString &aMessageName, bool aWarning,
+                      const nsAString &aURL, const nsAString &aContentType) = 0;
 };
 
 //-----------------------------------------------------------------------------
 // nsHttpChannel
 //-----------------------------------------------------------------------------
 
 // Use to support QI nsIChannel to nsHttpChannel
 #define NS_HTTPCHANNEL_IID                           \
@@ -194,16 +197,19 @@ class nsHttpChannel final : public HttpB
   // nsICorsPreflightCallback
   NS_IMETHOD OnPreflightSucceeded() override;
   NS_IMETHOD OnPreflightFailed(nsresult aError) override;
 
   MOZ_MUST_USE nsresult AddSecurityMessage(
       const nsAString &aMessageTag, const nsAString &aMessageCategory) override;
   NS_IMETHOD LogBlockedCORSRequest(const nsAString &aMessage,
                                    const nsACString &aCategory) override;
+  NS_IMETHOD LogMimeTypeMismatch(const nsACString &aMessageName, bool aWarning,
+                                 const nsAString &aURL,
+                                 const nsAString &aContentType) override;
 
   void SetWarningReporter(HttpChannelSecurityWarningReporter *aReporter);
   HttpChannelSecurityWarningReporter *GetWarningReporter();
 
  public: /* internal necko use only */
   uint32_t GetRequestTime() const { return mRequestTime; }
 
   nsresult AsyncOpenFinal(TimeStamp aTimeStamp);
--- a/netwerk/protocol/http/nsIHttpChannel.idl
+++ b/netwerk/protocol/http/nsIHttpChannel.idl
@@ -526,9 +526,14 @@ interface nsIHttpChannel : nsIChannel
      *
      * @param aMessage
      *        The message to print in the console.
      *
      * @param aCategory
      *        The category under which the message should be displayed.
      */
     void logBlockedCORSRequest(in AString aMessage, in ACString aCategory);
+
+    void logMimeTypeMismatch(in ACString aMessageName,
+                             in boolean aWarning,
+                             in AString aURL,
+                             in AString aContentType);
 };
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
@@ -1040,16 +1040,28 @@ nsViewSourceChannel::LogBlockedCORSReque
   if (!mHttpChannel) {
     NS_WARNING(
         "nsViewSourceChannel::LogBlockedCORSRequest mHttpChannel is null");
     return NS_ERROR_UNEXPECTED;
   }
   return mHttpChannel->LogBlockedCORSRequest(aMessage, aCategory);
 }
 
+NS_IMETHODIMP
+nsViewSourceChannel::LogMimeTypeMismatch(const nsACString &aMessageName,
+                                         bool aWarning, const nsAString &aURL,
+                                         const nsAString &aContentType) {
+  if (!mHttpChannel) {
+    NS_WARNING("nsViewSourceChannel::LogMimeTypeMismatch mHttpChannel is null");
+    return NS_ERROR_UNEXPECTED;
+  }
+  return mHttpChannel->LogMimeTypeMismatch(aMessageName, aWarning, aURL,
+                                           aContentType);
+}
+
 const nsTArray<mozilla::Tuple<nsCString, nsCString>>
     &nsViewSourceChannel::PreferredAlternativeDataTypes() {
   if (mCacheInfoChannel) {
     return mCacheInfoChannel->PreferredAlternativeDataTypes();
   }
   return mEmptyArray;
 }