[tor-commits] [tor-browser] 18/37: Bug 1757604 - Make content-type on JAR channels behave the same as HTTP channels. r=Gijs, a=RyanVM

gitolite role git at cupani.torproject.org
Wed Jun 22 18:27:27 UTC 2022


This is an automated email from the git hooks/post-receive script.

richard pushed a commit to branch tor-browser-91.11.0esr-11.5-1
in repository tor-browser.

commit e5894b0d6475393f12a81c2f064a42e543a8b812
Author: Emilio Cobos Álvarez <emilio at crisal.io>
AuthorDate: Sat Apr 30 01:24:47 2022 +0000

    Bug 1757604 - Make content-type on JAR channels behave the same as HTTP channels. r=Gijs, a=RyanVM
    
    That is, treat it as a hint if called before open, and as an override if
    called after. Override the hint on open.
    
    This is a less invasive change that is green on try and also fixes the
    issue.
    
    Differential Revision: https://phabricator.services.mozilla.com/D145098
---
 modules/libjar/nsJARChannel.cpp                    | 83 ++++++++++++----------
 modules/libjar/nsJARChannel.h                      | 11 ++-
 .../tests/browser/browser_xpcom_graph_wait.js      |  1 +
 3 files changed, 55 insertions(+), 40 deletions(-)

diff --git a/modules/libjar/nsJARChannel.cpp b/modules/libjar/nsJARChannel.cpp
index bb2b6f681608c..be5cf64d740cc 100644
--- a/modules/libjar/nsJARChannel.cpp
+++ b/modules/libjar/nsJARChannel.cpp
@@ -387,7 +387,7 @@ nsresult nsJARChannel::OpenLocalFile() {
   if (mLoadGroup) {
     mLoadGroup->AddRequest(this, nullptr);
   }
-  mOpened = true;
+  SetOpened();
 
   if (mPreCachedJarReader || !mEnableOMT) {
     RefPtr<nsJARInputThunk> input;
@@ -715,53 +715,53 @@ nsJARChannel::GetSecurityInfo(nsISupports** aSecurityInfo) {
   return NS_OK;
 }
 
+bool nsJARChannel::GetContentTypeGuess(nsACString& aResult) const {
+  const char *ext = nullptr, *fileName = mJarEntry.get();
+  int32_t len = mJarEntry.Length();
+
+  // check if we're displaying a directory
+  // mJarEntry will be empty if we're trying to display
+  // the topmost directory in a zip, e.g. jar:foo.zip!/
+  if (ENTRY_IS_DIRECTORY(mJarEntry)) {
+    aResult.AssignLiteral(APPLICATION_HTTP_INDEX_FORMAT);
+    return true;
+  }
+
+  // Not a directory, take a guess by its extension
+  for (int32_t i = len - 1; i >= 0; i--) {
+    if (fileName[i] == '.') {
+      ext = &fileName[i + 1];
+      break;
+    }
+  }
+  if (!ext) {
+    return false;
+  }
+  nsIMIMEService* mimeServ = gJarHandler->MimeService();
+  if (!mimeServ) {
+    return false;
+  }
+  mimeServ->GetTypeFromExtension(nsDependentCString(ext), aResult);
+  return !aResult.IsEmpty();
+}
+
 NS_IMETHODIMP
-nsJARChannel::GetContentType(nsACString& result) {
+nsJARChannel::GetContentType(nsACString& aResult) {
   // If the Jar file has not been open yet,
   // We return application/x-unknown-content-type
   if (!mOpened) {
-    result.AssignLiteral(UNKNOWN_CONTENT_TYPE);
+    aResult.AssignLiteral(UNKNOWN_CONTENT_TYPE);
     return NS_OK;
   }
 
-  if (mContentType.IsEmpty()) {
-    //
-    // generate content type and set it
-    //
-    const char *ext = nullptr, *fileName = mJarEntry.get();
-    int32_t len = mJarEntry.Length();
-
-    // check if we're displaying a directory
-    // mJarEntry will be empty if we're trying to display
-    // the topmost directory in a zip, e.g. jar:foo.zip!/
-    if (ENTRY_IS_DIRECTORY(mJarEntry)) {
-      mContentType.AssignLiteral(APPLICATION_HTTP_INDEX_FORMAT);
-    } else {
-      // not a directory, take a guess by its extension
-      for (int32_t i = len - 1; i >= 0; i--) {
-        if (fileName[i] == '.') {
-          ext = &fileName[i + 1];
-          break;
-        }
-      }
-      if (ext) {
-        nsIMIMEService* mimeServ = gJarHandler->MimeService();
-        if (mimeServ)
-          mimeServ->GetTypeFromExtension(nsDependentCString(ext), mContentType);
-      }
-      if (mContentType.IsEmpty())
-        mContentType.AssignLiteral(UNKNOWN_CONTENT_TYPE);
-    }
-  }
-  result = mContentType;
+  aResult = mContentType;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsJARChannel::SetContentType(const nsACString& aContentType) {
-  // If someone gives us a type hint we should just use that type instead of
-  // doing our guessing.  So we don't care when this is being called.
-
+  // We behave like HTTP channels (treat this as a hint if called before open,
+  // and override the charset if called after open).
   // mContentCharset is unchanged if not parsed
   NS_ParseResponseContentType(aContentType, mContentType, mContentCharset);
   return NS_OK;
@@ -1031,11 +1031,20 @@ nsJARChannel::Open(nsIInputStream** aStream) {
   if (NS_FAILED(rv)) return rv;
 
   input.forget(aStream);
-  mOpened = true;
+  SetOpened();
 
   return NS_OK;
 }
 
+void nsJARChannel::SetOpened() {
+  MOZ_ASSERT(!mOpened, "Opening channel twice?");
+  mOpened = true;
+  // Compute the content type now.
+  if (!GetContentTypeGuess(mContentType)) {
+    mContentType.Assign(UNKNOWN_CONTENT_TYPE);
+  }
+}
+
 NS_IMETHODIMP
 nsJARChannel::AsyncOpen(nsIStreamListener* aListener) {
   LOG(("nsJARChannel::AsyncOpen [this=%p]\n", this));
diff --git a/modules/libjar/nsJARChannel.h b/modules/libjar/nsJARChannel.h
index 7480abd8429da..59fcd4ee7c328 100644
--- a/modules/libjar/nsJARChannel.h
+++ b/modules/libjar/nsJARChannel.h
@@ -66,10 +66,15 @@ class nsJARChannel final : public nsIJARChannel,
   void NotifyError(nsresult aError);
   void FireOnProgress(uint64_t aProgress);
 
+  // Returns false if we don't know the content type of this channel, in which
+  // case we should use the content-type hint.
+  bool GetContentTypeGuess(nsACString&) const;
+  void SetOpened();
+
   nsCString mSpec;
 
   bool mOpened;
-  Atomic<bool, ReleaseAcquire> mCanceled;
+  mozilla::Atomic<bool, mozilla::ReleaseAcquire> mCanceled;
   bool mOnDataCalled = false;
 
   RefPtr<nsJARProtocolHandler> mJarHandler;
@@ -86,14 +91,14 @@ class nsJARChannel final : public nsIJARChannel,
   nsCString mContentCharset;
   int64_t mContentLength;
   uint32_t mLoadFlags;
-  Atomic<nsresult, ReleaseAcquire> mStatus;
+  mozilla::Atomic<nsresult, mozilla::ReleaseAcquire> mStatus;
   bool mIsPending;  // the AsyncOpen is in progress.
 
   bool mEnableOMT;
   // |Cancel()|, |Suspend()|, and |Resume()| might be called during AsyncOpen.
   struct {
     bool isCanceled;
-    Atomic<uint32_t> suspendCount;
+    mozilla::Atomic<uint32_t> suspendCount;
   } mPendingEvent;
 
   nsCOMPtr<nsIInputStreamPump> mPump;
diff --git a/toolkit/components/backgroundtasks/tests/browser/browser_xpcom_graph_wait.js b/toolkit/components/backgroundtasks/tests/browser/browser_xpcom_graph_wait.js
index ab012807f7345..22b6b61013283 100644
--- a/toolkit/components/backgroundtasks/tests/browser/browser_xpcom_graph_wait.js
+++ b/toolkit/components/backgroundtasks/tests/browser/browser_xpcom_graph_wait.js
@@ -102,6 +102,7 @@ const backgroundtaskPhases = {
         },
         "@mozilla.org/xpcom/debug;1",
         "@mozilla.org/xre/app-info;1",
+        "@mozilla.org/mime;1",
       ],
     },
   },

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tor-commits mailing list