LCOV - code coverage report
Current view: directory - objdir/dist/include - nsNetUtil.h (source / functions) Found Hit Coverage
Test: app.info Lines: 750 499 66.5 %
Date: 2012-04-21 Functions: 91 63 69.2 %

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

Generated by: LCOV version 1.7