/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=4 sw=2 sts=2 et: */ /* 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 "nsViewSourceHandler.h" #include "nsViewSourceChannel.h" #include "nsNetUtil.h" #include "nsSimpleNestedURI.h" #define VIEW_SOURCE "view-source" #define DEFAULT_FLAGS \ (URI_NORELATIVE | URI_NOAUTH | URI_DANGEROUS_TO_LOAD | URI_NON_PERSISTABLE) namespace mozilla { namespace net { //////////////////////////////////////////////////////////////////////////////// NS_IMPL_ISUPPORTS(nsViewSourceHandler, nsIProtocolHandler, nsIProtocolHandlerWithDynamicFlags) //////////////////////////////////////////////////////////////////////////////// // nsIProtocolHandler methods: NS_IMETHODIMP nsViewSourceHandler::GetScheme(nsACString& result) { result.AssignLiteral(VIEW_SOURCE); return NS_OK; } NS_IMETHODIMP nsViewSourceHandler::GetFlagsForURI(nsIURI* aURI, uint32_t* result) { *result = DEFAULT_FLAGS; nsCOMPtr nestedURI(do_QueryInterface(aURI)); if (!nestedURI) { return NS_OK; } nsCOMPtr innerURI; nestedURI->GetInnerURI(getter_AddRefs(innerURI)); nsCOMPtr netUtil = do_GetNetUtil(); bool isLoadable = false; nsresult rv = netUtil->ProtocolHasFlags(innerURI, URI_LOADABLE_BY_ANYONE, &isLoadable); NS_ENSURE_SUCCESS(rv, rv); if (isLoadable) { *result |= URI_LOADABLE_BY_EXTENSIONS; } return NS_OK; } // static nsresult nsViewSourceHandler::CreateNewURI(const nsACString& aSpec, const char* aCharset, nsIURI* aBaseURI, nsIURI** aResult) { *aResult = nullptr; // Extract inner URL and normalize to ASCII. This is done to properly // support IDN in cases like "view-source:http://www.szalagavató.hu/" int32_t colon = aSpec.FindChar(':'); if (colon == kNotFound) return NS_ERROR_MALFORMED_URI; nsCOMPtr innerURI; nsresult rv = NS_NewURI(getter_AddRefs(innerURI), Substring(aSpec, colon + 1), aCharset, aBaseURI); if (NS_FAILED(rv)) return rv; nsAutoCString asciiSpec; rv = innerURI->GetAsciiSpec(asciiSpec); if (NS_FAILED(rv)) return rv; // put back our scheme and construct a simple-uri wrapper asciiSpec.Insert(VIEW_SOURCE ":", 0); nsCOMPtr uri; rv = NS_MutateURI(new nsSimpleNestedURI::Mutator()) .Apply(&nsINestedURIMutator::Init, innerURI) .SetSpec(asciiSpec) .Finalize(uri); if (NS_FAILED(rv)) { return rv; } uri.swap(*aResult); return rv; } NS_IMETHODIMP nsViewSourceHandler::NewChannel(nsIURI* uri, nsILoadInfo* aLoadInfo, nsIChannel** result) { NS_ENSURE_ARG_POINTER(uri); RefPtr channel = new nsViewSourceChannel(); nsresult rv = channel->Init(uri, aLoadInfo); if (NS_FAILED(rv)) { return rv; } *result = channel.forget().downcast().take(); return NS_OK; } nsresult nsViewSourceHandler::NewSrcdocChannel(nsIURI* aURI, nsIURI* aBaseURI, const nsAString& aSrcdoc, nsILoadInfo* aLoadInfo, nsIChannel** outChannel) { NS_ENSURE_ARG_POINTER(aURI); RefPtr channel = new nsViewSourceChannel(); nsresult rv = channel->InitSrcdoc(aURI, aBaseURI, aSrcdoc, aLoadInfo); if (NS_FAILED(rv)) { return rv; } *outChannel = static_cast(channel.forget().take()); return NS_OK; } NS_IMETHODIMP nsViewSourceHandler::AllowPort(int32_t port, const char* scheme, bool* _retval) { // don't override anything. *_retval = false; return NS_OK; } nsViewSourceHandler::nsViewSourceHandler() { gInstance = this; } nsViewSourceHandler::~nsViewSourceHandler() { gInstance = nullptr; } nsViewSourceHandler* nsViewSourceHandler::gInstance = nullptr; nsViewSourceHandler* nsViewSourceHandler::GetInstance() { return gInstance; } } // namespace net } // namespace mozilla