LCOV - code coverage report
Current view: directory - objdir/dist/include - nsNetUtil.h (source / functions) Found Hit Coverage
Test: app.info Lines: 753 502 66.7 %
Date: 2012-06-02 Functions: 91 64 70.3 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* vim:set ts=4 sw=4 sts=4 et cin: */
       3                 : /* ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is mozilla.org code.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  * Netscape Communications Corporation.
      20                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   Bradley Baetz <bbaetz@student.usyd.edu.au>
      25                 :  *   Malcolm Smith <malsmith@cs.rmit.edu.au>
      26                 :  *   Taras Glek <tglek@mozilla.com>
      27                 :  *
      28                 :  * Alternatively, the contents of this file may be used under the terms of
      29                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      30                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      31                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      32                 :  * of those above. If you wish to allow use of your version of this file only
      33                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      34                 :  * use your version of this file under the terms of the MPL, indicate your
      35                 :  * decision by deleting the provisions above and replace them with the notice
      36                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      37                 :  * the provisions above, a recipient may use your version of this file under
      38                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      39                 :  *
      40                 :  * ***** END LICENSE BLOCK ***** */
      41                 : 
      42                 : #ifndef nsNetUtil_h__
      43                 : #define nsNetUtil_h__
      44                 : 
      45                 : #include "nsNetError.h"
      46                 : #include "nsNetCID.h"
      47                 : #include "nsStringGlue.h"
      48                 : #include "nsMemory.h"
      49                 : #include "nsCOMPtr.h"
      50                 : #include "prio.h" // for read/write flags, permissions, etc.
      51                 : #include "nsHashKeys.h"
      52                 : 
      53                 : #include "plstr.h"
      54                 : #include "nsIURI.h"
      55                 : #include "nsIStandardURL.h"
      56                 : #include "nsIURLParser.h"
      57                 : #include "nsIUUIDGenerator.h"
      58                 : #include "nsIInputStream.h"
      59                 : #include "nsIOutputStream.h"
      60                 : #include "nsISafeOutputStream.h"
      61                 : #include "nsIStreamListener.h"
      62                 : #include "nsIRequestObserverProxy.h"
      63                 : #include "nsISimpleStreamListener.h"
      64                 : #include "nsILoadGroup.h"
      65                 : #include "nsIInterfaceRequestor.h"
      66                 : #include "nsIInterfaceRequestorUtils.h"
      67                 : #include "nsIIOService.h"
      68                 : #include "nsIServiceManager.h"
      69                 : #include "nsIChannel.h"
      70                 : #include "nsChannelProperties.h"
      71                 : #include "nsIInputStreamChannel.h"
      72                 : #include "nsITransport.h"
      73                 : #include "nsIStreamTransportService.h"
      74                 : #include "nsIHttpChannel.h"
      75                 : #include "nsIDownloader.h"
      76                 : #include "nsIStreamLoader.h"
      77                 : #include "nsIUnicharStreamLoader.h"
      78                 : #include "nsIPipe.h"
      79                 : #include "nsIProtocolHandler.h"
      80                 : #include "nsIFileProtocolHandler.h"
      81                 : #include "nsIStringStream.h"
      82                 : #include "nsILocalFile.h"
      83                 : #include "nsIFileStreams.h"
      84                 : #include "nsIFileURL.h"
      85                 : #include "nsIProtocolProxyService.h"
      86                 : #include "nsIProxyInfo.h"
      87                 : #include "nsIFileStreams.h"
      88                 : #include "nsIBufferedStreams.h"
      89                 : #include "nsIInputStreamPump.h"
      90                 : #include "nsIAsyncStreamCopier.h"
      91                 : #include "nsIPersistentProperties2.h"
      92                 : #include "nsISyncStreamListener.h"
      93                 : #include "nsInterfaceRequestorAgg.h"
      94                 : #include "nsINetUtil.h"
      95                 : #include "nsIURIWithPrincipal.h"
      96                 : #include "nsIAuthPrompt.h"
      97                 : #include "nsIAuthPrompt2.h"
      98                 : #include "nsIAuthPromptAdapterFactory.h"
      99                 : #include "nsComponentManagerUtils.h"
     100                 : #include "nsServiceManagerUtils.h"
     101                 : #include "nsINestedURI.h"
     102                 : #include "nsIMutable.h"
     103                 : #include "nsIPropertyBag2.h"
     104                 : #include "nsIWritablePropertyBag2.h"
     105                 : #include "nsIIDNService.h"
     106                 : #include "nsIChannelEventSink.h"
     107                 : #include "nsIChannelPolicy.h"
     108                 : #include "nsISocketProviderService.h"
     109                 : #include "nsISocketProvider.h"
     110                 : #include "nsIRedirectChannelRegistrar.h"
     111                 : #include "nsIMIMEHeaderParam.h"
     112                 : #include "mozilla/Services.h"
     113                 : 
     114                 : #ifdef MOZILLA_INTERNAL_API
     115                 : 
     116                 : inline already_AddRefed<nsIIOService>
     117          233673 : do_GetIOService(nsresult* error = 0)
     118                 : {
     119          233673 :     already_AddRefed<nsIIOService> ret = mozilla::services::GetIOService();
     120          233673 :     if (error)
     121          233645 :         *error = ret.get() ? NS_OK : NS_ERROR_FAILURE;
     122                 :     return ret;
     123                 : }
     124                 : 
     125                 : inline already_AddRefed<nsINetUtil>
     126          107308 : do_GetNetUtil(nsresult *error = 0) 
     127                 : {
     128          214616 :     nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
     129          107308 :     already_AddRefed<nsINetUtil> ret = nsnull;
     130          107308 :     if (io)
     131          107308 :         CallQueryInterface(io, &ret.mRawPtr);
     132                 : 
     133          107308 :     if (error)
     134          107307 :         *error = ret.get() ? NS_OK : NS_ERROR_FAILURE;
     135                 :     return ret;
     136                 : }
     137                 : #else
     138                 : // Helper, to simplify getting the I/O service.
     139                 : inline const nsGetServiceByContractIDWithError
     140             275 : do_GetIOService(nsresult* error = 0)
     141                 : {
     142             275 :     return nsGetServiceByContractIDWithError(NS_IOSERVICE_CONTRACTID, error);
     143                 : }
     144                 : 
     145                 : // An alias to do_GetIOService
     146                 : inline const nsGetServiceByContractIDWithError
     147                 : do_GetNetUtil(nsresult* error = 0)
     148                 : {
     149                 :     return do_GetIOService(error);
     150                 : }
     151                 : #endif
     152                 : 
     153                 : // private little helper function... don't call this directly!
     154                 : inline nsresult
     155          161423 : net_EnsureIOService(nsIIOService **ios, nsCOMPtr<nsIIOService> &grip)
     156                 : {
     157          161423 :     nsresult rv = NS_OK;
     158          161423 :     if (!*ios) {
     159          160104 :         grip = do_GetIOService(&rv);
     160          160104 :         *ios = grip;
     161                 :     }
     162          161423 :     return rv;
     163                 : }
     164                 : 
     165                 : inline nsresult
     166          136821 : NS_NewURI(nsIURI **result, 
     167                 :           const nsACString &spec, 
     168                 :           const char *charset = nsnull,
     169                 :           nsIURI *baseURI = nsnull,
     170                 :           nsIIOService *ioService = nsnull)     // pass in nsIIOService to optimize callers
     171                 : {
     172                 :     nsresult rv;
     173          273642 :     nsCOMPtr<nsIIOService> grip;
     174          136821 :     rv = net_EnsureIOService(&ioService, grip);
     175          136821 :     if (ioService)
     176          136821 :         rv = ioService->NewURI(spec, charset, baseURI, result);
     177          136821 :     return rv; 
     178                 : }
     179                 : 
     180                 : inline nsresult
     181             338 : NS_NewURI(nsIURI* *result, 
     182                 :           const nsAString& spec, 
     183                 :           const char *charset = nsnull,
     184                 :           nsIURI* baseURI = nsnull,
     185                 :           nsIIOService* ioService = nsnull)     // pass in nsIIOService to optimize callers
     186                 : {
     187             338 :     return NS_NewURI(result, NS_ConvertUTF16toUTF8(spec), charset, baseURI, ioService);
     188                 : }
     189                 : 
     190                 : inline nsresult
     191          109505 : NS_NewURI(nsIURI* *result, 
     192                 :           const char *spec,
     193                 :           nsIURI* baseURI = nsnull,
     194                 :           nsIIOService* ioService = nsnull)     // pass in nsIIOService to optimize callers
     195                 : {
     196          109505 :     return NS_NewURI(result, nsDependentCString(spec), nsnull, baseURI, ioService);
     197                 : }
     198                 : 
     199                 : inline nsresult
     200             333 : NS_NewFileURI(nsIURI* *result, 
     201                 :               nsIFile* spec, 
     202                 :               nsIIOService* ioService = nsnull)     // pass in nsIIOService to optimize callers
     203                 : {
     204                 :     nsresult rv;
     205             666 :     nsCOMPtr<nsIIOService> grip;
     206             333 :     rv = net_EnsureIOService(&ioService, grip);
     207             333 :     if (ioService)
     208             333 :         rv = ioService->NewFileURI(spec, result);
     209             333 :     return rv;
     210                 : }
     211                 : 
     212                 : inline nsresult
     213            4032 : NS_NewChannel(nsIChannel           **result,
     214                 :               nsIURI                *uri,
     215                 :               nsIIOService          *ioService = nsnull,    // pass in nsIIOService to optimize callers
     216                 :               nsILoadGroup          *loadGroup = nsnull,
     217                 :               nsIInterfaceRequestor *callbacks = nsnull,
     218                 :               PRUint32               loadFlags = nsIRequest::LOAD_NORMAL,
     219                 :               nsIChannelPolicy      *channelPolicy = nsnull)
     220                 : {
     221                 :     nsresult rv;
     222            8064 :     nsCOMPtr<nsIIOService> grip;
     223            4032 :     rv = net_EnsureIOService(&ioService, grip);
     224            4032 :     if (ioService) {
     225            8064 :         nsCOMPtr<nsIChannel> chan;
     226            4032 :         rv = ioService->NewChannelFromURI(uri, getter_AddRefs(chan));
     227            4032 :         if (NS_SUCCEEDED(rv)) {
     228            4028 :             if (loadGroup)
     229               0 :                 rv |= chan->SetLoadGroup(loadGroup);
     230            4028 :             if (callbacks)
     231             483 :                 rv |= chan->SetNotificationCallbacks(callbacks);
     232            4028 :             if (loadFlags != nsIRequest::LOAD_NORMAL) {
     233                 :                 // Retain the LOAD_REPLACE load flag if set.
     234            1064 :                 nsLoadFlags normalLoadFlags = 0;
     235            1064 :                 chan->GetLoadFlags(&normalLoadFlags);
     236            1064 :                 rv |= chan->SetLoadFlags(loadFlags | 
     237                 :                                          (normalLoadFlags & 
     238            1064 :                                           nsIChannel::LOAD_REPLACE));
     239                 :             }
     240            4028 :             if (channelPolicy) {
     241               0 :                 nsCOMPtr<nsIWritablePropertyBag2> props = do_QueryInterface(chan);
     242               0 :                 if (props) {
     243               0 :                     props->SetPropertyAsInterface(NS_CHANNEL_PROP_CHANNEL_POLICY,
     244               0 :                                                   channelPolicy);
     245                 :                 }
     246                 :             }
     247            4028 :             if (NS_SUCCEEDED(rv))
     248            4028 :                 chan.forget(result);
     249                 :         }
     250                 :     }
     251            4032 :     return rv;
     252                 : }
     253                 : 
     254                 : // Use this function with CAUTION. It creates a stream that blocks when you
     255                 : // Read() from it and blocking the UI thread is a bad idea. If you don't want
     256                 : // to implement a full blown asynchronous consumer (via nsIStreamListener) look
     257                 : // at nsIStreamLoader instead.
     258                 : inline nsresult
     259               1 : NS_OpenURI(nsIInputStream       **result,
     260                 :            nsIURI                *uri,
     261                 :            nsIIOService          *ioService = nsnull,     // pass in nsIIOService to optimize callers
     262                 :            nsILoadGroup          *loadGroup = nsnull,
     263                 :            nsIInterfaceRequestor *callbacks = nsnull,
     264                 :            PRUint32               loadFlags = nsIRequest::LOAD_NORMAL,
     265                 :            nsIChannel           **channelOut = nsnull)
     266                 : {
     267                 :     nsresult rv;
     268               2 :     nsCOMPtr<nsIChannel> channel;
     269               1 :     rv = NS_NewChannel(getter_AddRefs(channel), uri, ioService,
     270               1 :                        loadGroup, callbacks, loadFlags);
     271               1 :     if (NS_SUCCEEDED(rv)) {
     272                 :         nsIInputStream *stream;
     273               1 :         rv = channel->Open(&stream);
     274               1 :         if (NS_SUCCEEDED(rv)) {
     275               1 :             *result = stream;
     276               1 :             if (channelOut) {
     277               0 :                 *channelOut = nsnull;
     278               0 :                 channel.swap(*channelOut);
     279                 :             }
     280                 :         }
     281                 :     }
     282               1 :     return rv;
     283                 : }
     284                 : 
     285                 : inline nsresult
     286               5 : NS_OpenURI(nsIStreamListener     *listener, 
     287                 :            nsISupports           *context, 
     288                 :            nsIURI                *uri,
     289                 :            nsIIOService          *ioService = nsnull,     // pass in nsIIOService to optimize callers
     290                 :            nsILoadGroup          *loadGroup = nsnull,
     291                 :            nsIInterfaceRequestor *callbacks = nsnull,
     292                 :            PRUint32               loadFlags = nsIRequest::LOAD_NORMAL)
     293                 : {
     294                 :     nsresult rv;
     295              10 :     nsCOMPtr<nsIChannel> channel;
     296               5 :     rv = NS_NewChannel(getter_AddRefs(channel), uri, ioService,
     297               5 :                        loadGroup, callbacks, loadFlags);
     298               5 :     if (NS_SUCCEEDED(rv))
     299               5 :         rv = channel->AsyncOpen(listener, context);
     300               5 :     return rv;
     301                 : }
     302                 : 
     303                 : inline nsresult
     304                 : NS_MakeAbsoluteURI(nsACString       &result,
     305                 :                    const nsACString &spec, 
     306                 :                    nsIURI           *baseURI, 
     307                 :                    nsIIOService     *unused = nsnull)
     308                 : {
     309                 :     nsresult rv;
     310                 :     if (!baseURI) {
     311                 :         NS_WARNING("It doesn't make sense to not supply a base URI");
     312                 :         result = spec;
     313                 :         rv = NS_OK;
     314                 :     }
     315                 :     else if (spec.IsEmpty())
     316                 :         rv = baseURI->GetSpec(result);
     317                 :     else
     318                 :         rv = baseURI->Resolve(spec, result);
     319                 :     return rv;
     320                 : }
     321                 : 
     322                 : inline nsresult
     323                 : NS_MakeAbsoluteURI(char        **result,
     324                 :                    const char   *spec, 
     325                 :                    nsIURI       *baseURI, 
     326                 :                    nsIIOService *unused = nsnull)
     327                 : {
     328                 :     nsresult rv;
     329                 :     nsCAutoString resultBuf;
     330                 :     rv = NS_MakeAbsoluteURI(resultBuf, nsDependentCString(spec), baseURI);
     331                 :     if (NS_SUCCEEDED(rv)) {
     332                 :         *result = ToNewCString(resultBuf);
     333                 :         if (!*result)
     334                 :             rv = NS_ERROR_OUT_OF_MEMORY;
     335                 :     }
     336                 :     return rv;
     337                 : }
     338                 : 
     339                 : inline nsresult
     340               0 : NS_MakeAbsoluteURI(nsAString       &result,
     341                 :                    const nsAString &spec, 
     342                 :                    nsIURI          *baseURI,
     343                 :                    nsIIOService    *unused = nsnull)
     344                 : {
     345                 :     nsresult rv;
     346               0 :     if (!baseURI) {
     347               0 :         NS_WARNING("It doesn't make sense to not supply a base URI");
     348               0 :         result = spec;
     349               0 :         rv = NS_OK;
     350                 :     }
     351                 :     else {
     352               0 :         nsCAutoString resultBuf;
     353               0 :         if (spec.IsEmpty())
     354               0 :             rv = baseURI->GetSpec(resultBuf);
     355                 :         else
     356               0 :             rv = baseURI->Resolve(NS_ConvertUTF16toUTF8(spec), resultBuf);
     357               0 :         if (NS_SUCCEEDED(rv))
     358               0 :             CopyUTF8toUTF16(resultBuf, result);
     359                 :     }
     360               0 :     return rv;
     361                 : }
     362                 : 
     363                 : /**
     364                 :  * This function is a helper function to get a scheme's default port.
     365                 :  */
     366                 : inline PRInt32
     367              19 : NS_GetDefaultPort(const char *scheme,
     368                 :                   nsIIOService* ioService = nsnull)
     369                 : {
     370                 :   nsresult rv;
     371                 : 
     372              38 :   nsCOMPtr<nsIIOService> grip;
     373              19 :   net_EnsureIOService(&ioService, grip);
     374              19 :   if (!ioService)
     375               0 :       return -1;
     376                 :  
     377              38 :   nsCOMPtr<nsIProtocolHandler> handler;
     378              19 :   rv = ioService->GetProtocolHandler(scheme, getter_AddRefs(handler));
     379              19 :   if (NS_FAILED(rv))
     380               0 :     return -1;
     381                 :   PRInt32 port;
     382              19 :   rv = handler->GetDefaultPort(&port);
     383              19 :   return NS_SUCCEEDED(rv) ? port : -1;
     384                 : }
     385                 : 
     386                 : /**
     387                 :  * This function is a helper function to apply the ToAscii conversion
     388                 :  * to a string
     389                 :  */
     390                 : inline bool
     391                 : NS_StringToACE(const nsACString &idn, nsACString &result)
     392                 : {
     393                 :   nsCOMPtr<nsIIDNService> idnSrv = do_GetService(NS_IDNSERVICE_CONTRACTID);
     394                 :   if (!idnSrv)
     395                 :     return false;
     396                 :   nsresult rv = idnSrv->ConvertUTF8toACE(idn, result);
     397                 :   if (NS_FAILED(rv))
     398                 :     return false;
     399                 :   
     400                 :   return true;
     401                 : }
     402                 : 
     403                 : /**
     404                 :  * This function is a helper function to get a protocol's default port if the
     405                 :  * URI does not specify a port explicitly. Returns -1 if this protocol has no
     406                 :  * concept of ports or if there was an error getting the port.
     407                 :  */
     408                 : inline PRInt32
     409            2914 : NS_GetRealPort(nsIURI* aURI,
     410                 :                nsIIOService* ioService = nsnull)     // pass in nsIIOService to optimize callers
     411                 : {
     412                 :     PRInt32 port;
     413            2914 :     nsresult rv = aURI->GetPort(&port);
     414            2914 :     if (NS_FAILED(rv))
     415            2834 :         return -1;
     416                 : 
     417              80 :     if (port != -1)
     418              61 :         return port; // explicitly specified
     419                 : 
     420                 :     // Otherwise, we have to get the default port from the protocol handler
     421                 : 
     422                 :     // Need the scheme first
     423              38 :     nsCAutoString scheme;
     424              19 :     rv = aURI->GetScheme(scheme);
     425              19 :     if (NS_FAILED(rv))
     426               0 :         return -1;
     427                 : 
     428              19 :     return NS_GetDefaultPort(scheme.get());
     429                 : }
     430                 : 
     431                 : inline nsresult
     432            1338 : NS_NewInputStreamChannel(nsIChannel      **result,
     433                 :                          nsIURI           *uri,
     434                 :                          nsIInputStream   *stream,
     435                 :                          const nsACString &contentType,
     436                 :                          const nsACString *contentCharset)
     437                 : {
     438                 :     nsresult rv;
     439                 :     nsCOMPtr<nsIInputStreamChannel> isc =
     440            2676 :         do_CreateInstance(NS_INPUTSTREAMCHANNEL_CONTRACTID, &rv);
     441            1338 :     if (NS_FAILED(rv))
     442               0 :         return rv;
     443            1338 :     rv |= isc->SetURI(uri);
     444            1338 :     rv |= isc->SetContentStream(stream);
     445            1338 :     if (NS_FAILED(rv))
     446               0 :         return rv;
     447            2676 :     nsCOMPtr<nsIChannel> chan = do_QueryInterface(isc, &rv);
     448            1338 :     if (NS_FAILED(rv))
     449               0 :         return rv;
     450            1338 :     if (!contentType.IsEmpty())
     451            1334 :         rv |= chan->SetContentType(contentType);
     452            1338 :     if (contentCharset && !contentCharset->IsEmpty())
     453               2 :         rv |= chan->SetContentCharset(*contentCharset);
     454            1338 :     if (NS_SUCCEEDED(rv)) {
     455            1338 :         *result = nsnull;
     456            1338 :         chan.swap(*result);
     457                 :     }
     458            1338 :     return rv;
     459                 : }
     460                 : 
     461                 : inline nsresult
     462             767 : NS_NewInputStreamChannel(nsIChannel      **result,
     463                 :                          nsIURI           *uri,
     464                 :                          nsIInputStream   *stream,
     465               2 :                          const nsACString &contentType    = EmptyCString())
     466                 : {
     467             767 :     return NS_NewInputStreamChannel(result, uri, stream, contentType, nsnull);
     468                 : }
     469                 : 
     470                 : inline nsresult
     471               2 : NS_NewInputStreamChannel(nsIChannel      **result,
     472                 :                          nsIURI           *uri,
     473                 :                          nsIInputStream   *stream,
     474                 :                          const nsACString &contentType,
     475                 :                          const nsACString &contentCharset)
     476                 : {
     477                 :     return NS_NewInputStreamChannel(result, uri, stream, contentType,
     478               2 :                                     &contentCharset);
     479                 : }
     480                 : 
     481                 : inline nsresult
     482               5 : NS_NewInputStreamPump(nsIInputStreamPump **result,
     483                 :                       nsIInputStream      *stream,
     484                 :                       PRInt64              streamPos = PRInt64(-1),
     485                 :                       PRInt64              streamLen = PRInt64(-1),
     486                 :                       PRUint32             segsize = 0,
     487                 :                       PRUint32             segcount = 0,
     488                 :                       bool                 closeWhenDone = false)
     489                 : {
     490                 :     nsresult rv;
     491                 :     nsCOMPtr<nsIInputStreamPump> pump =
     492              10 :         do_CreateInstance(NS_INPUTSTREAMPUMP_CONTRACTID, &rv);
     493               5 :     if (NS_SUCCEEDED(rv)) {
     494               5 :         rv = pump->Init(stream, streamPos, streamLen,
     495               5 :                         segsize, segcount, closeWhenDone);
     496               5 :         if (NS_SUCCEEDED(rv)) {
     497               5 :             *result = nsnull;
     498               5 :             pump.swap(*result);
     499                 :         }
     500                 :     }
     501               5 :     return rv;
     502                 : }
     503                 : 
     504                 : // NOTE: you will need to specify whether or not your streams are buffered
     505                 : // (i.e., do they implement ReadSegments/WriteSegments).  the default
     506                 : // assumption of TRUE for both streams might not be right for you!
     507                 : inline nsresult
     508               0 : NS_NewAsyncStreamCopier(nsIAsyncStreamCopier **result,
     509                 :                         nsIInputStream        *source,
     510                 :                         nsIOutputStream       *sink,
     511                 :                         nsIEventTarget        *target,
     512                 :                         bool                   sourceBuffered = true,
     513                 :                         bool                   sinkBuffered = true,
     514                 :                         PRUint32               chunkSize = 0,
     515                 :                         bool                   closeSource = true,
     516                 :                         bool                   closeSink = true)
     517                 : {
     518                 :     nsresult rv;
     519                 :     nsCOMPtr<nsIAsyncStreamCopier> copier =
     520               0 :         do_CreateInstance(NS_ASYNCSTREAMCOPIER_CONTRACTID, &rv);
     521               0 :     if (NS_SUCCEEDED(rv)) {
     522               0 :         rv = copier->Init(source, sink, target, sourceBuffered, sinkBuffered,
     523               0 :                           chunkSize, closeSource, closeSink);
     524               0 :         if (NS_SUCCEEDED(rv)) {
     525               0 :             *result = nsnull;
     526               0 :             copier.swap(*result);
     527                 :         }
     528                 :     }
     529               0 :     return rv;
     530                 : }
     531                 : 
     532                 : inline nsresult
     533            1404 : NS_NewLoadGroup(nsILoadGroup      **result,
     534                 :                 nsIRequestObserver *obs)
     535                 : {
     536                 :     nsresult rv;
     537                 :     nsCOMPtr<nsILoadGroup> group =
     538            2808 :         do_CreateInstance(NS_LOADGROUP_CONTRACTID, &rv);
     539            1404 :     if (NS_SUCCEEDED(rv)) {
     540            1404 :         rv = group->SetGroupObserver(obs);
     541            1404 :         if (NS_SUCCEEDED(rv)) {
     542            1404 :             *result = nsnull;
     543            1404 :             group.swap(*result);
     544                 :         }
     545                 :     }
     546            1404 :     return rv;
     547                 : }
     548                 : 
     549                 : inline nsresult
     550               1 : NS_NewDownloader(nsIStreamListener   **result,
     551                 :                  nsIDownloadObserver  *observer,
     552                 :                  nsIFile              *downloadLocation = nsnull)
     553                 : {
     554                 :     nsresult rv;
     555                 :     nsCOMPtr<nsIDownloader> downloader =
     556               2 :         do_CreateInstance(NS_DOWNLOADER_CONTRACTID, &rv);
     557               1 :     if (NS_SUCCEEDED(rv)) {
     558               1 :         rv = downloader->Init(observer, downloadLocation);
     559               1 :         if (NS_SUCCEEDED(rv))
     560               1 :             NS_ADDREF(*result = downloader);
     561                 :     }
     562               1 :     return rv;
     563                 : }
     564                 : 
     565                 : inline nsresult
     566               0 : NS_NewStreamLoader(nsIStreamLoader        **result,
     567                 :                    nsIStreamLoaderObserver *observer)
     568                 : {
     569                 :     nsresult rv;
     570                 :     nsCOMPtr<nsIStreamLoader> loader =
     571               0 :         do_CreateInstance(NS_STREAMLOADER_CONTRACTID, &rv);
     572               0 :     if (NS_SUCCEEDED(rv)) {
     573               0 :         rv = loader->Init(observer);
     574               0 :         if (NS_SUCCEEDED(rv)) {
     575               0 :             *result = nsnull;
     576               0 :             loader.swap(*result);
     577                 :         }
     578                 :     }
     579               0 :     return rv;
     580                 : }
     581                 : 
     582                 : inline nsresult
     583               0 : NS_NewStreamLoader(nsIStreamLoader        **result,
     584                 :                    nsIURI                  *uri,
     585                 :                    nsIStreamLoaderObserver *observer,
     586                 :                    nsISupports             *context   = nsnull,
     587                 :                    nsILoadGroup            *loadGroup = nsnull,
     588                 :                    nsIInterfaceRequestor   *callbacks = nsnull,
     589                 :                    PRUint32                 loadFlags = nsIRequest::LOAD_NORMAL,
     590                 :                    nsIURI                  *referrer  = nsnull)
     591                 : {
     592                 :     nsresult rv;
     593               0 :     nsCOMPtr<nsIChannel> channel;
     594               0 :     rv = NS_NewChannel(getter_AddRefs(channel),
     595                 :                        uri,
     596                 :                        nsnull,
     597                 :                        loadGroup,
     598                 :                        callbacks,
     599               0 :                        loadFlags);
     600               0 :     if (NS_SUCCEEDED(rv)) {
     601               0 :         nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
     602               0 :         if (httpChannel)
     603               0 :             httpChannel->SetReferrer(referrer);
     604               0 :         rv = NS_NewStreamLoader(result, observer);
     605               0 :         if (NS_SUCCEEDED(rv))
     606               0 :           rv = channel->AsyncOpen(*result, context);
     607                 :     }
     608               0 :     return rv;
     609                 : }
     610                 : 
     611                 : inline nsresult
     612               0 : NS_NewUnicharStreamLoader(nsIUnicharStreamLoader        **result,
     613                 :                           nsIUnicharStreamLoaderObserver *observer)
     614                 : {
     615                 :     nsresult rv;
     616                 :     nsCOMPtr<nsIUnicharStreamLoader> loader =
     617               0 :         do_CreateInstance(NS_UNICHARSTREAMLOADER_CONTRACTID, &rv);
     618               0 :     if (NS_SUCCEEDED(rv)) {
     619               0 :         rv = loader->Init(observer);
     620               0 :         if (NS_SUCCEEDED(rv)) {
     621               0 :             *result = nsnull;
     622               0 :             loader.swap(*result);
     623                 :         }
     624                 :     }
     625               0 :     return rv;
     626                 : }
     627                 : 
     628                 : inline nsresult
     629              18 : NS_NewSyncStreamListener(nsIStreamListener **result,
     630                 :                          nsIInputStream    **stream)
     631                 : {
     632                 :     nsresult rv;
     633                 :     nsCOMPtr<nsISyncStreamListener> listener =
     634              36 :         do_CreateInstance(NS_SYNCSTREAMLISTENER_CONTRACTID, &rv);
     635              18 :     if (NS_SUCCEEDED(rv)) {
     636              18 :         rv = listener->GetInputStream(stream);
     637              18 :         if (NS_SUCCEEDED(rv))
     638              18 :             NS_ADDREF(*result = listener);  // cannot use nsCOMPtr::swap
     639                 :     }
     640              18 :     return rv;
     641                 : }
     642                 : 
     643                 : /**
     644                 :  * Implement the nsIChannel::Open(nsIInputStream**) method using the channel's
     645                 :  * AsyncOpen method.
     646                 :  *
     647                 :  * NOTE: Reading from the returned nsIInputStream may spin the current
     648                 :  * thread's event queue, which could result in any event being processed.
     649                 :  */
     650                 : inline nsresult
     651              18 : NS_ImplementChannelOpen(nsIChannel      *channel,
     652                 :                         nsIInputStream **result)
     653                 : {
     654              36 :     nsCOMPtr<nsIStreamListener> listener;
     655              36 :     nsCOMPtr<nsIInputStream> stream;
     656              18 :     nsresult rv = NS_NewSyncStreamListener(getter_AddRefs(listener),
     657              36 :                                            getter_AddRefs(stream));
     658              18 :     if (NS_SUCCEEDED(rv)) {
     659              18 :         rv = channel->AsyncOpen(listener, nsnull);
     660              18 :         if (NS_SUCCEEDED(rv)) {
     661                 :             PRUint32 n;
     662                 :             // block until the initial response is received or an error occurs.
     663              18 :             rv = stream->Available(&n);
     664              18 :             if (NS_SUCCEEDED(rv)) {
     665              18 :                 *result = nsnull;
     666              18 :                 stream.swap(*result);
     667                 :             }
     668                 :         }
     669                 :     }
     670              18 :     return rv;
     671                 : }
     672                 : 
     673                 : inline nsresult
     674             399 : NS_NewRequestObserverProxy(nsIRequestObserver **result,
     675                 :                            nsIRequestObserver  *observer,
     676                 :                            nsIEventTarget      *target = nsnull)
     677                 : {
     678                 :     nsresult rv;
     679                 :     nsCOMPtr<nsIRequestObserverProxy> proxy =
     680             798 :         do_CreateInstance(NS_REQUESTOBSERVERPROXY_CONTRACTID, &rv);
     681             399 :     if (NS_SUCCEEDED(rv)) {
     682             399 :         rv = proxy->Init(observer, target);
     683             399 :         if (NS_SUCCEEDED(rv))
     684             399 :             NS_ADDREF(*result = proxy);  // cannot use nsCOMPtr::swap
     685                 :     }
     686             399 :     return rv;
     687                 : }
     688                 : 
     689                 : inline nsresult
     690            5733 : NS_NewSimpleStreamListener(nsIStreamListener **result,
     691                 :                            nsIOutputStream    *sink,
     692                 :                            nsIRequestObserver *observer = nsnull)
     693                 : {
     694                 :     nsresult rv;
     695                 :     nsCOMPtr<nsISimpleStreamListener> listener = 
     696           11466 :         do_CreateInstance(NS_SIMPLESTREAMLISTENER_CONTRACTID, &rv);
     697            5733 :     if (NS_SUCCEEDED(rv)) {
     698            5733 :         rv = listener->Init(sink, observer);
     699            5733 :         if (NS_SUCCEEDED(rv))
     700            5733 :             NS_ADDREF(*result = listener);  // cannot use nsCOMPtr::swap
     701                 :     }
     702            5733 :     return rv;
     703                 : }
     704                 : 
     705                 : inline nsresult
     706            3125 : NS_CheckPortSafety(PRInt32       port,
     707                 :                    const char   *scheme,
     708                 :                    nsIIOService *ioService = nsnull)
     709                 : {
     710                 :     nsresult rv;
     711            6250 :     nsCOMPtr<nsIIOService> grip;
     712            3125 :     rv = net_EnsureIOService(&ioService, grip);
     713            3125 :     if (ioService) {
     714                 :         bool allow;
     715            3125 :         rv = ioService->AllowPort(port, scheme, &allow);
     716            3125 :         if (NS_SUCCEEDED(rv) && !allow) {
     717               0 :             NS_WARNING("port blocked");
     718               0 :             rv = NS_ERROR_PORT_ACCESS_NOT_ALLOWED;
     719                 :         }
     720                 :     }
     721            3125 :     return rv;
     722                 : }
     723                 : 
     724                 : // Determine if this URI is using a safe port.
     725                 : inline nsresult
     726            3673 : NS_CheckPortSafety(nsIURI *uri) {
     727                 :     PRInt32 port;
     728            3673 :     nsresult rv = uri->GetPort(&port);
     729            3673 :     if (NS_FAILED(rv) || port == -1)  // port undefined or default-valued
     730             548 :         return NS_OK;
     731            6250 :     nsCAutoString scheme;
     732            3125 :     uri->GetScheme(scheme);
     733            3125 :     return NS_CheckPortSafety(port, scheme.get());
     734                 : }
     735                 : 
     736                 : inline nsresult
     737                 : NS_NewProxyInfo(const nsACString &type,
     738                 :                 const nsACString &host,
     739                 :                 PRInt32           port,
     740                 :                 PRUint32          flags,
     741                 :                 nsIProxyInfo    **result)
     742                 : {
     743                 :     nsresult rv;
     744                 :     nsCOMPtr<nsIProtocolProxyService> pps =
     745                 :             do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv);
     746                 :     if (NS_SUCCEEDED(rv))
     747                 :         rv = pps->NewProxyInfo(type, host, port, flags, PR_UINT32_MAX, nsnull,
     748                 :                                result);
     749                 :     return rv; 
     750                 : }
     751                 : 
     752                 : inline nsresult
     753           17093 : NS_GetFileProtocolHandler(nsIFileProtocolHandler **result,
     754                 :                           nsIIOService            *ioService = nsnull)
     755                 : {
     756                 :     nsresult rv;
     757           34186 :     nsCOMPtr<nsIIOService> grip;
     758           17093 :     rv = net_EnsureIOService(&ioService, grip);
     759           17093 :     if (ioService) {
     760           34186 :         nsCOMPtr<nsIProtocolHandler> handler;
     761           17093 :         rv = ioService->GetProtocolHandler("file", getter_AddRefs(handler));
     762           17093 :         if (NS_SUCCEEDED(rv))
     763           17093 :             rv = CallQueryInterface(handler, result);
     764                 :     }
     765           17093 :     return rv;
     766                 : }
     767                 : 
     768                 : inline nsresult
     769               0 : NS_GetFileFromURLSpec(const nsACString  &inURL,
     770                 :                       nsIFile          **result,
     771                 :                       nsIIOService      *ioService = nsnull)
     772                 : {
     773                 :     nsresult rv;
     774               0 :     nsCOMPtr<nsIFileProtocolHandler> fileHandler;
     775               0 :     rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler), ioService);
     776               0 :     if (NS_SUCCEEDED(rv))
     777               0 :         rv = fileHandler->GetFileFromURLSpec(inURL, result);
     778               0 :     return rv;
     779                 : }
     780                 : 
     781                 : inline nsresult
     782               0 : NS_GetURLSpecFromFile(nsIFile      *file,
     783                 :                       nsACString   &url,
     784                 :                       nsIIOService *ioService = nsnull)
     785                 : {
     786                 :     nsresult rv;
     787               0 :     nsCOMPtr<nsIFileProtocolHandler> fileHandler;
     788               0 :     rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler), ioService);
     789               0 :     if (NS_SUCCEEDED(rv))
     790               0 :         rv = fileHandler->GetURLSpecFromFile(file, url);
     791               0 :     return rv;
     792                 : }
     793                 : 
     794                 : /**
     795                 :  * Converts the nsIFile to the corresponding URL string.
     796                 :  * Should only be called on files which are not directories,
     797                 :  * is otherwise identical to NS_GetURLSpecFromFile, but is
     798                 :  * usually more efficient.
     799                 :  * Warning: this restriction may not be enforced at runtime!
     800                 :  */
     801                 : inline nsresult
     802           14178 : NS_GetURLSpecFromActualFile(nsIFile      *file,
     803                 :                             nsACString   &url,
     804                 :                             nsIIOService *ioService = nsnull)
     805                 : {
     806                 :     nsresult rv;
     807           28356 :     nsCOMPtr<nsIFileProtocolHandler> fileHandler;
     808           14178 :     rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler), ioService);
     809           14178 :     if (NS_SUCCEEDED(rv))
     810           14178 :         rv = fileHandler->GetURLSpecFromActualFile(file, url);
     811           14178 :     return rv;
     812                 : }
     813                 : 
     814                 : /**
     815                 :  * Converts the nsIFile to the corresponding URL string.
     816                 :  * Should only be called on files which are directories,
     817                 :  * is otherwise identical to NS_GetURLSpecFromFile, but is
     818                 :  * usually more efficient.
     819                 :  * Warning: this restriction may not be enforced at runtime!
     820                 :  */
     821                 : inline nsresult
     822                 : NS_GetURLSpecFromDir(nsIFile      *file,
     823                 :                      nsACString   &url,
     824                 :                      nsIIOService *ioService = nsnull)
     825                 : {
     826                 :     nsresult rv;
     827                 :     nsCOMPtr<nsIFileProtocolHandler> fileHandler;
     828                 :     rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler), ioService);
     829                 :     if (NS_SUCCEEDED(rv))
     830                 :         rv = fileHandler->GetURLSpecFromDir(file, url);
     831                 :     return rv;
     832                 : }
     833                 : 
     834                 : /**
     835                 :  * Obtains the referrer for a given channel.  This first tries to obtain the
     836                 :  * referrer from the property docshell.internalReferrer, and if that doesn't
     837                 :  * work and the channel is an nsIHTTPChannel, we check it's referrer property.
     838                 :  *
     839                 :  * @returns NS_ERROR_NOT_AVAILABLE if no referrer is available.
     840                 :  */
     841                 : inline nsresult
     842              23 : NS_GetReferrerFromChannel(nsIChannel *channel,
     843                 :                           nsIURI **referrer)
     844                 : {
     845              23 :     nsresult rv = NS_ERROR_NOT_AVAILABLE;
     846              23 :     *referrer = nsnull;
     847                 : 
     848              46 :     nsCOMPtr<nsIPropertyBag2> props(do_QueryInterface(channel));
     849              23 :     if (props) {
     850                 :       // We have to check for a property on a property bag because the
     851                 :       // referrer may be empty for security reasons (for example, when loading
     852                 :       // an http page with an https referrer).
     853              46 :       rv = props->GetPropertyAsInterface(NS_LITERAL_STRING("docshell.internalReferrer"),
     854                 :                                          NS_GET_IID(nsIURI),
     855              23 :                                          reinterpret_cast<void **>(referrer));
     856              23 :       if (NS_FAILED(rv))
     857              23 :         *referrer = nsnull;
     858                 :     }
     859                 : 
     860                 :     // if that didn't work, we can still try to get the referrer from the
     861                 :     // nsIHttpChannel (if we can QI to it)
     862              23 :     if (!(*referrer)) {
     863              46 :       nsCOMPtr<nsIHttpChannel> chan(do_QueryInterface(channel));
     864              23 :       if (chan) {
     865              23 :         rv = chan->GetReferrer(referrer);
     866              23 :         if (NS_FAILED(rv))
     867               0 :           *referrer = nsnull;
     868                 :       }
     869                 :     }
     870              23 :     return rv;
     871                 : }
     872                 : 
     873                 : #ifdef MOZILLA_INTERNAL_API
     874                 : inline nsresult
     875                 : NS_ExamineForProxy(const char    *scheme,
     876                 :                    const char    *host,
     877                 :                    PRInt32        port, 
     878                 :                    nsIProxyInfo **proxyInfo)
     879                 : {
     880                 :     nsresult rv;
     881                 :     nsCOMPtr<nsIProtocolProxyService> pps =
     882                 :             do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv);
     883                 :     if (NS_SUCCEEDED(rv)) {
     884                 :         nsCAutoString spec(scheme);
     885                 :         spec.Append("://");
     886                 :         spec.Append(host);
     887                 :         spec.Append(':');
     888                 :         spec.AppendInt(port);
     889                 :         // XXXXX - Under no circumstances whatsoever should any code which
     890                 :         // wants a uri do this. I do this here because I do not, in fact,
     891                 :         // actually want a uri (the dummy uris created here may not be 
     892                 :         // syntactically valid for the specific protocol), and all we need
     893                 :         // is something which has a valid scheme, hostname, and a string
     894                 :         // to pass to PAC if needed - bbaetz
     895                 :         nsCOMPtr<nsIURI> uri =
     896                 :                 do_CreateInstance(NS_STANDARDURL_CONTRACTID, &rv);
     897                 :         if (NS_SUCCEEDED(rv)) {
     898                 :             rv = uri->SetSpec(spec);
     899                 :             if (NS_SUCCEEDED(rv))
     900                 :                 rv = pps->Resolve(uri, 0, proxyInfo);
     901                 :         }
     902                 :     }
     903                 :     return rv;
     904                 : }
     905                 : #endif
     906                 : 
     907                 : inline nsresult
     908             101 : NS_ParseContentType(const nsACString &rawContentType,
     909                 :                     nsCString        &contentType,
     910                 :                     nsCString        &contentCharset)
     911                 : {
     912                 :     // contentCharset is left untouched if not present in rawContentType
     913                 :     nsresult rv;
     914             202 :     nsCOMPtr<nsINetUtil> util = do_GetNetUtil(&rv);
     915             101 :     NS_ENSURE_SUCCESS(rv, rv);
     916             202 :     nsCString charset;
     917                 :     bool hadCharset;
     918             101 :     rv = util->ParseContentType(rawContentType, charset, &hadCharset,
     919             101 :                                 contentType);
     920             101 :     if (NS_SUCCEEDED(rv) && hadCharset)
     921               4 :         contentCharset = charset;
     922             101 :     return rv;
     923                 : }
     924                 : 
     925                 : inline nsresult
     926               0 : NS_ExtractCharsetFromContentType(const nsACString &rawContentType,
     927                 :                                  nsCString        &contentCharset,
     928                 :                                  bool             *hadCharset,
     929                 :                                  PRInt32          *charsetStart,
     930                 :                                  PRInt32          *charsetEnd)
     931                 : {
     932                 :     // contentCharset is left untouched if not present in rawContentType
     933                 :     nsresult rv;
     934               0 :     nsCOMPtr<nsINetUtil> util = do_GetNetUtil(&rv);
     935               0 :     NS_ENSURE_SUCCESS(rv, rv);
     936                 : 
     937               0 :     return util->ExtractCharsetFromContentType(rawContentType,
     938                 :                                                contentCharset,
     939                 :                                                charsetStart,
     940                 :                                                charsetEnd,
     941               0 :                                                hadCharset);
     942                 : }
     943                 : 
     944                 : inline nsresult
     945           12186 : NS_NewLocalFileInputStream(nsIInputStream **result,
     946                 :                            nsIFile         *file,
     947                 :                            PRInt32          ioFlags       = -1,
     948                 :                            PRInt32          perm          = -1,
     949                 :                            PRInt32          behaviorFlags = 0)
     950                 : {
     951                 :     nsresult rv;
     952                 :     nsCOMPtr<nsIFileInputStream> in =
     953           24372 :         do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID, &rv);
     954           12186 :     if (NS_SUCCEEDED(rv)) {
     955           12186 :         rv = in->Init(file, ioFlags, perm, behaviorFlags);
     956           12186 :         if (NS_SUCCEEDED(rv))
     957           11674 :             NS_ADDREF(*result = in);  // cannot use nsCOMPtr::swap
     958                 :     }
     959           12186 :     return rv;
     960                 : }
     961                 : 
     962                 : inline nsresult
     963               0 : NS_NewPartialLocalFileInputStream(nsIInputStream **result,
     964                 :                                   nsIFile         *file,
     965                 :                                   PRUint64         offset,
     966                 :                                   PRUint64         length,
     967                 :                                   PRInt32          ioFlags       = -1,
     968                 :                                   PRInt32          perm          = -1,
     969                 :                                   PRInt32          behaviorFlags = 0)
     970                 : {
     971                 :     nsresult rv;
     972                 :     nsCOMPtr<nsIPartialFileInputStream> in =
     973               0 :         do_CreateInstance(NS_PARTIALLOCALFILEINPUTSTREAM_CONTRACTID, &rv);
     974               0 :     if (NS_SUCCEEDED(rv)) {
     975               0 :         rv = in->Init(file, offset, length, ioFlags, perm, behaviorFlags);
     976               0 :         if (NS_SUCCEEDED(rv))
     977               0 :             rv = CallQueryInterface(in, result);
     978                 :     }
     979               0 :     return rv;
     980                 : }
     981                 : 
     982                 : inline nsresult
     983             979 : NS_NewLocalFileOutputStream(nsIOutputStream **result,
     984                 :                             nsIFile          *file,
     985                 :                             PRInt32           ioFlags       = -1,
     986                 :                             PRInt32           perm          = -1,
     987                 :                             PRInt32           behaviorFlags = 0)
     988                 : {
     989                 :     nsresult rv;
     990                 :     nsCOMPtr<nsIFileOutputStream> out =
     991            1958 :         do_CreateInstance(NS_LOCALFILEOUTPUTSTREAM_CONTRACTID, &rv);
     992             979 :     if (NS_SUCCEEDED(rv)) {
     993             979 :         rv = out->Init(file, ioFlags, perm, behaviorFlags);
     994             979 :         if (NS_SUCCEEDED(rv))
     995             976 :             NS_ADDREF(*result = out);  // cannot use nsCOMPtr::swap
     996                 :     }
     997             979 :     return rv;
     998                 : }
     999                 : 
    1000                 : // returns a file output stream which can be QI'ed to nsISafeOutputStream.
    1001                 : inline nsresult
    1002              32 : NS_NewSafeLocalFileOutputStream(nsIOutputStream **result,
    1003                 :                                 nsIFile          *file,
    1004                 :                                 PRInt32           ioFlags       = -1,
    1005                 :                                 PRInt32           perm          = -1,
    1006                 :                                 PRInt32           behaviorFlags = 0)
    1007                 : {
    1008                 :     nsresult rv;
    1009                 :     nsCOMPtr<nsIFileOutputStream> out =
    1010              64 :         do_CreateInstance(NS_SAFELOCALFILEOUTPUTSTREAM_CONTRACTID, &rv);
    1011              32 :     if (NS_SUCCEEDED(rv)) {
    1012              32 :         rv = out->Init(file, ioFlags, perm, behaviorFlags);
    1013              32 :         if (NS_SUCCEEDED(rv))
    1014              32 :             NS_ADDREF(*result = out);  // cannot use nsCOMPtr::swap
    1015                 :     }
    1016              32 :     return rv;
    1017                 : }
    1018                 : 
    1019                 : // returns the input end of a pipe.  the output end of the pipe
    1020                 : // is attached to the original stream.  data from the original
    1021                 : // stream is read into the pipe on a background thread.
    1022                 : inline nsresult
    1023                 : NS_BackgroundInputStream(nsIInputStream **result,
    1024                 :                          nsIInputStream  *stream,
    1025                 :                          PRUint32         segmentSize  = 0,
    1026                 :                          PRUint32         segmentCount = 0)
    1027                 : {
    1028                 :     nsresult rv;
    1029                 :     nsCOMPtr<nsIStreamTransportService> sts =
    1030                 :         do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
    1031                 :     if (NS_SUCCEEDED(rv)) {
    1032                 :         nsCOMPtr<nsITransport> inTransport;
    1033                 :         rv = sts->CreateInputTransport(stream, PRInt64(-1), PRInt64(-1),
    1034                 :                                        true, getter_AddRefs(inTransport));
    1035                 :         if (NS_SUCCEEDED(rv))
    1036                 :             rv = inTransport->OpenInputStream(nsITransport::OPEN_BLOCKING,
    1037                 :                                               segmentSize, segmentCount,
    1038                 :                                               result);
    1039                 :     }
    1040                 :     return rv;
    1041                 : }
    1042                 : 
    1043                 : // returns the output end of a pipe.  the input end of the pipe
    1044                 : // is attached to the original stream.  data written to the pipe
    1045                 : // is copied to the original stream on a background thread.
    1046                 : inline nsresult
    1047                 : NS_BackgroundOutputStream(nsIOutputStream **result,
    1048                 :                           nsIOutputStream  *stream,
    1049                 :                           PRUint32          segmentSize  = 0,
    1050                 :                           PRUint32          segmentCount = 0)
    1051                 : {
    1052                 :     nsresult rv;
    1053                 :     nsCOMPtr<nsIStreamTransportService> sts =
    1054                 :         do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
    1055                 :     if (NS_SUCCEEDED(rv)) {
    1056                 :         nsCOMPtr<nsITransport> inTransport;
    1057                 :         rv = sts->CreateOutputTransport(stream, PRInt64(-1), PRInt64(-1),
    1058                 :                                         true, getter_AddRefs(inTransport));
    1059                 :         if (NS_SUCCEEDED(rv))
    1060                 :             rv = inTransport->OpenOutputStream(nsITransport::OPEN_BLOCKING,
    1061                 :                                                segmentSize, segmentCount,
    1062                 :                                                result);
    1063                 :     }
    1064                 :     return rv;
    1065                 : }
    1066                 : 
    1067                 : inline nsresult
    1068             943 : NS_NewBufferedInputStream(nsIInputStream **result,
    1069                 :                           nsIInputStream  *str,
    1070                 :                           PRUint32         bufferSize)
    1071                 : {
    1072                 :     nsresult rv;
    1073                 :     nsCOMPtr<nsIBufferedInputStream> in =
    1074            1886 :         do_CreateInstance(NS_BUFFEREDINPUTSTREAM_CONTRACTID, &rv);
    1075             943 :     if (NS_SUCCEEDED(rv)) {
    1076             943 :         rv = in->Init(str, bufferSize);
    1077             943 :         if (NS_SUCCEEDED(rv))
    1078             943 :             NS_ADDREF(*result = in);  // cannot use nsCOMPtr::swap
    1079                 :     }
    1080             943 :     return rv;
    1081                 : }
    1082                 : 
    1083                 : // note: the resulting stream can be QI'ed to nsISafeOutputStream iff the
    1084                 : // provided stream supports it.
    1085                 : inline nsresult
    1086            1058 : NS_NewBufferedOutputStream(nsIOutputStream **result,
    1087                 :                            nsIOutputStream  *str,
    1088                 :                            PRUint32          bufferSize)
    1089                 : {
    1090                 :     nsresult rv;
    1091                 :     nsCOMPtr<nsIBufferedOutputStream> out =
    1092            2116 :         do_CreateInstance(NS_BUFFEREDOUTPUTSTREAM_CONTRACTID, &rv);
    1093            1058 :     if (NS_SUCCEEDED(rv)) {
    1094            1058 :         rv = out->Init(str, bufferSize);
    1095            1058 :         if (NS_SUCCEEDED(rv))
    1096            1058 :             NS_ADDREF(*result = out);  // cannot use nsCOMPtr::swap
    1097                 :     }
    1098            1058 :     return rv;
    1099                 : }
    1100                 : 
    1101                 : /**
    1102                 :  * Attempts to buffer a given output stream.  If this fails, it returns the
    1103                 :  * passed-in output stream.
    1104                 :  *
    1105                 :  * @param aOutputStream
    1106                 :  *        The output stream we want to buffer.  This cannot be null.
    1107                 :  * @param aBufferSize
    1108                 :  *        The size of the buffer for the buffered output stream.
    1109                 :  * @returns an nsIOutputStream that is buffered with the specified buffer size,
    1110                 :  *          or is aOutputStream if creating the new buffered stream failed.
    1111                 :  */
    1112                 : inline already_AddRefed<nsIOutputStream>
    1113              26 : NS_BufferOutputStream(nsIOutputStream *aOutputStream,
    1114                 :                       PRUint32 aBufferSize)
    1115                 : {
    1116              26 :     NS_ASSERTION(aOutputStream, "No output stream given!");
    1117                 : 
    1118              52 :     nsCOMPtr<nsIOutputStream> bos;
    1119              26 :     nsresult rv = NS_NewBufferedOutputStream(getter_AddRefs(bos), aOutputStream,
    1120              26 :                                              aBufferSize);
    1121              26 :     if (NS_SUCCEEDED(rv))
    1122              26 :         return bos.forget();
    1123                 : 
    1124               0 :     NS_ADDREF(aOutputStream);
    1125               0 :     return aOutputStream;
    1126                 : }
    1127                 : 
    1128                 : // returns an input stream compatible with nsIUploadChannel::SetUploadStream()
    1129                 : inline nsresult
    1130               0 : NS_NewPostDataStream(nsIInputStream  **result,
    1131                 :                      bool              isFile,
    1132                 :                      const nsACString &data,
    1133                 :                      PRUint32          encodeFlags,
    1134                 :                      nsIIOService     *unused = nsnull)
    1135                 : {
    1136                 :     nsresult rv;
    1137                 : 
    1138               0 :     if (isFile) {
    1139               0 :         nsCOMPtr<nsILocalFile> file;
    1140               0 :         nsCOMPtr<nsIInputStream> fileStream;
    1141                 : 
    1142               0 :         rv = NS_NewNativeLocalFile(data, false, getter_AddRefs(file));
    1143               0 :         if (NS_SUCCEEDED(rv)) {
    1144               0 :             rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream), file);
    1145               0 :             if (NS_SUCCEEDED(rv)) {
    1146                 :                 // wrap the file stream with a buffered input stream
    1147               0 :                 rv = NS_NewBufferedInputStream(result, fileStream, 8192);
    1148                 :             }
    1149                 :         }
    1150               0 :         return rv;
    1151                 :     }
    1152                 : 
    1153                 :     // otherwise, create a string stream for the data (copies)
    1154                 :     nsCOMPtr<nsIStringInputStream> stream
    1155               0 :         (do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv));
    1156               0 :     if (NS_FAILED(rv))
    1157               0 :         return rv;
    1158                 : 
    1159               0 :     rv = stream->SetData(data.BeginReading(), data.Length());
    1160               0 :     if (NS_FAILED(rv))
    1161               0 :         return rv;
    1162                 : 
    1163               0 :     NS_ADDREF(*result = stream);
    1164               0 :     return NS_OK;
    1165                 : }
    1166                 : 
    1167                 : inline nsresult
    1168             525 : NS_ReadInputStreamToBuffer(nsIInputStream *aInputStream, 
    1169                 :                            void** aDest,
    1170                 :                            PRUint32 aCount)
    1171                 : {
    1172                 :     nsresult rv;
    1173                 : 
    1174             525 :     if (!*aDest) {
    1175               0 :         *aDest = malloc(aCount);
    1176               0 :         if (!*aDest)
    1177               0 :             return NS_ERROR_OUT_OF_MEMORY;
    1178                 :     }
    1179                 : 
    1180             525 :     char * p = reinterpret_cast<char*>(*aDest);
    1181                 :     PRUint32 bytesRead;
    1182             525 :     PRUint32 totalRead = 0;
    1183               0 :     while (1) {
    1184             525 :         rv = aInputStream->Read(p + totalRead, aCount - totalRead, &bytesRead);
    1185             525 :         if (!NS_SUCCEEDED(rv)) 
    1186               0 :             return rv;
    1187             525 :         totalRead += bytesRead;
    1188             525 :         if (totalRead == aCount)
    1189                 :             break;
    1190                 :         // if Read reads 0 bytes, we've hit EOF 
    1191               0 :         if (bytesRead == 0)
    1192               0 :             return NS_ERROR_UNEXPECTED;
    1193                 :     }
    1194             525 :     return rv; 
    1195                 : }
    1196                 : 
    1197                 : inline nsresult
    1198             525 : NS_ReadInputStreamToString(nsIInputStream *aInputStream, 
    1199                 :                            nsACString &aDest,
    1200                 :                            PRUint32 aCount)
    1201                 : {
    1202             525 :     aDest.SetLength(aCount);
    1203             525 :     if (aDest.Length() != aCount)
    1204               0 :         return NS_ERROR_OUT_OF_MEMORY;
    1205             525 :     void* dest = aDest.BeginWriting();
    1206             525 :     return NS_ReadInputStreamToBuffer(aInputStream, &dest, aCount);
    1207                 : }
    1208                 : 
    1209                 : inline nsresult
    1210               0 : NS_LoadPersistentPropertiesFromURI(nsIPersistentProperties **result,
    1211                 :                                    nsIURI                   *uri,
    1212                 :                                    nsIIOService             *ioService = nsnull)
    1213                 : {
    1214               0 :     nsCOMPtr<nsIInputStream> in;
    1215               0 :     nsresult rv = NS_OpenURI(getter_AddRefs(in), uri, ioService);
    1216               0 :     if (NS_SUCCEEDED(rv)) {
    1217                 :         nsCOMPtr<nsIPersistentProperties> properties = 
    1218               0 :             do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID, &rv);
    1219               0 :         if (NS_SUCCEEDED(rv)) {
    1220               0 :             rv = properties->Load(in);
    1221               0 :             if (NS_SUCCEEDED(rv)) {
    1222               0 :                 *result = nsnull;
    1223               0 :                 properties.swap(*result);
    1224                 :             }
    1225                 :         }
    1226                 :     }
    1227               0 :     return rv;
    1228                 : }
    1229                 : 
    1230                 : inline nsresult
    1231               0 : NS_LoadPersistentPropertiesFromURISpec(nsIPersistentProperties **result,
    1232                 :                                        const nsACString        &spec,
    1233                 :                                        const char              *charset = nsnull,
    1234                 :                                        nsIURI                  *baseURI = nsnull,
    1235                 :                                        nsIIOService            *ioService = nsnull)     
    1236                 : {
    1237               0 :     nsCOMPtr<nsIURI> uri;
    1238                 :     nsresult rv = 
    1239               0 :         NS_NewURI(getter_AddRefs(uri), spec, charset, baseURI, ioService);
    1240                 : 
    1241               0 :     if (NS_SUCCEEDED(rv))
    1242               0 :         rv = NS_LoadPersistentPropertiesFromURI(result, uri, ioService);
    1243                 : 
    1244               0 :     return rv;
    1245                 : }
    1246                 : 
    1247                 : /**
    1248                 :  * NS_QueryNotificationCallbacks implements the canonical algorithm for
    1249                 :  * querying interfaces from a channel's notification callbacks.  It first
    1250                 :  * searches the channel's notificationCallbacks attribute, and if the interface
    1251                 :  * is not found there, then it inspects the notificationCallbacks attribute of
    1252                 :  * the channel's loadGroup.
    1253                 :  */
    1254                 : inline void
    1255             311 : NS_QueryNotificationCallbacks(nsIChannel   *channel,
    1256                 :                               const nsIID  &iid,
    1257                 :                               void        **result)
    1258                 : {
    1259             311 :     NS_PRECONDITION(channel, "null channel");
    1260             311 :     *result = nsnull;
    1261                 : 
    1262             622 :     nsCOMPtr<nsIInterfaceRequestor> cbs;
    1263             311 :     channel->GetNotificationCallbacks(getter_AddRefs(cbs));
    1264             311 :     if (cbs)
    1265             124 :         cbs->GetInterface(iid, result);
    1266             311 :     if (!*result) {
    1267                 :         // try load group's notification callbacks...
    1268             498 :         nsCOMPtr<nsILoadGroup> loadGroup;
    1269             249 :         channel->GetLoadGroup(getter_AddRefs(loadGroup));
    1270             249 :         if (loadGroup) {
    1271               0 :             loadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
    1272               0 :             if (cbs)
    1273               0 :                 cbs->GetInterface(iid, result);
    1274                 :         }
    1275                 :     }
    1276             311 : }
    1277                 : 
    1278                 : /* template helper */
    1279                 : template <class T> inline void
    1280             156 : NS_QueryNotificationCallbacks(nsIChannel  *channel,
    1281                 :                               nsCOMPtr<T> &result)
    1282                 : {
    1283             156 :     NS_QueryNotificationCallbacks(channel, NS_GET_TEMPLATE_IID(T),
    1284                 :                                   getter_AddRefs(result));
    1285             156 : }
    1286                 : 
    1287                 : /**
    1288                 :  * Alternate form of NS_QueryNotificationCallbacks designed for use by
    1289                 :  * nsIChannel implementations.
    1290                 :  */
    1291                 : inline void
    1292            7995 : NS_QueryNotificationCallbacks(nsIInterfaceRequestor  *callbacks,
    1293                 :                               nsILoadGroup           *loadGroup,
    1294                 :                               const nsIID            &iid,
    1295                 :                               void                  **result)
    1296                 : {
    1297            7995 :     *result = nsnull;
    1298                 : 
    1299            7995 :     if (callbacks)
    1300            5610 :         callbacks->GetInterface(iid, result);
    1301            7995 :     if (!*result) {
    1302                 :         // try load group's notification callbacks...
    1303            7313 :         if (loadGroup) {
    1304              52 :             nsCOMPtr<nsIInterfaceRequestor> cbs;
    1305              26 :             loadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
    1306              26 :             if (cbs)
    1307               0 :                 cbs->GetInterface(iid, result);
    1308                 :         }
    1309                 :     }
    1310            7995 : }
    1311                 : 
    1312                 : /**
    1313                 :  * Wraps an nsIAuthPrompt so that it can be used as an nsIAuthPrompt2. This
    1314                 :  * method is provided mainly for use by other methods in this file.
    1315                 :  *
    1316                 :  * *aAuthPrompt2 should be set to null before calling this function.
    1317                 :  */
    1318                 : inline void
    1319               4 : NS_WrapAuthPrompt(nsIAuthPrompt *aAuthPrompt, nsIAuthPrompt2** aAuthPrompt2)
    1320                 : {
    1321                 :     nsCOMPtr<nsIAuthPromptAdapterFactory> factory =
    1322               8 :         do_GetService(NS_AUTHPROMPT_ADAPTER_FACTORY_CONTRACTID);
    1323               4 :     if (!factory)
    1324                 :         return;
    1325                 : 
    1326               4 :     NS_WARNING("Using deprecated nsIAuthPrompt");
    1327               4 :     factory->CreateAdapter(aAuthPrompt, aAuthPrompt2);
    1328                 : }
    1329                 : 
    1330                 : /**
    1331                 :  * Gets an auth prompt from an interface requestor. This takes care of wrapping
    1332                 :  * an nsIAuthPrompt so that it can be used as an nsIAuthPrompt2.
    1333                 :  */
    1334                 : inline void
    1335              37 : NS_QueryAuthPrompt2(nsIInterfaceRequestor  *aCallbacks,
    1336                 :                     nsIAuthPrompt2        **aAuthPrompt)
    1337                 : {
    1338              37 :     CallGetInterface(aCallbacks, aAuthPrompt);
    1339              37 :     if (*aAuthPrompt)
    1340              26 :         return;
    1341                 : 
    1342                 :     // Maybe only nsIAuthPrompt is provided and we have to wrap it.
    1343              22 :     nsCOMPtr<nsIAuthPrompt> prompt(do_GetInterface(aCallbacks));
    1344              11 :     if (!prompt)
    1345                 :         return;
    1346                 : 
    1347               4 :     NS_WrapAuthPrompt(prompt, aAuthPrompt);
    1348                 : }
    1349                 : 
    1350                 : /**
    1351                 :  * Gets an nsIAuthPrompt2 from a channel. Use this instead of
    1352                 :  * NS_QueryNotificationCallbacks for better backwards compatibility.
    1353                 :  */
    1354                 : inline void
    1355               0 : NS_QueryAuthPrompt2(nsIChannel      *aChannel,
    1356                 :                     nsIAuthPrompt2 **aAuthPrompt)
    1357                 : {
    1358               0 :     *aAuthPrompt = nsnull;
    1359                 : 
    1360                 :     // We want to use any auth prompt we can find on the channel's callbacks,
    1361                 :     // and if that fails use the loadgroup's prompt (if any)
    1362                 :     // Therefore, we can't just use NS_QueryNotificationCallbacks, because
    1363                 :     // that would prefer a loadgroup's nsIAuthPrompt2 over a channel's
    1364                 :     // nsIAuthPrompt.
    1365               0 :     nsCOMPtr<nsIInterfaceRequestor> callbacks;
    1366               0 :     aChannel->GetNotificationCallbacks(getter_AddRefs(callbacks));
    1367               0 :     if (callbacks) {
    1368               0 :         NS_QueryAuthPrompt2(callbacks, aAuthPrompt);
    1369               0 :         if (*aAuthPrompt)
    1370                 :             return;
    1371                 :     }
    1372                 : 
    1373               0 :     nsCOMPtr<nsILoadGroup> group;
    1374               0 :     aChannel->GetLoadGroup(getter_AddRefs(group));
    1375               0 :     if (!group)
    1376                 :         return;
    1377                 : 
    1378               0 :     group->GetNotificationCallbacks(getter_AddRefs(callbacks));
    1379               0 :     if (!callbacks)
    1380                 :         return;
    1381               0 :     NS_QueryAuthPrompt2(callbacks, aAuthPrompt);
    1382                 : }
    1383                 : 
    1384                 : /* template helper */
    1385                 : template <class T> inline void
    1386               1 : NS_QueryNotificationCallbacks(nsIInterfaceRequestor *callbacks,
    1387                 :                               nsILoadGroup          *loadGroup,
    1388                 :                               nsCOMPtr<T>           &result)
    1389                 : {
    1390               1 :     NS_QueryNotificationCallbacks(callbacks, loadGroup,
    1391                 :                                   NS_GET_TEMPLATE_IID(T),
    1392                 :                                   getter_AddRefs(result));
    1393               1 : }
    1394                 : 
    1395                 : /* template helper */
    1396                 : template <class T> inline void
    1397               1 : NS_QueryNotificationCallbacks(const nsCOMPtr<nsIInterfaceRequestor> &aCallbacks,
    1398                 :                               const nsCOMPtr<nsILoadGroup>          &aLoadGroup,
    1399                 :                               nsCOMPtr<T>                           &aResult)
    1400                 : {
    1401               1 :     NS_QueryNotificationCallbacks(aCallbacks.get(), aLoadGroup.get(), aResult);
    1402               1 : }
    1403                 : 
    1404                 : /* template helper */
    1405                 : template <class T> inline void
    1406             152 : NS_QueryNotificationCallbacks(const nsCOMPtr<nsIChannel> &aChannel,
    1407                 :                               nsCOMPtr<T>                &aResult)
    1408                 : {
    1409             152 :     NS_QueryNotificationCallbacks(aChannel.get(), aResult);
    1410             152 : }
    1411                 : 
    1412                 : /**
    1413                 :  * This function returns a nsIInterfaceRequestor instance that returns the
    1414                 :  * same result as NS_QueryNotificationCallbacks when queried.  It is useful
    1415                 :  * as the value for nsISocketTransport::securityCallbacks.
    1416                 :  */
    1417                 : inline nsresult
    1418            2989 : NS_NewNotificationCallbacksAggregation(nsIInterfaceRequestor  *callbacks,
    1419                 :                                        nsILoadGroup           *loadGroup,
    1420                 :                                        nsIInterfaceRequestor **result)
    1421                 : {
    1422            5978 :     nsCOMPtr<nsIInterfaceRequestor> cbs;
    1423            2989 :     if (loadGroup)
    1424               8 :         loadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
    1425            2989 :     return NS_NewInterfaceRequestorAggregation(callbacks, cbs, result);
    1426                 : }
    1427                 : 
    1428                 : /**
    1429                 :  * Helper function for testing online/offline state of the browser.
    1430                 :  */
    1431                 : inline bool
    1432              17 : NS_IsOffline()
    1433                 : {
    1434              17 :     bool offline = true;
    1435              34 :     nsCOMPtr<nsIIOService> ios = do_GetIOService();
    1436              17 :     if (ios)
    1437              17 :         ios->GetOffline(&offline);
    1438              17 :     return offline;
    1439                 : }
    1440                 : 
    1441                 : /**
    1442                 :  * Helper functions for implementing nsINestedURI::innermostURI.
    1443                 :  *
    1444                 :  * Note that NS_DoImplGetInnermostURI is "private" -- call
    1445                 :  * NS_ImplGetInnermostURI instead.
    1446                 :  */
    1447                 : inline nsresult
    1448             133 : NS_DoImplGetInnermostURI(nsINestedURI* nestedURI, nsIURI** result)
    1449                 : {
    1450             133 :     NS_PRECONDITION(nestedURI, "Must have a nested URI!");
    1451             133 :     NS_PRECONDITION(!*result, "Must have null *result");
    1452                 :     
    1453             266 :     nsCOMPtr<nsIURI> inner;
    1454             133 :     nsresult rv = nestedURI->GetInnerURI(getter_AddRefs(inner));
    1455             133 :     NS_ENSURE_SUCCESS(rv, rv);
    1456                 : 
    1457                 :     // We may need to loop here until we reach the innermost
    1458                 :     // URI.
    1459             266 :     nsCOMPtr<nsINestedURI> nestedInner(do_QueryInterface(inner));
    1460             267 :     while (nestedInner) {
    1461               1 :         rv = nestedInner->GetInnerURI(getter_AddRefs(inner));
    1462               1 :         NS_ENSURE_SUCCESS(rv, rv);
    1463               1 :         nestedInner = do_QueryInterface(inner);
    1464                 :     }
    1465                 : 
    1466                 :     // Found the innermost one if we reach here.
    1467             133 :     inner.swap(*result);
    1468                 : 
    1469             133 :     return rv;
    1470                 : }
    1471                 : 
    1472                 : inline nsresult
    1473             133 : NS_ImplGetInnermostURI(nsINestedURI* nestedURI, nsIURI** result)
    1474                 : {
    1475                 :     // Make it safe to use swap()
    1476             133 :     *result = nsnull;
    1477                 : 
    1478             133 :     return NS_DoImplGetInnermostURI(nestedURI, result);
    1479                 : }
    1480                 : 
    1481                 : /**
    1482                 :  * Helper function that ensures that |result| is a URI that's safe to
    1483                 :  * return.  If |uri| is immutable, just returns it, otherwise returns
    1484                 :  * a clone.  |uri| must not be null.
    1485                 :  */
    1486                 : inline nsresult
    1487            7844 : NS_EnsureSafeToReturn(nsIURI* uri, nsIURI** result)
    1488                 : {
    1489            7844 :     NS_PRECONDITION(uri, "Must have a URI");
    1490                 :     
    1491                 :     // Assume mutable until told otherwise
    1492            7844 :     bool isMutable = true;
    1493           15688 :     nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(uri));
    1494            7844 :     if (mutableObj) {
    1495            2543 :         nsresult rv = mutableObj->GetMutable(&isMutable);
    1496            2543 :         isMutable = NS_FAILED(rv) || isMutable;
    1497                 :     }
    1498                 : 
    1499            7844 :     if (!isMutable) {
    1500            1875 :         NS_ADDREF(*result = uri);
    1501            1875 :         return NS_OK;
    1502                 :     }
    1503                 : 
    1504            5969 :     nsresult rv = uri->Clone(result);
    1505            5969 :     if (NS_SUCCEEDED(rv) && !*result) {
    1506               0 :         NS_ERROR("nsIURI.clone contract was violated");
    1507               0 :         return NS_ERROR_UNEXPECTED;
    1508                 :     }
    1509                 : 
    1510            5969 :     return rv;
    1511                 : }
    1512                 : 
    1513                 : /**
    1514                 :  * Helper function that tries to set the argument URI to be immutable
    1515                 :  */  
    1516                 : inline void
    1517            5880 : NS_TryToSetImmutable(nsIURI* uri)
    1518                 : {
    1519           11760 :     nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(uri));
    1520            5880 :     if (mutableObj) {
    1521            5260 :         mutableObj->SetMutable(false);
    1522                 :     }
    1523            5880 : }
    1524                 : 
    1525                 : /**
    1526                 :  * Helper function for calling ToImmutableURI.  If all else fails, returns
    1527                 :  * the input URI.  The optional second arg indicates whether we had to fall
    1528                 :  * back to the input URI.  Passing in a null URI is ok.
    1529                 :  */
    1530                 : inline already_AddRefed<nsIURI>
    1531            2184 : NS_TryToMakeImmutable(nsIURI* uri,
    1532                 :                       nsresult* outRv = nsnull)
    1533                 : {
    1534                 :     nsresult rv;
    1535            4368 :     nsCOMPtr<nsINetUtil> util = do_GetNetUtil(&rv);
    1536                 : 
    1537            2184 :     nsIURI* result = nsnull;
    1538            2184 :     if (NS_SUCCEEDED(rv)) {
    1539            2184 :         NS_ASSERTION(util, "do_GetNetUtil lied");
    1540            2184 :         rv = util->ToImmutableURI(uri, &result);
    1541                 :     }
    1542                 : 
    1543            2184 :     if (NS_FAILED(rv)) {
    1544               0 :         NS_IF_ADDREF(result = uri);
    1545                 :     }
    1546                 : 
    1547            2184 :     if (outRv) {
    1548               0 :         *outRv = rv;
    1549                 :     }
    1550                 : 
    1551            2184 :     return result;
    1552                 : }
    1553                 : 
    1554                 : /**
    1555                 :  * Helper function for testing whether the given URI, or any of its
    1556                 :  * inner URIs, has all the given protocol flags.
    1557                 :  */
    1558                 : inline nsresult
    1559          105022 : NS_URIChainHasFlags(nsIURI   *uri,
    1560                 :                     PRUint32  flags,
    1561                 :                     bool     *result)
    1562                 : {
    1563                 :     nsresult rv;
    1564          210044 :     nsCOMPtr<nsINetUtil> util = do_GetNetUtil(&rv);
    1565          105022 :     NS_ENSURE_SUCCESS(rv, rv);
    1566                 : 
    1567          105022 :     return util->URIChainHasFlags(uri, flags, result);
    1568                 : }
    1569                 : 
    1570                 : /**
    1571                 :  * Helper function for getting the innermost URI for a given URI.  The return
    1572                 :  * value could be just the object passed in if it's not a nested URI.
    1573                 :  */
    1574                 : inline already_AddRefed<nsIURI>
    1575           67935 : NS_GetInnermostURI(nsIURI *uri)
    1576                 : {
    1577           67935 :     NS_PRECONDITION(uri, "Must have URI");
    1578                 :     
    1579          135870 :     nsCOMPtr<nsINestedURI> nestedURI(do_QueryInterface(uri));
    1580           67935 :     if (!nestedURI) {
    1581           67804 :         NS_ADDREF(uri);
    1582           67804 :         return uri;
    1583                 :     }
    1584                 : 
    1585             131 :     nsresult rv = nestedURI->GetInnermostURI(&uri);
    1586             131 :     if (NS_FAILED(rv)) {
    1587               0 :         return nsnull;
    1588                 :     }
    1589                 : 
    1590             131 :     return uri;
    1591                 : }
    1592                 : 
    1593                 : /**
    1594                 :  * Get the "final" URI for a channel.  This is either the same as GetURI or
    1595                 :  * GetOriginalURI, depending on whether this channel has
    1596                 :  * nsIChanel::LOAD_REPLACE set.  For channels without that flag set, the final
    1597                 :  * URI is the original URI, while for ones with the flag the final URI is the
    1598                 :  * channel URI.
    1599                 :  */
    1600                 : inline nsresult
    1601             634 : NS_GetFinalChannelURI(nsIChannel* channel, nsIURI** uri)
    1602                 : {
    1603             634 :     *uri = nsnull;
    1604             634 :     nsLoadFlags loadFlags = 0;
    1605             634 :     nsresult rv = channel->GetLoadFlags(&loadFlags);
    1606             634 :     NS_ENSURE_SUCCESS(rv, rv);
    1607                 :     
    1608             634 :     if (loadFlags & nsIChannel::LOAD_REPLACE) {
    1609              67 :         return channel->GetURI(uri);
    1610                 :     }
    1611                 :     
    1612             567 :     return channel->GetOriginalURI(uri);
    1613                 : }
    1614                 : 
    1615                 : // NS_SecurityHashURI must return the same hash value for any two URIs that
    1616                 : // compare equal according to NS_SecurityCompareURIs.  Unfortunately, in the
    1617                 : // case of files, it's not clear we can do anything better than returning
    1618                 : // the schemeHash, so hashing files degenerates to storing them in a list.
    1619                 : inline PRUint32
    1620            2828 : NS_SecurityHashURI(nsIURI* aURI)
    1621                 : {
    1622            5656 :     nsCOMPtr<nsIURI> baseURI = NS_GetInnermostURI(aURI);
    1623                 : 
    1624            5656 :     nsCAutoString scheme;
    1625            2828 :     PRUint32 schemeHash = 0;
    1626            2828 :     if (NS_SUCCEEDED(baseURI->GetScheme(scheme)))
    1627            2828 :         schemeHash = mozilla::HashString(scheme);
    1628                 : 
    1629                 :     // TODO figure out how to hash file:// URIs
    1630            2828 :     if (scheme.EqualsLiteral("file"))
    1631               0 :         return schemeHash; // sad face
    1632                 : 
    1633            8484 :     if (scheme.EqualsLiteral("imap") ||
    1634            2828 :         scheme.EqualsLiteral("mailbox") ||
    1635            2828 :         scheme.EqualsLiteral("news"))
    1636                 :     {
    1637               0 :         nsCAutoString spec;
    1638               0 :         PRUint32 specHash = baseURI->GetSpec(spec);
    1639               0 :         if (NS_SUCCEEDED(specHash))
    1640               0 :             specHash = mozilla::HashString(spec);
    1641               0 :         return specHash;
    1642                 :     }
    1643                 : 
    1644            5656 :     nsCAutoString host;
    1645            2828 :     PRUint32 hostHash = 0;
    1646            2828 :     if (NS_SUCCEEDED(baseURI->GetAsciiHost(host)))
    1647            2828 :         hostHash = mozilla::HashString(host);
    1648                 : 
    1649            2828 :     return mozilla::AddToHash(schemeHash, hostHash, NS_GetRealPort(baseURI));
    1650                 : }
    1651                 : 
    1652                 : inline bool
    1653              45 : NS_SecurityCompareURIs(nsIURI* aSourceURI,
    1654                 :                        nsIURI* aTargetURI,
    1655                 :                        bool aStrictFileOriginPolicy)
    1656                 : {
    1657                 :     // Note that this is not an Equals() test on purpose -- for URIs that don't
    1658                 :     // support host/port, we want equality to basically be object identity, for
    1659                 :     // security purposes.  Otherwise, for example, two javascript: URIs that
    1660                 :     // are otherwise unrelated could end up "same origin", which would be
    1661                 :     // unfortunate.
    1662              45 :     if (aSourceURI && aSourceURI == aTargetURI)
    1663                 :     {
    1664               0 :         return true;
    1665                 :     }
    1666                 : 
    1667              45 :     if (!aTargetURI || !aSourceURI)
    1668                 :     {
    1669               0 :         return false;
    1670                 :     }
    1671                 : 
    1672                 :     // If either URI is a nested URI, get the base URI
    1673              90 :     nsCOMPtr<nsIURI> sourceBaseURI = NS_GetInnermostURI(aSourceURI);
    1674              90 :     nsCOMPtr<nsIURI> targetBaseURI = NS_GetInnermostURI(aTargetURI);
    1675                 : 
    1676                 :     // If either uri is an nsIURIWithPrincipal
    1677              90 :     nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(sourceBaseURI);
    1678              45 :     if (uriPrinc) {
    1679               0 :         uriPrinc->GetPrincipalUri(getter_AddRefs(sourceBaseURI));
    1680                 :     }
    1681                 : 
    1682              45 :     uriPrinc = do_QueryInterface(targetBaseURI);
    1683              45 :     if (uriPrinc) {
    1684               0 :         uriPrinc->GetPrincipalUri(getter_AddRefs(targetBaseURI));
    1685                 :     }
    1686                 : 
    1687              45 :     if (!sourceBaseURI || !targetBaseURI)
    1688               0 :         return false;
    1689                 : 
    1690                 :     // Compare schemes
    1691              90 :     nsCAutoString targetScheme;
    1692              45 :     bool sameScheme = false;
    1693             135 :     if (NS_FAILED( targetBaseURI->GetScheme(targetScheme) ) ||
    1694              45 :         NS_FAILED( sourceBaseURI->SchemeIs(targetScheme.get(), &sameScheme) ) ||
    1695              45 :         !sameScheme)
    1696                 :     {
    1697                 :         // Not same-origin if schemes differ
    1698               5 :         return false;
    1699                 :     }
    1700                 : 
    1701                 :     // special handling for file: URIs
    1702              40 :     if (targetScheme.EqualsLiteral("file"))
    1703                 :     {
    1704                 :         // in traditional unsafe behavior all files are the same origin
    1705               0 :         if (!aStrictFileOriginPolicy)
    1706               0 :             return true;
    1707                 : 
    1708               0 :         nsCOMPtr<nsIFileURL> sourceFileURL(do_QueryInterface(sourceBaseURI));
    1709               0 :         nsCOMPtr<nsIFileURL> targetFileURL(do_QueryInterface(targetBaseURI));
    1710                 : 
    1711               0 :         if (!sourceFileURL || !targetFileURL)
    1712               0 :             return false;
    1713                 : 
    1714               0 :         nsCOMPtr<nsIFile> sourceFile, targetFile;
    1715                 : 
    1716               0 :         sourceFileURL->GetFile(getter_AddRefs(sourceFile));
    1717               0 :         targetFileURL->GetFile(getter_AddRefs(targetFile));
    1718                 : 
    1719               0 :         if (!sourceFile || !targetFile)
    1720               0 :             return false;
    1721                 : 
    1722                 :         // Otherwise they had better match
    1723               0 :         bool filesAreEqual = false;
    1724               0 :         nsresult rv = sourceFile->Equals(targetFile, &filesAreEqual);
    1725               0 :         return NS_SUCCEEDED(rv) && filesAreEqual;
    1726                 :     }
    1727                 : 
    1728                 :     // Special handling for mailnews schemes
    1729             120 :     if (targetScheme.EqualsLiteral("imap") ||
    1730              40 :         targetScheme.EqualsLiteral("mailbox") ||
    1731              40 :         targetScheme.EqualsLiteral("news"))
    1732                 :     {
    1733                 :         // Each message is a distinct trust domain; use the
    1734                 :         // whole spec for comparison
    1735               0 :         nsCAutoString targetSpec;
    1736               0 :         nsCAutoString sourceSpec;
    1737               0 :         return ( NS_SUCCEEDED( targetBaseURI->GetSpec(targetSpec) ) &&
    1738               0 :                  NS_SUCCEEDED( sourceBaseURI->GetSpec(sourceSpec) ) &&
    1739               0 :                  targetSpec.Equals(sourceSpec) );
    1740                 :     }
    1741                 : 
    1742                 :     // Compare hosts
    1743              80 :     nsCAutoString targetHost;
    1744              80 :     nsCAutoString sourceHost;
    1745              80 :     if (NS_FAILED( targetBaseURI->GetAsciiHost(targetHost) ) ||
    1746              40 :         NS_FAILED( sourceBaseURI->GetAsciiHost(sourceHost) ))
    1747                 :     {
    1748               0 :         return false;
    1749                 :     }
    1750                 : 
    1751              80 :     nsCOMPtr<nsIStandardURL> targetURL(do_QueryInterface(targetBaseURI));
    1752              80 :     nsCOMPtr<nsIStandardURL> sourceURL(do_QueryInterface(sourceBaseURI));
    1753              40 :     if (!targetURL || !sourceURL)
    1754                 :     {
    1755               4 :         return false;
    1756                 :     }
    1757                 : 
    1758                 : #ifdef MOZILLA_INTERNAL_API
    1759              36 :     if (!targetHost.Equals(sourceHost, nsCaseInsensitiveCStringComparator() ))
    1760                 : #else
    1761                 :     if (!targetHost.Equals(sourceHost, CaseInsensitiveCompare))
    1762                 : #endif
    1763                 :     {
    1764               3 :         return false;
    1765                 :     }
    1766                 : 
    1767              33 :     return NS_GetRealPort(targetBaseURI) == NS_GetRealPort(sourceBaseURI);
    1768                 : }
    1769                 : 
    1770                 : inline bool
    1771              35 : NS_IsInternalSameURIRedirect(nsIChannel *aOldChannel,
    1772                 :                              nsIChannel *aNewChannel,
    1773                 :                              PRUint32 aFlags)
    1774                 : {
    1775              35 :   if (!(aFlags & nsIChannelEventSink::REDIRECT_INTERNAL)) {
    1776              35 :     return false;
    1777                 :   }
    1778                 : 
    1779               0 :   nsCOMPtr<nsIURI> oldURI, newURI;
    1780               0 :   aOldChannel->GetURI(getter_AddRefs(oldURI));
    1781               0 :   aNewChannel->GetURI(getter_AddRefs(newURI));
    1782                 : 
    1783               0 :   if (!oldURI || !newURI) {
    1784               0 :     return false;
    1785                 :   }
    1786                 : 
    1787                 :   bool res;
    1788               0 :   return NS_SUCCEEDED(oldURI->Equals(newURI, &res)) && res;
    1789                 : }
    1790                 : 
    1791                 : inline nsresult
    1792               0 : NS_LinkRedirectChannels(PRUint32 channelId,
    1793                 :                         nsIParentChannel *parentChannel,
    1794                 :                         nsIChannel** _result)
    1795                 : {
    1796                 :   nsresult rv;
    1797                 : 
    1798                 :   nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
    1799               0 :       do_GetService("@mozilla.org/redirectchannelregistrar;1", &rv);
    1800               0 :   NS_ENSURE_SUCCESS(rv, rv);
    1801                 : 
    1802               0 :   return registrar->LinkChannels(channelId,
    1803                 :                                  parentChannel,
    1804               0 :                                  _result);
    1805                 : }
    1806                 : 
    1807                 : /**
    1808                 :  * Helper function to create a random URL string that's properly formed
    1809                 :  * but guaranteed to be invalid.
    1810                 :  */  
    1811                 : #define NS_FAKE_SCHEME "http://"
    1812                 : #define NS_FAKE_TLD ".invalid"
    1813                 : inline nsresult
    1814               0 : NS_MakeRandomInvalidURLString(nsCString& result)
    1815                 : {
    1816                 :   nsresult rv;
    1817                 :   nsCOMPtr<nsIUUIDGenerator> uuidgen =
    1818               0 :     do_GetService("@mozilla.org/uuid-generator;1", &rv);
    1819               0 :   NS_ENSURE_SUCCESS(rv, rv);
    1820                 : 
    1821                 :   nsID idee;
    1822               0 :   rv = uuidgen->GenerateUUIDInPlace(&idee);
    1823               0 :   NS_ENSURE_SUCCESS(rv, rv);
    1824                 : 
    1825                 :   char chars[NSID_LENGTH];
    1826               0 :   idee.ToProvidedString(chars);
    1827                 : 
    1828               0 :   result.AssignLiteral(NS_FAKE_SCHEME);
    1829                 :   // Strip off the '{' and '}' at the beginning and end of the UUID
    1830               0 :   result.Append(chars + 1, NSID_LENGTH - 3);
    1831               0 :   result.AppendLiteral(NS_FAKE_TLD);
    1832                 : 
    1833               0 :   return NS_OK;
    1834                 : }
    1835                 : #undef NS_FAKE_SCHEME
    1836                 : #undef NS_FAKE_TLD
    1837                 : 
    1838                 : /**
    1839                 :  * Helper function to determine whether urlString is Java-compatible --
    1840                 :  * whether it can be passed to the Java URL(String) constructor without the
    1841                 :  * latter throwing a MalformedURLException, or without Java otherwise
    1842                 :  * mishandling it.  This function (in effect) implements a scheme whitelist
    1843                 :  * for Java.
    1844                 :  */  
    1845                 : inline nsresult
    1846               0 : NS_CheckIsJavaCompatibleURLString(nsCString& urlString, bool *result)
    1847                 : {
    1848               0 :   *result = false; // Default to "no"
    1849                 : 
    1850               0 :   nsresult rv = NS_OK;
    1851                 :   nsCOMPtr<nsIURLParser> urlParser =
    1852               0 :     do_GetService(NS_STDURLPARSER_CONTRACTID, &rv);
    1853               0 :   if (NS_FAILED(rv) || !urlParser)
    1854               0 :     return NS_ERROR_FAILURE;
    1855                 : 
    1856               0 :   bool compatible = true;
    1857               0 :   PRUint32 schemePos = 0;
    1858               0 :   PRInt32 schemeLen = 0;
    1859               0 :   urlParser->ParseURL(urlString.get(), -1, &schemePos, &schemeLen,
    1860               0 :                       nsnull, nsnull, nsnull, nsnull);
    1861               0 :   if (schemeLen != -1) {
    1862               0 :     nsCString scheme;
    1863               0 :     scheme.Assign(urlString.get() + schemePos, schemeLen);
    1864                 :     // By default Java only understands a small number of URL schemes, and of
    1865                 :     // these only some can legitimately represent a browser page's "origin"
    1866                 :     // (and be something we can legitimately expect Java to handle ... or not
    1867                 :     // to mishandle).
    1868                 :     //
    1869                 :     // Besides those listed below, the OJI plugin understands the "jar",
    1870                 :     // "mailto", "netdoc", "javascript" and "rmi" schemes, and Java Plugin2
    1871                 :     // also understands the "about" scheme.  We actually pass "about" URLs
    1872                 :     // to Java ("about:blank" when processing a javascript: URL (one that
    1873                 :     // calls Java) from the location bar of a blank page, and (in FF4 and up)
    1874                 :     // "about:home" when processing a javascript: URL from the home page).
    1875                 :     // And Java doesn't appear to mishandle them (for example it doesn't allow
    1876                 :     // connections to "about" URLs).  But it doesn't make any sense to do
    1877                 :     // same-origin checks on "about" URLs, so we don't include them in our
    1878                 :     // scheme whitelist.
    1879                 :     //
    1880                 :     // The OJI plugin doesn't understand "chrome" URLs (only Java Plugin2
    1881                 :     // does) -- so we mustn't pass them to the OJI plugin.  But we do need to
    1882                 :     // pass "chrome" URLs to Java Plugin2:  Java Plugin2 grants additional
    1883                 :     // privileges to chrome "origins", and some extensions take advantage of
    1884                 :     // this.  For more information see bug 620773.
    1885                 :     //
    1886                 :     // As of FF4, we no longer support the OJI plugin.
    1887               0 :     if (PL_strcasecmp(scheme.get(), "http") &&
    1888               0 :         PL_strcasecmp(scheme.get(), "https") &&
    1889               0 :         PL_strcasecmp(scheme.get(), "file") &&
    1890               0 :         PL_strcasecmp(scheme.get(), "ftp") &&
    1891               0 :         PL_strcasecmp(scheme.get(), "gopher") &&
    1892               0 :         PL_strcasecmp(scheme.get(), "chrome"))
    1893               0 :       compatible = false;
    1894                 :   } else {
    1895               0 :     compatible = false;
    1896                 :   }
    1897                 : 
    1898               0 :   *result = compatible;
    1899                 : 
    1900               0 :   return NS_OK;
    1901                 : }
    1902                 : 
    1903                 : /** Given the first (disposition) token from a Content-Disposition header,
    1904                 :  * tell whether it indicates the content is inline or attachment
    1905                 :  * @param aDispToken the disposition token from the content-disposition header
    1906                 :  */
    1907                 : inline PRUint32
    1908              17 : NS_GetContentDispositionFromToken(const nsAString& aDispToken)
    1909                 : {
    1910                 :   // RFC 2183, section 2.8 says that an unknown disposition
    1911                 :   // value should be treated as "attachment"
    1912                 :   // If all of these tests eval to false, then we have a content-disposition of
    1913                 :   // "attachment" or unknown
    1914             115 :   if (aDispToken.IsEmpty() ||
    1915              17 :       aDispToken.LowerCaseEqualsLiteral("inline") ||
    1916                 :       // Broken sites just send
    1917                 :       // Content-Disposition: filename="file"
    1918                 :       // without a disposition token... screen those out.
    1919              49 :       StringHead(aDispToken, 8).LowerCaseEqualsLiteral("filename") ||
    1920                 :       // Also in use is Content-Disposition: name="file"
    1921              49 :       StringHead(aDispToken, 4).LowerCaseEqualsLiteral("name"))
    1922               1 :     return nsIChannel::DISPOSITION_INLINE;
    1923                 : 
    1924              16 :   return nsIChannel::DISPOSITION_ATTACHMENT;
    1925                 : }
    1926                 : 
    1927                 : /** Determine the disposition (inline/attachment) of the content based on the
    1928                 :  * Content-Disposition header
    1929                 :  * @param aHeader the content-disposition header (full value)
    1930                 :  * @param aChan the channel the header came from
    1931                 :  */
    1932                 : inline PRUint32
    1933              21 : NS_GetContentDispositionFromHeader(const nsACString& aHeader, nsIChannel *aChan = nsnull)
    1934                 : {
    1935                 :   nsresult rv;
    1936              42 :   nsCOMPtr<nsIMIMEHeaderParam> mimehdrpar = do_GetService(NS_MIMEHEADERPARAM_CONTRACTID, &rv);
    1937              21 :   if (NS_FAILED(rv))
    1938               0 :     return nsIChannel::DISPOSITION_ATTACHMENT;
    1939                 : 
    1940              42 :   nsCAutoString fallbackCharset;
    1941              21 :   if (aChan) {
    1942              42 :     nsCOMPtr<nsIURI> uri;
    1943              21 :     aChan->GetURI(getter_AddRefs(uri));
    1944              21 :     if (uri)
    1945              21 :       uri->GetOriginCharset(fallbackCharset);
    1946                 :   }
    1947                 : 
    1948              42 :   nsAutoString dispToken;
    1949              21 :   rv = mimehdrpar->GetParameter(aHeader, "", fallbackCharset, true, nsnull,
    1950              21 :                                 dispToken);
    1951                 : 
    1952              21 :   if (NS_FAILED(rv)) {
    1953                 :     // special case (see bug 272541): empty disposition type handled as "inline"
    1954               4 :     if (rv == NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY)
    1955               0 :         return nsIChannel::DISPOSITION_INLINE;
    1956               4 :     return nsIChannel::DISPOSITION_ATTACHMENT;
    1957                 :   }
    1958                 : 
    1959              17 :   return NS_GetContentDispositionFromToken(dispToken);
    1960                 : }
    1961                 : 
    1962                 : /** Extracts the filename out of a content-disposition header
    1963                 :  * @param aFilename [out] The filename. Can be empty on error.
    1964                 :  * @param aDisposition Value of a Content-Disposition header
    1965                 :  * @param aURI Optional. Will be used to get a fallback charset for the
    1966                 :  *        filename, if it is QI'able to nsIURL
    1967                 :  */
    1968                 : inline nsresult
    1969              15 : NS_GetFilenameFromDisposition(nsAString& aFilename,
    1970                 :                               const nsACString& aDisposition,
    1971                 :                               nsIURI* aURI = nsnull)
    1972                 : {
    1973              15 :   aFilename.Truncate();
    1974                 : 
    1975                 :   nsresult rv;
    1976                 :   nsCOMPtr<nsIMIMEHeaderParam> mimehdrpar =
    1977              30 :       do_GetService(NS_MIMEHEADERPARAM_CONTRACTID, &rv);
    1978              15 :   if (NS_FAILED(rv))
    1979               0 :     return rv;
    1980                 : 
    1981              30 :   nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
    1982                 : 
    1983              30 :   nsCAutoString fallbackCharset;
    1984              15 :   if (url)
    1985              15 :     url->GetOriginCharset(fallbackCharset);
    1986                 :   // Get the value of 'filename' parameter
    1987              15 :   rv = mimehdrpar->GetParameter(aDisposition, "filename",
    1988                 :                                 fallbackCharset, true, nsnull,
    1989              15 :                                 aFilename);
    1990              15 :   if (NS_FAILED(rv) || aFilename.IsEmpty()) {
    1991                 :     // Try 'name' parameter, instead.
    1992               7 :     rv = mimehdrpar->GetParameter(aDisposition, "name", fallbackCharset,
    1993               7 :                                   true, nsnull, aFilename);
    1994                 :   }
    1995                 : 
    1996              15 :   if (NS_FAILED(rv)) {
    1997               7 :     aFilename.Truncate();
    1998               7 :     return rv;
    1999                 :   }
    2000                 : 
    2001               8 :   if (aFilename.IsEmpty())
    2002               0 :     return NS_ERROR_NOT_AVAILABLE;
    2003                 : 
    2004               8 :   return NS_OK;
    2005                 : }
    2006                 : 
    2007                 : /**
    2008                 :  * Make sure Personal Security Manager is initialized
    2009                 :  */
    2010                 : inline void
    2011               5 : net_EnsurePSMInit()
    2012                 : {
    2013                 :     nsCOMPtr<nsISocketProviderService> spserv =
    2014              10 :             do_GetService(NS_SOCKETPROVIDERSERVICE_CONTRACTID);
    2015               5 :     if (spserv) {
    2016              10 :         nsCOMPtr<nsISocketProvider> provider;
    2017               5 :         spserv->GetSocketProvider("ssl", getter_AddRefs(provider));
    2018                 :     }
    2019               5 : }
    2020                 : 
    2021                 : /**
    2022                 :  * Test whether a URI is "about:blank".  |uri| must not be null
    2023                 :  */
    2024                 : inline bool
    2025               0 : NS_IsAboutBlank(nsIURI *uri)
    2026                 : {
    2027                 :     // GetSpec can be expensive for some URIs, so check the scheme first.
    2028               0 :     bool isAbout = false;
    2029               0 :     if (NS_FAILED(uri->SchemeIs("about", &isAbout)) || !isAbout) {
    2030               0 :         return false;
    2031                 :     }
    2032                 : 
    2033               0 :     nsCAutoString str;
    2034               0 :     uri->GetSpec(str);
    2035               0 :     return str.EqualsLiteral("about:blank");
    2036                 : }
    2037                 : 
    2038                 : 
    2039                 : inline nsresult
    2040            3610 : NS_GenerateHostPort(const nsCString& host, PRInt32 port,
    2041                 :                     nsCString& hostLine)
    2042                 : {
    2043            3610 :     if (strchr(host.get(), ':')) {
    2044                 :         // host is an IPv6 address literal and must be encapsulated in []'s
    2045               0 :         hostLine.Assign('[');
    2046                 :         // scope id is not needed for Host header.
    2047               0 :         int scopeIdPos = host.FindChar('%');
    2048               0 :         if (scopeIdPos == -1)
    2049               0 :             hostLine.Append(host);
    2050               0 :         else if (scopeIdPos > 0)
    2051               0 :             hostLine.Append(Substring(host, 0, scopeIdPos));
    2052                 :         else
    2053               0 :           return NS_ERROR_MALFORMED_URI;
    2054               0 :         hostLine.Append(']');
    2055                 :     }
    2056                 :     else
    2057            3610 :         hostLine.Assign(host);
    2058            3610 :     if (port != -1) {
    2059            3138 :         hostLine.Append(':');
    2060            3138 :         hostLine.AppendInt(port);
    2061                 :     }
    2062            3610 :     return NS_OK;
    2063                 : }
    2064                 : 
    2065                 : #endif // !nsNetUtil_h__

Generated by: LCOV version 1.7