michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* vim:set ts=4 sw=4 sts=4 et: */ 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 "nsViewSourceHandler.h" michael@0: #include "nsViewSourceChannel.h" michael@0: #include "nsNetUtil.h" michael@0: #include "nsSimpleNestedURI.h" michael@0: michael@0: #define VIEW_SOURCE "view-source" michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: NS_IMPL_ISUPPORTS(nsViewSourceHandler, nsIProtocolHandler) michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // nsIProtocolHandler methods: michael@0: michael@0: NS_IMETHODIMP michael@0: nsViewSourceHandler::GetScheme(nsACString &result) michael@0: { michael@0: result.AssignLiteral(VIEW_SOURCE); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsViewSourceHandler::GetDefaultPort(int32_t *result) michael@0: { michael@0: *result = -1; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsViewSourceHandler::GetProtocolFlags(uint32_t *result) michael@0: { michael@0: *result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_ANYONE | michael@0: URI_NON_PERSISTABLE; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsViewSourceHandler::NewURI(const nsACString &aSpec, michael@0: const char *aCharset, michael@0: nsIURI *aBaseURI, michael@0: nsIURI **aResult) michael@0: { michael@0: *aResult = nullptr; michael@0: michael@0: // Extract inner URL and normalize to ASCII. This is done to properly michael@0: // support IDN in cases like "view-source:http://www.szalagavató.hu/" michael@0: michael@0: int32_t colon = aSpec.FindChar(':'); michael@0: if (colon == kNotFound) michael@0: return NS_ERROR_MALFORMED_URI; michael@0: michael@0: nsCOMPtr innerURI; michael@0: nsresult rv = NS_NewURI(getter_AddRefs(innerURI), michael@0: Substring(aSpec, colon + 1), aCharset, aBaseURI); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: nsAutoCString asciiSpec; michael@0: rv = innerURI->GetAsciiSpec(asciiSpec); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: // put back our scheme and construct a simple-uri wrapper michael@0: michael@0: asciiSpec.Insert(VIEW_SOURCE ":", 0); michael@0: michael@0: // We can't swap() from an nsRefPtr to an nsIURI**, michael@0: // sadly. michael@0: nsSimpleNestedURI* ourURI = new nsSimpleNestedURI(innerURI); michael@0: nsCOMPtr uri = ourURI; michael@0: if (!uri) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: michael@0: rv = ourURI->SetSpec(asciiSpec); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: // Make the URI immutable so it's impossible to get it out of sync michael@0: // with its inner URI. michael@0: ourURI->SetMutable(false); michael@0: michael@0: uri.swap(*aResult); michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsViewSourceHandler::NewChannel(nsIURI* uri, nsIChannel* *result) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(uri); michael@0: nsViewSourceChannel *channel = new nsViewSourceChannel(); michael@0: if (!channel) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: NS_ADDREF(channel); michael@0: michael@0: nsresult rv = channel->Init(uri); michael@0: if (NS_FAILED(rv)) { michael@0: NS_RELEASE(channel); michael@0: return rv; michael@0: } michael@0: michael@0: *result = static_cast(channel); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsViewSourceHandler::NewSrcdocChannel(nsIURI* uri, const nsAString &srcdoc, michael@0: nsIURI* baseURI, nsIChannel* *result) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(uri); michael@0: nsViewSourceChannel *channel = new nsViewSourceChannel(); michael@0: if (!channel) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: NS_ADDREF(channel); michael@0: michael@0: nsresult rv = channel->InitSrcdoc(uri, srcdoc, baseURI); michael@0: if (NS_FAILED(rv)) { michael@0: NS_RELEASE(channel); michael@0: return rv; michael@0: } michael@0: michael@0: *result = static_cast(channel); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsViewSourceHandler::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: nsViewSourceHandler::nsViewSourceHandler() michael@0: { michael@0: gInstance = this; michael@0: } michael@0: michael@0: nsViewSourceHandler::~nsViewSourceHandler() michael@0: { michael@0: gInstance = nullptr; michael@0: } michael@0: michael@0: nsViewSourceHandler* nsViewSourceHandler::gInstance = nullptr; michael@0: michael@0: nsViewSourceHandler* michael@0: nsViewSourceHandler::GetInstance() michael@0: { michael@0: return gInstance; michael@0: }