summaryrefslogtreecommitdiffstats
path: root/modules/libjar/nsJARProtocolHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/libjar/nsJARProtocolHandler.cpp')
-rw-r--r--modules/libjar/nsJARProtocolHandler.cpp188
1 files changed, 188 insertions, 0 deletions
diff --git a/modules/libjar/nsJARProtocolHandler.cpp b/modules/libjar/nsJARProtocolHandler.cpp
new file mode 100644
index 000000000..38de73f14
--- /dev/null
+++ b/modules/libjar/nsJARProtocolHandler.cpp
@@ -0,0 +1,188 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsAutoPtr.h"
+#include "nsJARProtocolHandler.h"
+#include "nsIIOService.h"
+#include "nsCRT.h"
+#include "nsIComponentManager.h"
+#include "nsIServiceManager.h"
+#include "nsJARURI.h"
+#include "nsIURL.h"
+#include "nsJARChannel.h"
+#include "nsXPIDLString.h"
+#include "nsString.h"
+#include "nsNetCID.h"
+#include "nsIMIMEService.h"
+#include "nsMimeTypes.h"
+#include "nsThreadUtils.h"
+
+static NS_DEFINE_CID(kZipReaderCacheCID, NS_ZIPREADERCACHE_CID);
+
+#define NS_JAR_CACHE_SIZE 32
+
+//-----------------------------------------------------------------------------
+
+nsJARProtocolHandler *gJarHandler = nullptr;
+
+nsJARProtocolHandler::nsJARProtocolHandler()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+}
+
+nsJARProtocolHandler::~nsJARProtocolHandler()
+{
+ MOZ_ASSERT(gJarHandler == this);
+ gJarHandler = nullptr;
+}
+
+nsresult
+nsJARProtocolHandler::Init()
+{
+ nsresult rv;
+
+ mJARCache = do_CreateInstance(kZipReaderCacheCID, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ rv = mJARCache->Init(NS_JAR_CACHE_SIZE);
+ return rv;
+}
+
+nsIMIMEService *
+nsJARProtocolHandler::MimeService()
+{
+ if (!mMimeService)
+ mMimeService = do_GetService("@mozilla.org/mime;1");
+
+ return mMimeService.get();
+}
+
+NS_IMPL_ISUPPORTS(nsJARProtocolHandler,
+ nsIJARProtocolHandler,
+ nsIProtocolHandler,
+ nsISupportsWeakReference)
+
+nsJARProtocolHandler*
+nsJARProtocolHandler::GetSingleton()
+{
+ if (!gJarHandler) {
+ gJarHandler = new nsJARProtocolHandler();
+ if (!gJarHandler)
+ return nullptr;
+
+ NS_ADDREF(gJarHandler);
+ nsresult rv = gJarHandler->Init();
+ if (NS_FAILED(rv)) {
+ NS_RELEASE(gJarHandler);
+ return nullptr;
+ }
+ }
+ NS_ADDREF(gJarHandler);
+ return gJarHandler;
+}
+
+NS_IMETHODIMP
+nsJARProtocolHandler::GetJARCache(nsIZipReaderCache* *result)
+{
+ *result = mJARCache;
+ NS_ADDREF(*result);
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIProtocolHandler methods:
+
+NS_IMETHODIMP
+nsJARProtocolHandler::GetScheme(nsACString &result)
+{
+ result.AssignLiteral("jar");
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsJARProtocolHandler::GetDefaultPort(int32_t *result)
+{
+ *result = -1; // no port for JAR: URLs
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsJARProtocolHandler::GetProtocolFlags(uint32_t *result)
+{
+ // URI_LOADABLE_BY_ANYONE, since it's our inner URI that will matter
+ // anyway.
+ *result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_ANYONE;
+ /* Although jar uris have their own concept of relative urls
+ it is very different from the standard behaviour, so we
+ have to say norelative here! */
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsJARProtocolHandler::NewURI(const nsACString &aSpec,
+ const char *aCharset,
+ nsIURI *aBaseURI,
+ nsIURI **result)
+{
+ nsresult rv = NS_OK;
+
+ RefPtr<nsJARURI> jarURI = new nsJARURI();
+ if (!jarURI)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ rv = jarURI->Init(aCharset);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = jarURI->SetSpecWithBase(aSpec, aBaseURI);
+ if (NS_FAILED(rv))
+ return rv;
+
+ NS_ADDREF(*result = jarURI);
+ return rv;
+}
+
+NS_IMETHODIMP
+nsJARProtocolHandler::NewChannel2(nsIURI* uri,
+ nsILoadInfo* aLoadInfo,
+ nsIChannel** result)
+{
+ nsJARChannel *chan = new nsJARChannel();
+ if (!chan)
+ return NS_ERROR_OUT_OF_MEMORY;
+ NS_ADDREF(chan);
+
+ nsresult rv = chan->Init(uri);
+ if (NS_FAILED(rv)) {
+ NS_RELEASE(chan);
+ return rv;
+ }
+
+ // set the loadInfo on the new channel
+ rv = chan->SetLoadInfo(aLoadInfo);
+ if (NS_FAILED(rv)) {
+ NS_RELEASE(chan);
+ return rv;
+ }
+
+ *result = chan;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsJARProtocolHandler::NewChannel(nsIURI *uri, nsIChannel **result)
+{
+ return NewChannel2(uri, nullptr, result);
+}
+
+
+NS_IMETHODIMP
+nsJARProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval)
+{
+ // don't override anything.
+ *_retval = false;
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////