modules/libjar/nsJARProtocolHandler.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsAutoPtr.h"
     7 #include "nsJARProtocolHandler.h"
     8 #include "nsIIOService.h"
     9 #include "nsCRT.h"
    10 #include "nsIComponentManager.h"
    11 #include "nsIServiceManager.h"
    12 #include "nsJARURI.h"
    13 #include "nsIURL.h"
    14 #include "nsJARChannel.h"
    15 #include "nsXPIDLString.h"
    16 #include "nsString.h"
    17 #include "nsNetCID.h"
    18 #include "nsIMIMEService.h"
    19 #include "nsMimeTypes.h"
    20 #include "nsIRemoteOpenFileListener.h"
    21 #include "nsIHashable.h"
    22 #include "nsThreadUtils.h"
    23 #include "nsXULAppAPI.h"
    24 #include "nsTArray.h"
    26 static NS_DEFINE_CID(kZipReaderCacheCID, NS_ZIPREADERCACHE_CID);
    28 #define NS_JAR_CACHE_SIZE 32
    30 //-----------------------------------------------------------------------------
    32 nsJARProtocolHandler *gJarHandler = nullptr;
    34 nsJARProtocolHandler::nsJARProtocolHandler()
    35 : mIsMainProcess(XRE_GetProcessType() == GeckoProcessType_Default)
    36 {
    37     MOZ_ASSERT(NS_IsMainThread());
    38 }
    40 nsJARProtocolHandler::~nsJARProtocolHandler()
    41 {
    42     MOZ_ASSERT(gJarHandler == this);
    43     gJarHandler = nullptr;
    44 }
    46 nsresult
    47 nsJARProtocolHandler::Init()
    48 {
    49     nsresult rv;
    51     mJARCache = do_CreateInstance(kZipReaderCacheCID, &rv);
    52     if (NS_FAILED(rv)) return rv;
    54     rv = mJARCache->Init(NS_JAR_CACHE_SIZE);
    55     return rv;
    56 }
    58 nsIMIMEService * 
    59 nsJARProtocolHandler::MimeService()
    60 {
    61     if (!mMimeService)
    62         mMimeService = do_GetService("@mozilla.org/mime;1");
    64     return mMimeService.get();
    65 }
    67 bool
    68 nsJARProtocolHandler::RemoteOpenFileInProgress(
    69                                            nsIHashable *aRemoteFile,
    70                                            nsIRemoteOpenFileListener *aListener)
    71 {
    72     MOZ_ASSERT(NS_IsMainThread());
    73     MOZ_ASSERT(aRemoteFile);
    74     MOZ_ASSERT(aListener);
    76     if (IsMainProcess()) {
    77         MOZ_CRASH("Shouldn't be called in the main process!");
    78     }
    80     RemoteFileListenerArray *listeners;
    81     if (mRemoteFileListeners.Get(aRemoteFile, &listeners)) {
    82         listeners->AppendElement(aListener);
    83         return true;
    84     }
    86     // We deliberately don't put the listener in the new array since the first
    87     // load is handled differently.
    88     mRemoteFileListeners.Put(aRemoteFile, new RemoteFileListenerArray());
    89     return false;
    90 }
    92 void
    93 nsJARProtocolHandler::RemoteOpenFileComplete(nsIHashable *aRemoteFile,
    94                                              nsresult aStatus)
    95 {
    96     MOZ_ASSERT(NS_IsMainThread());
    97     MOZ_ASSERT(aRemoteFile);
    99     if (IsMainProcess()) {
   100         MOZ_CRASH("Shouldn't be called in the main process!");
   101     }
   103     RemoteFileListenerArray *tempListeners;
   104     if (!mRemoteFileListeners.Get(aRemoteFile, &tempListeners)) {
   105         return;
   106     }
   108     // Save the listeners in a stack array. The call to Remove() below will
   109     // delete the tempListeners array.
   110     RemoteFileListenerArray listeners;
   111     tempListeners->SwapElements(listeners);
   113     mRemoteFileListeners.Remove(aRemoteFile);
   115     // Technically we must fail OnRemoteFileComplete() since OpenNSPRFileDesc()
   116     // won't succeed here. We've trained nsJARChannel to recognize
   117     // NS_ERROR_ALREADY_OPENED in this case as "proceed to JAR cache hit."
   118     nsresult status = NS_SUCCEEDED(aStatus) ? NS_ERROR_ALREADY_OPENED : aStatus;
   120     uint32_t count = listeners.Length();
   121     for (uint32_t index = 0; index < count; index++) {
   122         listeners[index]->OnRemoteFileOpenComplete(status);
   123     }
   124 }
   126 NS_IMPL_ISUPPORTS(nsJARProtocolHandler,
   127                   nsIJARProtocolHandler,
   128                   nsIProtocolHandler,
   129                   nsISupportsWeakReference)
   131 nsJARProtocolHandler*
   132 nsJARProtocolHandler::GetSingleton()
   133 {
   134     if (!gJarHandler) {
   135         gJarHandler = new nsJARProtocolHandler();
   136         if (!gJarHandler)
   137             return nullptr;
   139         NS_ADDREF(gJarHandler);
   140         nsresult rv = gJarHandler->Init();
   141         if (NS_FAILED(rv)) {
   142             NS_RELEASE(gJarHandler);
   143             return nullptr;
   144         }
   145     }
   146     NS_ADDREF(gJarHandler);
   147     return gJarHandler;
   148 }
   150 NS_IMETHODIMP
   151 nsJARProtocolHandler::GetJARCache(nsIZipReaderCache* *result)
   152 {
   153     *result = mJARCache;
   154     NS_ADDREF(*result);
   155     return NS_OK;
   156 }
   158 ////////////////////////////////////////////////////////////////////////////////
   159 // nsIProtocolHandler methods:
   161 NS_IMETHODIMP
   162 nsJARProtocolHandler::GetScheme(nsACString &result)
   163 {
   164     result.AssignLiteral("jar");
   165     return NS_OK;
   166 }
   168 NS_IMETHODIMP
   169 nsJARProtocolHandler::GetDefaultPort(int32_t *result)
   170 {
   171     *result = -1;        // no port for JAR: URLs
   172     return NS_OK;
   173 }
   175 NS_IMETHODIMP
   176 nsJARProtocolHandler::GetProtocolFlags(uint32_t *result)
   177 {
   178     // URI_LOADABLE_BY_ANYONE, since it's our inner URI that will matter
   179     // anyway.
   180     *result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_ANYONE;
   181     /* Although jar uris have their own concept of relative urls
   182        it is very different from the standard behaviour, so we
   183        have to say norelative here! */
   184     return NS_OK;
   185 }
   187 NS_IMETHODIMP
   188 nsJARProtocolHandler::NewURI(const nsACString &aSpec,
   189                              const char *aCharset,
   190                              nsIURI *aBaseURI,
   191                              nsIURI **result)
   192 {
   193     nsresult rv = NS_OK;
   195     nsRefPtr<nsJARURI> jarURI = new nsJARURI();
   196     if (!jarURI)
   197         return NS_ERROR_OUT_OF_MEMORY;
   199     rv = jarURI->Init(aCharset);
   200     NS_ENSURE_SUCCESS(rv, rv);
   202     rv = jarURI->SetSpecWithBase(aSpec, aBaseURI);
   203     if (NS_FAILED(rv))
   204         return rv;
   206     NS_ADDREF(*result = jarURI);
   207     return rv;
   208 }
   210 NS_IMETHODIMP
   211 nsJARProtocolHandler::NewChannel(nsIURI *uri, nsIChannel **result)
   212 {
   213     nsJARChannel *chan = new nsJARChannel();
   214     if (!chan)
   215         return NS_ERROR_OUT_OF_MEMORY;
   216     NS_ADDREF(chan);
   218     nsresult rv = chan->Init(uri);
   219     if (NS_FAILED(rv)) {
   220         NS_RELEASE(chan);
   221         return rv;
   222     }
   224     *result = chan;
   225     return NS_OK;
   226 }
   229 NS_IMETHODIMP
   230 nsJARProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval)
   231 {
   232     // don't override anything.
   233     *_retval = false;
   234     return NS_OK;
   235 }
   237 ////////////////////////////////////////////////////////////////////////////////

mercurial