LCOV - code coverage report
Current view: top level - dom/url - URLMainThread.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 23 214 10.7 %
Date: 2017-07-14 16:53:18 Functions: 4 39 10.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "URLMainThread.h"
       8             : 
       9             : #include "mozilla/dom/BindingUtils.h"
      10             : #include "mozilla/dom/Blob.h"
      11             : #include "nsContentUtils.h"
      12             : #include "nsHostObjectProtocolHandler.h"
      13             : #include "nsIURL.h"
      14             : #include "nsNetUtil.h"
      15             : 
      16             : namespace mozilla {
      17             : namespace dom {
      18             : 
      19             : namespace {
      20             : 
      21             : template<typename T>
      22             : void
      23           0 : CreateObjectURLInternal(const GlobalObject& aGlobal, T aObject,
      24             :                         nsAString& aResult, ErrorResult& aRv)
      25             : {
      26           0 :   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
      27           0 :   if (NS_WARN_IF(!global)) {
      28           0 :     aRv.Throw(NS_ERROR_FAILURE);
      29           0 :     return;
      30             :   }
      31             : 
      32             :   nsCOMPtr<nsIPrincipal> principal =
      33           0 :     nsContentUtils::ObjectPrincipal(aGlobal.Get());
      34             : 
      35           0 :   nsAutoCString url;
      36           0 :   aRv = nsHostObjectProtocolHandler::AddDataEntry(aObject, principal, url);
      37           0 :   if (NS_WARN_IF(aRv.Failed())) {
      38           0 :     return;
      39             :   }
      40             : 
      41           0 :   global->RegisterHostObjectURI(url);
      42           0 :   CopyASCIItoUTF16(url, aResult);
      43             : }
      44             : 
      45             : } // anonymous namespace
      46             : 
      47             : /* static */ already_AddRefed<URLMainThread>
      48           3 : URLMainThread::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
      49             :                            const Optional<nsAString>& aBase, ErrorResult& aRv)
      50             : {
      51           3 :   if (aBase.WasPassed()) {
      52           0 :     return Constructor(aGlobal.GetAsSupports(), aURL, aBase.Value(), aRv);
      53             :   }
      54             : 
      55           3 :   return Constructor(aGlobal.GetAsSupports(), aURL, nullptr, aRv);
      56             : }
      57             : 
      58             : /* static */ already_AddRefed<URLMainThread>
      59           0 : URLMainThread::Constructor(nsISupports* aParent, const nsAString& aURL,
      60             :                            const nsAString& aBase, ErrorResult& aRv)
      61             : {
      62           0 :   MOZ_ASSERT(NS_IsMainThread());
      63             : 
      64           0 :   nsCOMPtr<nsIURI> baseUri;
      65           0 :   nsresult rv = NS_NewURI(getter_AddRefs(baseUri), aBase, nullptr, nullptr,
      66           0 :                           nsContentUtils::GetIOService());
      67           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
      68           0 :     aRv.ThrowTypeError<MSG_INVALID_URL>(aBase);
      69           0 :     return nullptr;
      70             :   }
      71             : 
      72           0 :   return Constructor(aParent, aURL, baseUri, aRv);
      73             : }
      74             : 
      75             : /* static */ already_AddRefed<URLMainThread>
      76           3 : URLMainThread::Constructor(nsISupports* aParent, const nsAString& aURL,
      77             :                            nsIURI* aBase, ErrorResult& aRv)
      78             : {
      79           3 :   MOZ_ASSERT(NS_IsMainThread());
      80             : 
      81           6 :   nsCOMPtr<nsIURI> uri;
      82           6 :   nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, nullptr, aBase,
      83           3 :                           nsContentUtils::GetIOService());
      84           3 :   if (NS_FAILED(rv)) {
      85             :     // No need to warn in this case. It's common to use the URL constructor
      86             :     // to determine if a URL is valid and an exception will be propagated.
      87           0 :     aRv.ThrowTypeError<MSG_INVALID_URL>(aURL);
      88           0 :     return nullptr;
      89             :   }
      90             : 
      91           9 :   RefPtr<URLMainThread> url = new URLMainThread(aParent, uri.forget());
      92           3 :   return url.forget();
      93             : }
      94             : 
      95             : /* static */ void
      96           0 : URLMainThread::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
      97             :                                nsAString& aResult, ErrorResult& aRv)
      98             : {
      99           0 :   MOZ_ASSERT(NS_IsMainThread());
     100           0 :   CreateObjectURLInternal(aGlobal, aBlob.Impl(), aResult, aRv);
     101           0 : }
     102             : 
     103             : /* static */ void
     104           0 : URLMainThread::CreateObjectURL(const GlobalObject& aGlobal,
     105             :                                DOMMediaStream& aStream,
     106             :                                nsAString& aResult, ErrorResult& aRv)
     107             : {
     108           0 :   MOZ_ASSERT(NS_IsMainThread());
     109           0 :   CreateObjectURLInternal(aGlobal, &aStream, aResult, aRv);
     110           0 : }
     111             : 
     112             : /* static */ void
     113           0 : URLMainThread::CreateObjectURL(const GlobalObject& aGlobal,
     114             :                                MediaSource& aSource,
     115             :                                nsAString& aResult, ErrorResult& aRv)
     116             : {
     117           0 :   MOZ_ASSERT(NS_IsMainThread());
     118             : 
     119             :   nsCOMPtr<nsIPrincipal> principal =
     120           0 :     nsContentUtils::ObjectPrincipal(aGlobal.Get());
     121             : 
     122           0 :   nsAutoCString url;
     123           0 :   aRv = nsHostObjectProtocolHandler::AddDataEntry(&aSource, principal, url);
     124           0 :   if (NS_WARN_IF(aRv.Failed())) {
     125           0 :     return;
     126             :   }
     127             : 
     128             :   nsCOMPtr<nsIRunnable> revocation =
     129           0 :     NS_NewRunnableFunction("dom::URLMainThread::CreateObjectURL", [url] {
     130           0 :       nsHostObjectProtocolHandler::RemoveDataEntry(url);
     131           0 :     });
     132             : 
     133           0 :   nsContentUtils::RunInStableState(revocation.forget());
     134             : 
     135           0 :   CopyASCIItoUTF16(url, aResult);
     136             : }
     137             : 
     138             : /* static */ void
     139           0 : URLMainThread::RevokeObjectURL(const GlobalObject& aGlobal,
     140             :                                const nsAString& aURL, ErrorResult& aRv)
     141             : {
     142           0 :   MOZ_ASSERT(NS_IsMainThread());
     143           0 :   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
     144           0 :   if (!global) {
     145           0 :     aRv.Throw(NS_ERROR_FAILURE);
     146           0 :     return;
     147             :   }
     148             : 
     149           0 :   nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
     150             : 
     151           0 :   NS_LossyConvertUTF16toASCII asciiurl(aURL);
     152             : 
     153             :   nsIPrincipal* urlPrincipal =
     154           0 :     nsHostObjectProtocolHandler::GetDataEntryPrincipal(asciiurl);
     155             : 
     156           0 :   if (urlPrincipal && principal->Subsumes(urlPrincipal)) {
     157           0 :     global->UnregisterHostObjectURI(asciiurl);
     158           0 :     nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl);
     159             :   }
     160             : }
     161             : 
     162           3 : URLMainThread::URLMainThread(nsISupports* aParent,
     163           3 :                              already_AddRefed<nsIURI> aURI)
     164             :   : URL(aParent)
     165           3 :   , mURI(aURI)
     166             : {
     167           3 :   MOZ_ASSERT(NS_IsMainThread());
     168           3 : }
     169             : 
     170           0 : URLMainThread::~URLMainThread()
     171             : {
     172           0 :   MOZ_ASSERT(NS_IsMainThread());
     173           0 : }
     174             : 
     175             : /* static */ bool
     176           0 : URLMainThread::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
     177             :                           ErrorResult& aRv)
     178             : {
     179           0 :   MOZ_ASSERT(NS_IsMainThread());
     180           0 :   NS_LossyConvertUTF16toASCII asciiurl(aURL);
     181           0 :   return nsHostObjectProtocolHandler::HasDataEntry(asciiurl);
     182             : }
     183             : 
     184             : void
     185           1 : URLMainThread::GetHref(nsAString& aHref, ErrorResult& aRv) const
     186             : {
     187           1 :   aHref.Truncate();
     188             : 
     189           2 :   nsAutoCString href;
     190           1 :   nsresult rv = mURI->GetSpec(href);
     191           1 :   if (NS_SUCCEEDED(rv)) {
     192           1 :     CopyUTF8toUTF16(href, aHref);
     193             :   }
     194           1 : }
     195             : 
     196             : void
     197           0 : URLMainThread::SetHref(const nsAString& aHref, ErrorResult& aRv)
     198             : {
     199           0 :   NS_ConvertUTF16toUTF8 href(aHref);
     200             : 
     201             :   nsresult rv;
     202           0 :   nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
     203           0 :   if (NS_FAILED(rv)) {
     204           0 :     aRv.Throw(rv);
     205           0 :     return;
     206             :   }
     207             : 
     208           0 :   nsCOMPtr<nsIURI> uri;
     209           0 :   rv = ioService->NewURI(href, nullptr, nullptr, getter_AddRefs(uri));
     210           0 :   if (NS_FAILED(rv)) {
     211           0 :     aRv.ThrowTypeError<MSG_INVALID_URL>(aHref);
     212           0 :     return;
     213             :   }
     214             : 
     215           0 :   mURI = uri;
     216           0 :   UpdateURLSearchParams();
     217             : }
     218             : 
     219             : void
     220           0 : URLMainThread::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const
     221             : {
     222           0 :   nsContentUtils::GetUTFOrigin(mURI, aOrigin);
     223           0 : }
     224             : 
     225             : void
     226           0 : URLMainThread::GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const
     227             : {
     228           0 :   nsAutoCString protocol;
     229           0 :   if (NS_SUCCEEDED(mURI->GetScheme(protocol))) {
     230           0 :     aProtocol.Truncate();
     231             :   }
     232             : 
     233           0 :   CopyASCIItoUTF16(protocol, aProtocol);
     234           0 :   aProtocol.Append(char16_t(':'));
     235           0 : }
     236             : 
     237             : void
     238           0 : URLMainThread::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv)
     239             : {
     240           0 :   nsAString::const_iterator start, end;
     241           0 :   aProtocol.BeginReading(start);
     242           0 :   aProtocol.EndReading(end);
     243           0 :   nsAString::const_iterator iter(start);
     244             : 
     245           0 :   FindCharInReadable(':', iter, end);
     246             : 
     247             :   // Changing the protocol of a URL, changes the "nature" of the URI
     248             :   // implementation. In order to do this properly, we have to serialize the
     249             :   // existing URL and reparse it in a new object.
     250           0 :   nsCOMPtr<nsIURI> clone;
     251           0 :   nsresult rv = mURI->Clone(getter_AddRefs(clone));
     252           0 :   if (NS_WARN_IF(NS_FAILED(rv)) || !clone) {
     253           0 :     return;
     254             :   }
     255             : 
     256           0 :   rv = clone->SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter)));
     257           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     258           0 :     return;
     259             :   }
     260             : 
     261           0 :   nsAutoCString href;
     262           0 :   rv = clone->GetSpec(href);
     263           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     264           0 :     return;
     265             :   }
     266             : 
     267           0 :   nsCOMPtr<nsIURI> uri;
     268           0 :   rv = NS_NewURI(getter_AddRefs(uri), href);
     269           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     270           0 :     return;
     271             :   }
     272             : 
     273           0 :   mURI = uri;
     274             : }
     275             : 
     276             : #define URL_GETTER( value, func ) \
     277             :   value.Truncate();               \
     278             :   nsAutoCString tmp;              \
     279             :   nsresult rv = mURI->func(tmp);  \
     280             :   if (NS_SUCCEEDED(rv)) {         \
     281             :     CopyUTF8toUTF16(tmp, value);  \
     282             :   }
     283             : 
     284             : void
     285           0 : URLMainThread::GetUsername(nsAString& aUsername, ErrorResult& aRv) const
     286             : {
     287           0 :   URL_GETTER(aUsername, GetUsername);
     288           0 : }
     289             : 
     290             : void
     291           0 : URLMainThread::SetUsername(const nsAString& aUsername, ErrorResult& aRv)
     292             : {
     293           0 :   mURI->SetUsername(NS_ConvertUTF16toUTF8(aUsername));
     294           0 : }
     295             : 
     296             : void
     297           0 : URLMainThread::GetPassword(nsAString& aPassword, ErrorResult& aRv) const
     298             : {
     299           0 :   URL_GETTER(aPassword, GetPassword);
     300           0 : }
     301             : 
     302             : void
     303           0 : URLMainThread::SetPassword(const nsAString& aPassword, ErrorResult& aRv)
     304             : {
     305           0 :   mURI->SetPassword(NS_ConvertUTF16toUTF8(aPassword));
     306           0 : }
     307             : 
     308             : void
     309           0 : URLMainThread::GetHost(nsAString& aHost, ErrorResult& aRv) const
     310             : {
     311           0 :   URL_GETTER(aHost, GetHostPort);
     312           0 : }
     313             : 
     314             : void
     315           0 : URLMainThread::SetHost(const nsAString& aHost, ErrorResult& aRv)
     316             : {
     317           0 :   mURI->SetHostPort(NS_ConvertUTF16toUTF8(aHost));
     318           0 : }
     319             : 
     320             : void
     321           0 : URLMainThread::UpdateURLSearchParams()
     322             : {
     323           0 :   if (!mSearchParams) {
     324           0 :     return;
     325             :   }
     326             : 
     327           0 :   nsAutoCString search;
     328           0 :   nsresult rv = mURI->GetQuery(search);
     329           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     330           0 :     search.Truncate();
     331             :   }
     332             : 
     333           0 :   mSearchParams->ParseInput(search);
     334             : }
     335             : 
     336             : void
     337           0 : URLMainThread::GetHostname(nsAString& aHostname, ErrorResult& aRv) const
     338             : {
     339           0 :   aHostname.Truncate();
     340           0 :   nsContentUtils::GetHostOrIPv6WithBrackets(mURI, aHostname);
     341           0 : }
     342             : 
     343             : void
     344           0 : URLMainThread::SetHostname(const nsAString& aHostname, ErrorResult& aRv)
     345             : {
     346             :   // nsStandardURL returns NS_ERROR_UNEXPECTED for an empty hostname
     347             :   // The return code is silently ignored
     348           0 :   mURI->SetHost(NS_ConvertUTF16toUTF8(aHostname));
     349           0 : }
     350             : 
     351             : void
     352           0 : URLMainThread::GetPort(nsAString& aPort, ErrorResult& aRv) const
     353             : {
     354           0 :   aPort.Truncate();
     355             : 
     356             :   int32_t port;
     357           0 :   nsresult rv = mURI->GetPort(&port);
     358           0 :   if (NS_SUCCEEDED(rv) && port != -1) {
     359           0 :     nsAutoString portStr;
     360           0 :     portStr.AppendInt(port, 10);
     361           0 :     aPort.Assign(portStr);
     362             :   }
     363           0 : }
     364             : 
     365             : void
     366           0 : URLMainThread::SetPort(const nsAString& aPort, ErrorResult& aRv)
     367             : {
     368             :   nsresult rv;
     369           0 :   nsAutoString portStr(aPort);
     370           0 :   int32_t port = -1;
     371             : 
     372             :   // nsIURI uses -1 as default value.
     373           0 :   if (!portStr.IsEmpty()) {
     374           0 :     port = portStr.ToInteger(&rv);
     375           0 :     if (NS_FAILED(rv)) {
     376           0 :       return;
     377             :     }
     378             :   }
     379             : 
     380           0 :   mURI->SetPort(port);
     381             : }
     382             : 
     383             : void
     384           0 : URLMainThread::GetPathname(nsAString& aPathname, ErrorResult& aRv) const
     385             : {
     386           0 :   aPathname.Truncate();
     387             : 
     388             :   // Do not throw!  Not having a valid URI or URL should result in an empty
     389             :   // string.
     390             : 
     391           0 :   nsAutoCString file;
     392           0 :   nsresult rv = mURI->GetFilePath(file);
     393           0 :   if (NS_SUCCEEDED(rv)) {
     394           0 :     CopyUTF8toUTF16(file, aPathname);
     395             :   }
     396           0 : }
     397             : 
     398             : void
     399           0 : URLMainThread::SetPathname(const nsAString& aPathname, ErrorResult& aRv)
     400             : {
     401             :   // Do not throw!
     402             : 
     403           0 :   mURI->SetFilePath(NS_ConvertUTF16toUTF8(aPathname));
     404           0 : }
     405             : 
     406             : void
     407           0 : URLMainThread::GetSearch(nsAString& aSearch, ErrorResult& aRv) const
     408             : {
     409           0 :   aSearch.Truncate();
     410             : 
     411             :   // Do not throw!  Not having a valid URI or URL should result in an empty
     412             :   // string.
     413             : 
     414           0 :   nsAutoCString search;
     415             :   nsresult rv;
     416             : 
     417           0 :   rv = mURI->GetQuery(search);
     418           0 :   if (NS_SUCCEEDED(rv) && !search.IsEmpty()) {
     419           0 :     CopyUTF8toUTF16(NS_LITERAL_CSTRING("?") + search, aSearch);
     420             :   }
     421           0 : }
     422             : 
     423             : void
     424           0 : URLMainThread::GetHash(nsAString& aHash, ErrorResult& aRv) const
     425             : {
     426           0 :   aHash.Truncate();
     427             : 
     428           0 :   nsAutoCString ref;
     429           0 :   nsresult rv = mURI->GetRef(ref);
     430           0 :   if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
     431           0 :     aHash.Assign(char16_t('#'));
     432           0 :     AppendUTF8toUTF16(ref, aHash);
     433             :   }
     434           0 : }
     435             : 
     436             : void
     437           0 : URLMainThread::SetHash(const nsAString& aHash, ErrorResult& aRv)
     438             : {
     439           0 :   mURI->SetRef(NS_ConvertUTF16toUTF8(aHash));
     440           0 : }
     441             : 
     442             : void
     443           0 : URLMainThread::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv)
     444             : {
     445             :   // Ignore failures to be compatible with NS4.
     446             : 
     447           0 :   mURI->SetQuery(NS_ConvertUTF16toUTF8(aSearch));
     448           0 : }
     449             : 
     450             : nsIURI*
     451           0 : URLMainThread::GetURI() const
     452             : {
     453           0 :   MOZ_ASSERT(NS_IsMainThread());
     454           0 :   return mURI;
     455             : }
     456             : 
     457             : } // namespace dom
     458             : } // namespace mozilla

Generated by: LCOV version 1.13