michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsWyciwyg.h" michael@0: #include "nsWyciwygChannel.h" michael@0: #include "nsWyciwygProtocolHandler.h" michael@0: #include "nsNetCID.h" michael@0: #include "nsServiceManagerUtils.h" michael@0: #include "plstr.h" michael@0: #include "nsNetUtil.h" michael@0: #include "nsIObserverService.h" michael@0: #include "mozIApplicationClearPrivateDataParams.h" michael@0: michael@0: #include "mozilla/net/NeckoChild.h" michael@0: michael@0: using namespace mozilla::net; michael@0: #include "mozilla/net/WyciwygChannelChild.h" michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: nsWyciwygProtocolHandler::nsWyciwygProtocolHandler() michael@0: { michael@0: #if defined(PR_LOGGING) michael@0: if (!gWyciwygLog) michael@0: gWyciwygLog = PR_NewLogModule("nsWyciwygChannel"); michael@0: #endif michael@0: michael@0: LOG(("Creating nsWyciwygProtocolHandler [this=%p].\n", this)); michael@0: } michael@0: michael@0: nsWyciwygProtocolHandler::~nsWyciwygProtocolHandler() michael@0: { michael@0: LOG(("Deleting nsWyciwygProtocolHandler [this=%p]\n", this)); michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS(nsWyciwygProtocolHandler, michael@0: nsIProtocolHandler) michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // nsIProtocolHandler methods: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: NS_IMETHODIMP michael@0: nsWyciwygProtocolHandler::GetScheme(nsACString &result) michael@0: { michael@0: result = "wyciwyg"; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsWyciwygProtocolHandler::GetDefaultPort(int32_t *result) michael@0: { michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsWyciwygProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval) michael@0: { michael@0: // don't override anything. michael@0: *_retval = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsWyciwygProtocolHandler::NewURI(const nsACString &aSpec, michael@0: const char *aCharset, // ignored michael@0: nsIURI *aBaseURI, michael@0: nsIURI **result) michael@0: { michael@0: nsresult rv; michael@0: michael@0: nsCOMPtr url = do_CreateInstance(NS_SIMPLEURI_CONTRACTID, &rv); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = url->SetSpec(aSpec); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: *result = url; michael@0: NS_ADDREF(*result); michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsWyciwygProtocolHandler::NewChannel(nsIURI* url, nsIChannel* *result) michael@0: { michael@0: if (mozilla::net::IsNeckoChild()) michael@0: mozilla::net::NeckoChild::InitNeckoChild(); michael@0: michael@0: NS_ENSURE_ARG_POINTER(url); michael@0: nsresult rv; michael@0: michael@0: nsCOMPtr channel; michael@0: if (IsNeckoChild()) { michael@0: NS_ENSURE_TRUE(gNeckoChild != nullptr, NS_ERROR_FAILURE); michael@0: michael@0: WyciwygChannelChild *wcc = static_cast( michael@0: gNeckoChild->SendPWyciwygChannelConstructor()); michael@0: if (!wcc) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: michael@0: channel = wcc; michael@0: rv = wcc->Init(url); michael@0: if (NS_FAILED(rv)) michael@0: PWyciwygChannelChild::Send__delete__(wcc); michael@0: } else michael@0: { michael@0: // If original channel used https, make sure PSM is initialized michael@0: // (this may be first channel to load during a session restore) michael@0: nsAutoCString path; michael@0: rv = url->GetPath(path); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: int32_t slashIndex = path.FindChar('/', 2); michael@0: if (slashIndex == kNotFound) michael@0: return NS_ERROR_FAILURE; michael@0: if (path.Length() < (uint32_t)slashIndex + 1 + 5) michael@0: return NS_ERROR_FAILURE; michael@0: if (!PL_strncasecmp(path.get() + slashIndex + 1, "https", 5)) michael@0: net_EnsurePSMInit(); michael@0: michael@0: nsWyciwygChannel *wc = new nsWyciwygChannel(); michael@0: channel = wc; michael@0: rv = wc->Init(url); michael@0: } michael@0: michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: channel.forget(result); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsWyciwygProtocolHandler::GetProtocolFlags(uint32_t *result) michael@0: { michael@0: // Should this be an an nsINestedURI? We don't really want random webpages michael@0: // loading these URIs... michael@0: michael@0: // Note that using URI_INHERITS_SECURITY_CONTEXT here is OK -- untrusted code michael@0: // is not allowed to link to wyciwyg URIs and users shouldn't be able to get michael@0: // at them, and nsDocShell::InternalLoad forbids non-history loads of these michael@0: // URIs. And when loading from history we end up using the principal from michael@0: // the history entry, which we put there ourselves, so all is ok. michael@0: *result = URI_NORELATIVE | URI_NOAUTH | URI_DANGEROUS_TO_LOAD | michael@0: URI_INHERITS_SECURITY_CONTEXT; michael@0: return NS_OK; michael@0: }