LCOV - code coverage report
Current view: top level - uriloader/exthandler - nsExternalProtocolHandler.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 15 225 6.7 %
Date: 2017-07-14 16:53:18 Functions: 5 67 7.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  * vim:set ts=2 sts=2 sw=2 et cin:
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       7             : 
       8             : #include "nsIURI.h"
       9             : #include "nsIURL.h"
      10             : #include "nsExternalProtocolHandler.h"
      11             : #include "nsXPIDLString.h"
      12             : #include "nsReadableUtils.h"
      13             : #include "nsCOMPtr.h"
      14             : #include "nsContentUtils.h"
      15             : #include "nsIServiceManager.h"
      16             : #include "nsServiceManagerUtils.h"
      17             : #include "nsIInterfaceRequestor.h"
      18             : #include "nsIInterfaceRequestorUtils.h"
      19             : #include "nsIStringBundle.h"
      20             : #include "nsIPrefService.h"
      21             : #include "nsIPrompt.h"
      22             : #include "nsNetUtil.h"
      23             : #include "nsContentSecurityManager.h"
      24             : #include "nsExternalHelperAppService.h"
      25             : 
      26             : // used to dispatch urls to default protocol handlers
      27             : #include "nsCExternalHandlerService.h"
      28             : #include "nsIExternalProtocolService.h"
      29             : #include "nsIChildChannel.h"
      30             : #include "nsIParentChannel.h"
      31             : 
      32             : class nsILoadInfo;
      33             : 
      34             : ////////////////////////////////////////////////////////////////////////
      35             : // a stub channel implemenation which will map calls to AsyncRead and OpenInputStream
      36             : // to calls in the OS for loading the url.
      37             : ////////////////////////////////////////////////////////////////////////
      38             : 
      39             : class nsExtProtocolChannel : public nsIChannel,
      40             :                              public nsIChildChannel,
      41             :                              public nsIParentChannel
      42             : {
      43             : public:
      44             :     NS_DECL_THREADSAFE_ISUPPORTS
      45             :     NS_DECL_NSICHANNEL
      46             :     NS_DECL_NSIREQUESTOBSERVER
      47             :     NS_DECL_NSISTREAMLISTENER
      48             :     NS_DECL_NSIREQUEST
      49             :     NS_DECL_NSICHILDCHANNEL
      50             :     NS_DECL_NSIPARENTCHANNEL
      51             : 
      52             :     nsExtProtocolChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo);
      53             : 
      54             : private:
      55             :     virtual ~nsExtProtocolChannel();
      56             : 
      57             :     nsresult OpenURL();
      58             :     void Finish(nsresult aResult);
      59             :     
      60             :     nsCOMPtr<nsIURI> mUrl;
      61             :     nsCOMPtr<nsIURI> mOriginalURI;
      62             :     nsresult mStatus;
      63             :     nsLoadFlags mLoadFlags;
      64             :     bool mWasOpened;
      65             :     // Set true (as a result of ConnectParent invoked from child process)
      66             :     // when this channel is on the parent process and is being used as
      67             :     // a redirect target channel.  It turns AsyncOpen into a no-op since
      68             :     // we do it on the child.
      69             :     bool mConnectedParent;
      70             :     
      71             :     nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
      72             :     nsCOMPtr<nsILoadGroup> mLoadGroup;
      73             :     nsCOMPtr<nsILoadInfo> mLoadInfo;
      74             : };
      75             : 
      76           0 : NS_IMPL_ADDREF(nsExtProtocolChannel)
      77           0 : NS_IMPL_RELEASE(nsExtProtocolChannel)
      78             : 
      79           0 : NS_INTERFACE_MAP_BEGIN(nsExtProtocolChannel)
      80           0 :    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIChannel)
      81           0 :    NS_INTERFACE_MAP_ENTRY(nsIChannel)
      82           0 :    NS_INTERFACE_MAP_ENTRY(nsIRequest)
      83           0 :    NS_INTERFACE_MAP_ENTRY(nsIChildChannel)
      84           0 :    NS_INTERFACE_MAP_ENTRY(nsIParentChannel)
      85           0 :    NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
      86           0 :    NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
      87           0 : NS_INTERFACE_MAP_END_THREADSAFE
      88             : 
      89           0 : nsExtProtocolChannel::nsExtProtocolChannel(nsIURI* aURI,
      90           0 :                                            nsILoadInfo* aLoadInfo)
      91             :   : mUrl(aURI)
      92             :   , mOriginalURI(aURI)
      93             :   , mStatus(NS_OK)
      94             :   , mLoadFlags(nsIRequest::LOAD_NORMAL)
      95             :   , mWasOpened(false)
      96             :   , mConnectedParent(false)
      97           0 :   , mLoadInfo(aLoadInfo)
      98             : {
      99           0 : }
     100             : 
     101           0 : nsExtProtocolChannel::~nsExtProtocolChannel()
     102           0 : {}
     103             : 
     104           0 : NS_IMETHODIMP nsExtProtocolChannel::GetLoadGroup(nsILoadGroup * *aLoadGroup)
     105             : {
     106           0 :   NS_IF_ADDREF(*aLoadGroup = mLoadGroup);
     107           0 :   return NS_OK;
     108             : }
     109             : 
     110           0 : NS_IMETHODIMP nsExtProtocolChannel::SetLoadGroup(nsILoadGroup * aLoadGroup)
     111             : {
     112           0 :   mLoadGroup = aLoadGroup;
     113           0 :   return NS_OK;
     114             : }
     115             : 
     116           0 : NS_IMETHODIMP nsExtProtocolChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aCallbacks)
     117             : {
     118           0 :   NS_IF_ADDREF(*aCallbacks = mCallbacks);
     119           0 :   return NS_OK;
     120             : }
     121             : 
     122           0 : NS_IMETHODIMP nsExtProtocolChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks)
     123             : {
     124           0 :   mCallbacks = aCallbacks;
     125           0 :   return NS_OK;
     126             : }
     127             : 
     128             : NS_IMETHODIMP 
     129           0 : nsExtProtocolChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
     130             : {
     131           0 :   *aSecurityInfo = nullptr;
     132           0 :   return NS_OK;
     133             : }
     134             : 
     135           0 : NS_IMETHODIMP nsExtProtocolChannel::GetOriginalURI(nsIURI* *aURI)
     136             : {
     137           0 :   NS_ADDREF(*aURI = mOriginalURI);
     138           0 :   return NS_OK; 
     139             : }
     140             :  
     141           0 : NS_IMETHODIMP nsExtProtocolChannel::SetOriginalURI(nsIURI* aURI)
     142             : {
     143           0 :   NS_ENSURE_ARG_POINTER(aURI);
     144           0 :   mOriginalURI = aURI;
     145           0 :   return NS_OK;
     146             : }
     147             :  
     148           0 : NS_IMETHODIMP nsExtProtocolChannel::GetURI(nsIURI* *aURI)
     149             : {
     150           0 :   *aURI = mUrl;
     151           0 :   NS_IF_ADDREF(*aURI);
     152           0 :   return NS_OK; 
     153             : }
     154             :  
     155           0 : nsresult nsExtProtocolChannel::OpenURL()
     156             : {
     157           0 :   nsresult rv = NS_ERROR_FAILURE;
     158           0 :   nsCOMPtr<nsIExternalProtocolService> extProtService (do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
     159             : 
     160           0 :   if (extProtService)
     161             :   {
     162             : #ifdef DEBUG
     163           0 :     nsAutoCString urlScheme;
     164           0 :     mUrl->GetScheme(urlScheme);
     165           0 :     bool haveHandler = false;
     166           0 :     extProtService->ExternalProtocolHandlerExists(urlScheme.get(), &haveHandler);
     167           0 :     NS_ASSERTION(haveHandler, "Why do we have a channel for this url if we don't support the protocol?");
     168             : #endif
     169             : 
     170           0 :     nsCOMPtr<nsIInterfaceRequestor> aggCallbacks;
     171           0 :     rv = NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
     172           0 :                                                 getter_AddRefs(aggCallbacks));
     173           0 :     if (NS_FAILED(rv)) {
     174           0 :       goto finish;
     175             :     }
     176             :                                                 
     177           0 :     rv = extProtService->LoadURI(mUrl, aggCallbacks);
     178           0 :     if (NS_SUCCEEDED(rv)) {
     179             :         // despite success, we need to abort this channel, at the very least 
     180             :         // to make it clear to the caller that no on{Start,Stop}Request
     181             :         // should be expected.
     182           0 :         rv = NS_ERROR_NO_CONTENT;
     183             :     }
     184             :   }
     185             : 
     186             : finish:
     187           0 :   mCallbacks = nullptr;
     188           0 :   return rv;
     189             : }
     190             : 
     191           0 : NS_IMETHODIMP nsExtProtocolChannel::Open(nsIInputStream **_retval)
     192             : {
     193           0 :   return OpenURL();
     194             : }
     195             : 
     196           0 : NS_IMETHODIMP nsExtProtocolChannel::Open2(nsIInputStream** aStream)
     197             : {
     198           0 :   nsCOMPtr<nsIStreamListener> listener;
     199           0 :   nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
     200           0 :   NS_ENSURE_SUCCESS(rv, rv);
     201           0 :   return Open(aStream);
     202             : }
     203             : 
     204           0 : NS_IMETHODIMP nsExtProtocolChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
     205             : {
     206           0 :   if (mConnectedParent) {
     207           0 :     return NS_OK;
     208             :   }
     209             : 
     210           0 :   MOZ_ASSERT(!mLoadInfo ||
     211             :              mLoadInfo->GetSecurityMode() == 0 ||
     212             :              mLoadInfo->GetInitialSecurityCheckDone() ||
     213             :              (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL &&
     214             :               nsContentUtils::IsSystemPrincipal(mLoadInfo->LoadingPrincipal())),
     215             :              "security flags in loadInfo but asyncOpen2() not called");
     216             : 
     217           0 :   NS_ENSURE_ARG_POINTER(listener);
     218           0 :   NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
     219             : 
     220           0 :   mWasOpened = true;
     221             : 
     222           0 :   return OpenURL();
     223             : }
     224             : 
     225           0 : NS_IMETHODIMP nsExtProtocolChannel::AsyncOpen2(nsIStreamListener *aListener)
     226             : {
     227           0 :   nsCOMPtr<nsIStreamListener> listener = aListener;
     228           0 :   nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
     229           0 :   if (NS_FAILED(rv)) {
     230           0 :     mCallbacks = nullptr;
     231           0 :     return rv;
     232             :   }
     233           0 :   return AsyncOpen(listener, nullptr);
     234             : }
     235             : 
     236           0 : NS_IMETHODIMP nsExtProtocolChannel::GetLoadFlags(nsLoadFlags *aLoadFlags)
     237             : {
     238           0 :   *aLoadFlags = mLoadFlags;
     239           0 :   return NS_OK;
     240             : }
     241             : 
     242           0 : NS_IMETHODIMP nsExtProtocolChannel::SetLoadFlags(nsLoadFlags aLoadFlags)
     243             : {
     244           0 :   mLoadFlags = aLoadFlags;
     245           0 :   return NS_OK;
     246             : }
     247             : 
     248           0 : NS_IMETHODIMP nsExtProtocolChannel::GetIsDocument(bool *aIsDocument)
     249             : {
     250           0 :   return NS_GetIsDocumentChannel(this, aIsDocument);
     251             : }
     252             : 
     253           0 : NS_IMETHODIMP nsExtProtocolChannel::GetContentType(nsACString &aContentType)
     254             : {
     255           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     256             : }
     257             : 
     258           0 : NS_IMETHODIMP nsExtProtocolChannel::SetContentType(const nsACString &aContentType)
     259             : {
     260           0 :   return NS_ERROR_FAILURE;
     261             : }
     262             : 
     263           0 : NS_IMETHODIMP nsExtProtocolChannel::GetContentCharset(nsACString &aContentCharset)
     264             : {
     265           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     266             : }
     267             : 
     268           0 : NS_IMETHODIMP nsExtProtocolChannel::SetContentCharset(const nsACString &aContentCharset)
     269             : {
     270           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     271             : }
     272             : 
     273           0 : NS_IMETHODIMP nsExtProtocolChannel::GetContentDisposition(uint32_t *aContentDisposition)
     274             : {
     275           0 :   return NS_ERROR_NOT_AVAILABLE;
     276             : }
     277             : 
     278           0 : NS_IMETHODIMP nsExtProtocolChannel::SetContentDisposition(uint32_t aContentDisposition)
     279             : {
     280           0 :   return NS_ERROR_NOT_AVAILABLE;
     281             : }
     282             : 
     283           0 : NS_IMETHODIMP nsExtProtocolChannel::GetContentDispositionFilename(nsAString &aContentDispositionFilename)
     284             : {
     285           0 :   return NS_ERROR_NOT_AVAILABLE;
     286             : }
     287             : 
     288           0 : NS_IMETHODIMP nsExtProtocolChannel::SetContentDispositionFilename(const nsAString &aContentDispositionFilename)
     289             : {
     290           0 :   return NS_ERROR_NOT_AVAILABLE;
     291             : }
     292             : 
     293           0 : NS_IMETHODIMP nsExtProtocolChannel::GetContentDispositionHeader(nsACString &aContentDispositionHeader)
     294             : {
     295           0 :   return NS_ERROR_NOT_AVAILABLE;
     296             : }
     297             : 
     298           0 : NS_IMETHODIMP nsExtProtocolChannel::GetContentLength(int64_t * aContentLength)
     299             : {
     300           0 :   *aContentLength = -1;
     301           0 :   return NS_OK;
     302             : }
     303             : 
     304             : NS_IMETHODIMP
     305           0 : nsExtProtocolChannel::SetContentLength(int64_t aContentLength)
     306             : {
     307           0 :   NS_NOTREACHED("SetContentLength");
     308           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     309             : }
     310             : 
     311           0 : NS_IMETHODIMP nsExtProtocolChannel::GetOwner(nsISupports * *aPrincipal)
     312             : {
     313           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     314             : }
     315             : 
     316           0 : NS_IMETHODIMP nsExtProtocolChannel::SetOwner(nsISupports * aPrincipal)
     317             : {
     318           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     319             : }
     320             : 
     321           0 : NS_IMETHODIMP nsExtProtocolChannel::GetLoadInfo(nsILoadInfo **aLoadInfo)
     322             : {
     323           0 :   NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
     324           0 :   return NS_OK;
     325             : }
     326             : 
     327           0 : NS_IMETHODIMP nsExtProtocolChannel::SetLoadInfo(nsILoadInfo *aLoadInfo)
     328             : {
     329           0 :   mLoadInfo = aLoadInfo;
     330           0 :   return NS_OK;
     331             : }
     332             : 
     333             : ////////////////////////////////////////////////////////////////////////////////
     334             : // From nsIRequest
     335             : ////////////////////////////////////////////////////////////////////////////////
     336             : 
     337           0 : NS_IMETHODIMP nsExtProtocolChannel::GetName(nsACString &result)
     338             : {
     339           0 :   return mUrl->GetSpec(result);
     340             : }
     341             : 
     342           0 : NS_IMETHODIMP nsExtProtocolChannel::IsPending(bool *result)
     343             : {
     344           0 :   *result = false;
     345           0 :   return NS_OK; 
     346             : }
     347             : 
     348           0 : NS_IMETHODIMP nsExtProtocolChannel::GetStatus(nsresult *status)
     349             : {
     350           0 :   *status = mStatus;
     351           0 :   return NS_OK;
     352             : }
     353             : 
     354           0 : NS_IMETHODIMP nsExtProtocolChannel::Cancel(nsresult status)
     355             : {
     356           0 :   mStatus = status;
     357           0 :   return NS_OK;
     358             : }
     359             : 
     360           0 : NS_IMETHODIMP nsExtProtocolChannel::Suspend()
     361             : {
     362           0 :   NS_NOTREACHED("Suspend");
     363           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     364             : }
     365             : 
     366           0 : NS_IMETHODIMP nsExtProtocolChannel::Resume()
     367             : {
     368           0 :   NS_NOTREACHED("Resume");
     369           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     370             : }
     371             : 
     372             : ///////////////////////////////////////////////////////////////////////
     373             : // From nsIChildChannel
     374             : //////////////////////////////////////////////////////////////////////
     375             : 
     376           0 : NS_IMETHODIMP nsExtProtocolChannel::ConnectParent(uint32_t registrarId)
     377             : {
     378           0 :   mozilla::dom::ContentChild::GetSingleton()->
     379           0 :     SendExtProtocolChannelConnectParent(registrarId);
     380           0 :   return NS_OK;
     381             : }
     382             : 
     383           0 : NS_IMETHODIMP nsExtProtocolChannel::CompleteRedirectSetup(nsIStreamListener *listener,
     384             :                                                           nsISupports *context)
     385             : {
     386             :   // For redirects to external protocols we AsyncOpen on the child
     387             :   // (not the parent) because child channel has the right docshell
     388             :   // (which is needed for the select dialog).
     389           0 :   return AsyncOpen(listener, context);
     390             : }
     391             : 
     392             : ///////////////////////////////////////////////////////////////////////
     393             : // From nsIParentChannel (derives from nsIStreamListener)
     394             : //////////////////////////////////////////////////////////////////////
     395             : 
     396           0 : NS_IMETHODIMP nsExtProtocolChannel::SetParentListener(HttpChannelParentListener* aListener)
     397             : {
     398             :   // This is called as part of the connect parent operation from
     399             :   // ContentParent::RecvExtProtocolChannelConnectParent.  Setting
     400             :   // this flag tells this channel to not proceed and makes AsyncOpen
     401             :   // just no-op.  Actual operation will happen from the child process
     402             :   // via CompleteRedirectSetup call on the child channel.
     403           0 :   mConnectedParent = true;
     404           0 :   return NS_OK;
     405             : }
     406             : 
     407           0 : NS_IMETHODIMP nsExtProtocolChannel::NotifyTrackingProtectionDisabled()
     408             : {
     409             :   // nothing to do
     410           0 :   return NS_OK;
     411             : }
     412             : 
     413           0 : NS_IMETHODIMP nsExtProtocolChannel::SetClassifierMatchedInfo(const nsACString& aList,
     414             :                                                              const nsACString& aProvider,
     415             :                                                              const nsACString& aPrefix)
     416             : {
     417             :   // nothing to do
     418           0 :   return NS_OK;
     419             : }
     420             : 
     421           0 : NS_IMETHODIMP nsExtProtocolChannel::NotifyTrackingResource()
     422             : {
     423             :   // nothing to do
     424           0 :   return NS_OK;
     425             : }
     426             : 
     427           0 : NS_IMETHODIMP nsExtProtocolChannel::Delete()
     428             : {
     429             :   // nothing to do
     430           0 :   return NS_OK;
     431             : }
     432             : 
     433           0 : NS_IMETHODIMP nsExtProtocolChannel::OnStartRequest(nsIRequest *aRequest,
     434             :                                                    nsISupports *aContext)
     435             : {
     436             :   // no data is expected
     437           0 :   MOZ_CRASH("No data expected from external protocol channel");
     438             :   return NS_ERROR_UNEXPECTED;
     439             : }
     440             : 
     441           0 : NS_IMETHODIMP nsExtProtocolChannel::OnStopRequest(nsIRequest *aRequest,
     442             :                                                   nsISupports *aContext,
     443             :                                                   nsresult aStatusCode)
     444             : {
     445             :   // no data is expected
     446           0 :   MOZ_CRASH("No data expected from external protocol channel");
     447             :   return NS_ERROR_UNEXPECTED;
     448             : }
     449             : 
     450           0 : NS_IMETHODIMP nsExtProtocolChannel::OnDataAvailable(nsIRequest *aRequest,
     451             :                                                     nsISupports *aContext,
     452             :                                                     nsIInputStream *aInputStream,
     453             :                                                     uint64_t aOffset,
     454             :                                                     uint32_t aCount)
     455             : {
     456             :   // no data is expected
     457           0 :   MOZ_CRASH("No data expected from external protocol channel");
     458             :   return NS_ERROR_UNEXPECTED;
     459             : }
     460             : 
     461             : ///////////////////////////////////////////////////////////////////////
     462             : // the default protocol handler implementation
     463             : //////////////////////////////////////////////////////////////////////
     464             : 
     465           2 : nsExternalProtocolHandler::nsExternalProtocolHandler()
     466             : {
     467           2 :   m_schemeName = "default";
     468           2 : }
     469             : 
     470             : 
     471           0 : nsExternalProtocolHandler::~nsExternalProtocolHandler()
     472           0 : {}
     473             : 
     474          23 : NS_IMPL_ADDREF(nsExternalProtocolHandler)
     475          21 : NS_IMPL_RELEASE(nsExternalProtocolHandler)
     476             : 
     477          19 : NS_INTERFACE_MAP_BEGIN(nsExternalProtocolHandler)
     478          19 :    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIProtocolHandler)
     479          17 :    NS_INTERFACE_MAP_ENTRY(nsIProtocolHandler)
     480           0 :    NS_INTERFACE_MAP_ENTRY(nsIExternalProtocolHandler)
     481           0 :    NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
     482           0 : NS_INTERFACE_MAP_END_THREADSAFE
     483             : 
     484           0 : NS_IMETHODIMP nsExternalProtocolHandler::GetScheme(nsACString &aScheme)
     485             : {
     486           0 :   aScheme = m_schemeName;
     487           0 :   return NS_OK;
     488             : }
     489             : 
     490           0 : NS_IMETHODIMP nsExternalProtocolHandler::GetDefaultPort(int32_t *aDefaultPort)
     491             : {
     492           0 :   *aDefaultPort = 0;
     493           0 :     return NS_OK;
     494             : }
     495             : 
     496             : NS_IMETHODIMP 
     497           0 : nsExternalProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval)
     498             : {
     499             :     // don't override anything.  
     500           0 :     *_retval = false;
     501           0 :     return NS_OK;
     502             : }
     503             : // returns TRUE if the OS can handle this protocol scheme and false otherwise.
     504           0 : bool nsExternalProtocolHandler::HaveExternalProtocolHandler(nsIURI * aURI)
     505             : {
     506           0 :   MOZ_ASSERT(aURI);
     507           0 :   nsAutoCString scheme;
     508           0 :   aURI->GetScheme(scheme);
     509             : 
     510           0 :   nsCOMPtr<nsIExternalProtocolService> extProtSvc(do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
     511           0 :   if (!extProtSvc) {
     512           0 :     return false;
     513             :   }
     514             : 
     515           0 :   bool haveHandler = false;
     516           0 :   extProtSvc->ExternalProtocolHandlerExists(scheme.get(), &haveHandler);
     517           0 :   return haveHandler;
     518             : }
     519             : 
     520           0 : NS_IMETHODIMP nsExternalProtocolHandler::GetProtocolFlags(uint32_t *aUritype)
     521             : {
     522             :     // Make it norelative since it is a simple uri
     523           0 :     *aUritype = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_ANYONE |
     524             :         URI_NON_PERSISTABLE | URI_DOES_NOT_RETURN_DATA;
     525           0 :     return NS_OK;
     526             : }
     527             : 
     528           1 : NS_IMETHODIMP nsExternalProtocolHandler::NewURI(const nsACString &aSpec,
     529             :                                                 const char *aCharset, // ignore charset info
     530             :                                                 nsIURI *aBaseURI,
     531             :                                                 nsIURI **_retval)
     532             : {
     533             :   nsresult rv;
     534           2 :   nsCOMPtr<nsIURI> uri = do_CreateInstance(NS_SIMPLEURI_CONTRACTID, &rv);
     535           1 :   NS_ENSURE_SUCCESS(rv, rv);
     536             :   
     537           1 :   rv = uri->SetSpec(aSpec);
     538           1 :   NS_ENSURE_SUCCESS(rv, rv);
     539             : 
     540           1 :   NS_ADDREF(*_retval = uri);
     541           1 :   return NS_OK;
     542             : }
     543             : 
     544             : NS_IMETHODIMP
     545           0 : nsExternalProtocolHandler::NewChannel2(nsIURI* aURI,
     546             :                                        nsILoadInfo* aLoadInfo,
     547             :                                        nsIChannel** aRetval)
     548             : {
     549           0 :   NS_ENSURE_TRUE(aURI, NS_ERROR_UNKNOWN_PROTOCOL);
     550           0 :   NS_ENSURE_TRUE(aRetval, NS_ERROR_UNKNOWN_PROTOCOL);
     551             : 
     552             :   // Only try to return a channel if we have a protocol handler for the url.
     553             :   // nsOSHelperAppService::LoadUriInternal relies on this to check trustedness
     554             :   // for some platforms at least.  (win uses ::ShellExecute and unix uses
     555             :   // gnome_url_show.)
     556           0 :   if (!HaveExternalProtocolHandler(aURI)) {
     557           0 :     return NS_ERROR_UNKNOWN_PROTOCOL;
     558             :   }
     559             : 
     560           0 :   nsCOMPtr<nsIChannel> channel = new nsExtProtocolChannel(aURI, aLoadInfo);
     561           0 :   channel.forget(aRetval);
     562           0 :   return NS_OK;
     563             : }
     564             : 
     565           0 : NS_IMETHODIMP nsExternalProtocolHandler::NewChannel(nsIURI *aURI, nsIChannel **_retval)
     566             : {
     567           0 :   return NewChannel2(aURI, nullptr, _retval);
     568             : }
     569             : 
     570             : ///////////////////////////////////////////////////////////////////////
     571             : // External protocol handler interface implementation
     572             : //////////////////////////////////////////////////////////////////////
     573           0 : NS_IMETHODIMP nsExternalProtocolHandler::ExternalAppExistsForScheme(const nsACString& aScheme, bool *_retval)
     574             : {
     575           0 :   nsCOMPtr<nsIExternalProtocolService> extProtSvc(do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
     576           0 :   if (extProtSvc)
     577           0 :     return extProtSvc->ExternalProtocolHandlerExists(
     578           0 :       PromiseFlatCString(aScheme).get(), _retval);
     579             : 
     580             :   // In case we don't have external protocol service.
     581           0 :   *_retval = false;
     582           0 :   return NS_OK;
     583             : }

Generated by: LCOV version 1.13