2007-03-22 10:30:00 -07:00
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim:set ts=4 sw=4 cindent et: */
2012-05-21 04:12:37 -07:00
/* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/. */
2007-03-22 10:30:00 -07:00
2012-12-14 15:58:45 -08:00
# include "mozilla/DebugOnly.h"
2007-03-22 10:30:00 -07:00
# include "nsIOService.h"
# include "nsIProtocolHandler.h"
# include "nsIFileProtocolHandler.h"
# include "nscore.h"
# include "nsIURI.h"
# include "prprf.h"
2013-09-21 20:04:57 -07:00
# include "nsIErrorService.h"
2007-03-22 10:30:00 -07:00
# include "netCore.h"
# include "nsIObserverService.h"
# include "nsIPrefService.h"
# include "nsXPCOM.h"
# include "nsIProxiedProtocolHandler.h"
# include "nsIProxyInfo.h"
# include "nsEscape.h"
# include "nsNetCID.h"
# include "nsCRT.h"
2009-08-23 15:48:07 -07:00
# include "nsSimpleNestedURI.h"
2007-03-22 10:30:00 -07:00
# include "nsNetUtil.h"
2009-01-21 20:15:34 -08:00
# include "nsTArray.h"
2009-11-18 15:21:13 -08:00
# include "nsIConsoleService.h"
# include "nsIUploadChannel2.h"
2010-05-11 05:44:12 -07:00
# include "nsXULAppAPI.h"
2012-09-14 13:27:46 -07:00
# include "nsIProtocolProxyCallback.h"
# include "nsICancelable.h"
2013-09-21 20:04:57 -07:00
# include "nsINetworkLinkService.h"
# include "nsPISocketTransportService.h"
# include "nsAsyncRedirectVerifyHelper.h"
# include "nsURLHelper.h"
# include "nsPIDNSService.h"
# include "nsIProtocolProxyService2.h"
# include "MainThreadUtils.h"
2014-09-19 03:34:00 -07:00
# include "nsIWidget.h"
2010-05-19 16:22:19 -07:00
2013-08-25 16:56:53 -07:00
# if defined(XP_WIN)
2007-03-22 10:30:00 -07:00
# include "nsNativeConnectionHelper.h"
# endif
2012-10-25 12:47:55 -07:00
using namespace mozilla ;
2009-01-12 21:52:00 -08:00
# define PORT_PREF_PREFIX "network.security.ports."
# define PORT_PREF(x) PORT_PREF_PREFIX x
# define AUTODIAL_PREF "network.autodial-helper.enabled"
# define MANAGE_OFFLINE_STATUS_PREF "network.manage-offline-status"
2007-03-22 10:30:00 -07:00
2012-01-09 19:43:52 -08:00
// Nb: these have been misnomers since bug 715770 removed the buffer cache.
// "network.segment.count" and "network.segment.size" would be better names,
// but the old names are still used to preserve backward compatibility.
2010-04-20 09:32:28 -07:00
# define NECKO_BUFFER_CACHE_COUNT_PREF "network.buffer.cache.count"
# define NECKO_BUFFER_CACHE_SIZE_PREF "network.buffer.cache.size"
2014-09-19 03:36:00 -07:00
# define NETWORK_NOTIFY_CHANGED_PREF "network.notify.changed"
2010-04-20 09:32:28 -07:00
2007-03-22 10:30:00 -07:00
# define MAX_RECURSION_COUNT 50
2012-07-30 07:20:58 -07:00
nsIOService * gIOService = nullptr ;
2011-09-28 23:19:26 -07:00
static bool gHasWarnedUploadChannel2 ;
2007-03-22 10:30:00 -07:00
2014-09-24 20:14:00 -07:00
// A general port blacklist. Connections to these ports will not be allowed
// unless the protocol overrides.
2007-03-22 10:30:00 -07:00
//
// TODO: I am sure that there are more ports to be added.
// This cut is based on the classic mozilla codebase
2012-08-22 08:56:38 -07:00
int16_t gBadPortList [ ] = {
2007-03-22 10:30:00 -07:00
1 , // tcpmux
7 , // echo
9 , // discard
11 , // systat
13 , // daytime
15 , // netstat
17 , // qotd
19 , // chargen
20 , // ftp-data
21 , // ftp-cntl
22 , // ssh
23 , // telnet
25 , // smtp
37 , // time
42 , // name
43 , // nicname
53 , // domain
77 , // priv-rjs
79 , // finger
87 , // ttylink
95 , // supdup
101 , // hostriame
102 , // iso-tsap
103 , // gppitnp
104 , // acr-nema
109 , // pop2
110 , // pop3
111 , // sunrpc
113 , // auth
115 , // sftp
117 , // uucp-path
119 , // nntp
123 , // NTP
135 , // loc-srv / epmap
139 , // netbios
143 , // imap2
179 , // BGP
389 , // ldap
465 , // smtp+ssl
512 , // print / exec
513 , // login
514 , // shell
515 , // printer
526 , // tempo
530 , // courier
531 , // Chat
532 , // netnews
540 , // uucp
556 , // remotefs
563 , // nntp+ssl
587 , //
601 , //
636 , // ldap+ssl
993 , // imap+ssl
995 , // pop3+ssl
2049 , // nfs
4045 , // lockd
6000 , // x11
0 , // This MUST be zero so that we can populating the array
} ;
static const char kProfileChangeNetTeardownTopic [ ] = " profile-change-net-teardown " ;
static const char kProfileChangeNetRestoreTopic [ ] = " profile-change-net-restore " ;
2011-10-18 02:46:59 -07:00
static const char kProfileDoChange [ ] = " profile-do-change " ;
2007-03-22 10:30:00 -07:00
2012-01-09 19:43:52 -08:00
// Necko buffer defaults
2012-08-22 08:56:38 -07:00
uint32_t nsIOService : : gDefaultSegmentSize = 4096 ;
uint32_t nsIOService : : gDefaultSegmentCount = 24 ;
2007-03-22 10:30:00 -07:00
////////////////////////////////////////////////////////////////////////////////
nsIOService : : nsIOService ( )
2011-10-17 07:59:28 -07:00
: mOffline ( true )
, mOfflineForProfileChange ( false )
2012-03-08 08:24:17 -08:00
, mManageOfflineStatus ( false )
2011-10-17 07:59:28 -07:00
, mSettingOffline ( false )
, mSetOfflineValue ( false )
, mShutdown ( false )
2011-10-18 02:46:59 -07:00
, mNetworkLinkServiceInitialized ( false )
2007-03-22 10:30:00 -07:00
, mChannelEventSinks ( NS_CHANNEL_EVENT_SINK_CATEGORY )
2011-10-17 07:59:28 -07:00
, mAutoDialEnabled ( false )
2014-09-19 03:36:00 -07:00
, mNetworkNotifyChanged ( true )
2007-03-22 10:30:00 -07:00
{
}
nsresult
nsIOService : : Init ( )
{
nsresult rv ;
2010-11-24 21:20:11 -08:00
// We need to get references to the DNS service so that we can shut it
2007-03-22 10:30:00 -07:00
// down later. If we wait until the nsIOService is being shut down,
// GetService will fail at that point.
2007-09-05 06:04:54 -07:00
mDNSService = do_GetService ( NS_DNSSERVICE_CONTRACTID , & rv ) ;
2007-06-10 17:01:48 -07:00
if ( NS_FAILED ( rv ) ) {
2007-03-22 10:30:00 -07:00
NS_WARNING ( " failed to get DNS service " ) ;
2007-06-10 17:01:48 -07:00
return rv ;
}
2007-03-22 10:30:00 -07:00
// XXX hack until xpidl supports error info directly (bug 13423)
2007-09-05 06:04:54 -07:00
nsCOMPtr < nsIErrorService > errorService = do_GetService ( NS_ERRORSERVICE_CONTRACTID ) ;
2007-03-22 10:30:00 -07:00
if ( errorService ) {
errorService - > RegisterErrorStringBundle ( NS_ERROR_MODULE_NETWORK , NECKO_MSGS_URL ) ;
}
else
NS_WARNING ( " failed to get error service " ) ;
// setup our bad port list stuff
for ( int i = 0 ; gBadPortList [ i ] ; i + + )
2009-02-22 17:05:28 -08:00
mRestrictedPortList . AppendElement ( gBadPortList [ i ] ) ;
2007-03-22 10:30:00 -07:00
// Further modifications to the port list come from prefs
2012-01-16 17:48:29 -08:00
nsCOMPtr < nsIPrefBranch > prefBranch ;
2007-03-22 10:30:00 -07:00
GetPrefBranch ( getter_AddRefs ( prefBranch ) ) ;
if ( prefBranch ) {
2011-10-17 07:59:28 -07:00
prefBranch - > AddObserver ( PORT_PREF_PREFIX , this , true ) ;
prefBranch - > AddObserver ( AUTODIAL_PREF , this , true ) ;
prefBranch - > AddObserver ( MANAGE_OFFLINE_STATUS_PREF , this , true ) ;
2013-03-14 08:05:54 -07:00
prefBranch - > AddObserver ( NECKO_BUFFER_CACHE_COUNT_PREF , this , true ) ;
prefBranch - > AddObserver ( NECKO_BUFFER_CACHE_SIZE_PREF , this , true ) ;
2014-09-19 03:36:00 -07:00
prefBranch - > AddObserver ( NETWORK_NOTIFY_CHANGED_PREF , this , true ) ;
2007-03-22 10:30:00 -07:00
PrefsChanged ( prefBranch ) ;
}
// Register for profile change notifications
nsCOMPtr < nsIObserverService > observerService =
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 09:59:13 -07:00
mozilla : : services : : GetObserverService ( ) ;
2007-03-22 10:30:00 -07:00
if ( observerService ) {
2011-10-17 07:59:28 -07:00
observerService - > AddObserver ( this , kProfileChangeNetTeardownTopic , true ) ;
observerService - > AddObserver ( this , kProfileChangeNetRestoreTopic , true ) ;
2011-10-18 02:46:59 -07:00
observerService - > AddObserver ( this , kProfileDoChange , true ) ;
2011-10-17 07:59:28 -07:00
observerService - > AddObserver ( this , NS_XPCOM_SHUTDOWN_OBSERVER_ID , true ) ;
observerService - > AddObserver ( this , NS_NETWORK_LINK_TOPIC , true ) ;
2014-09-19 03:34:00 -07:00
observerService - > AddObserver ( this , NS_WIDGET_WAKE_OBSERVER_TOPIC , true ) ;
2007-03-22 10:30:00 -07:00
}
else
NS_WARNING ( " failed to get observer service " ) ;
2010-05-19 16:22:19 -07:00
2007-03-22 10:30:00 -07:00
gIOService = this ;
2010-07-28 18:05:19 -07:00
2011-10-18 02:46:59 -07:00
InitializeNetworkLinkService ( ) ;
2007-03-22 10:30:00 -07:00
return NS_OK ;
}
nsIOService : : ~ nsIOService ( )
{
2012-07-30 07:20:58 -07:00
gIOService = nullptr ;
2010-11-24 21:20:11 -08:00
}
nsresult
nsIOService : : InitializeSocketTransportService ( )
{
nsresult rv = NS_OK ;
if ( ! mSocketTransportService ) {
mSocketTransportService = do_GetService ( NS_SOCKETTRANSPORTSERVICE_CONTRACTID , & rv ) ;
if ( NS_FAILED ( rv ) ) {
NS_WARNING ( " failed to get socket transport service " ) ;
}
}
if ( mSocketTransportService ) {
rv = mSocketTransportService - > Init ( ) ;
NS_ASSERTION ( NS_SUCCEEDED ( rv ) , " socket transport service init failed " ) ;
2011-05-07 01:26:58 -07:00
mSocketTransportService - > SetAutodialEnabled ( mAutoDialEnabled ) ;
2012-09-17 16:45:10 -07:00
mSocketTransportService - > SetOffline ( false ) ;
2010-11-24 21:20:11 -08:00
}
return rv ;
}
2007-03-22 10:30:00 -07:00
2011-10-18 02:46:59 -07:00
nsresult
nsIOService : : InitializeNetworkLinkService ( )
{
nsresult rv = NS_OK ;
if ( mNetworkLinkServiceInitialized )
return rv ;
if ( ! NS_IsMainThread ( ) ) {
NS_WARNING ( " Network link service should be created on main thread " ) ;
return NS_ERROR_FAILURE ;
}
// go into managed mode if we can, and chrome process
if ( XRE_GetProcessType ( ) = = GeckoProcessType_Default )
{
mNetworkLinkService = do_GetService ( NS_NETWORK_LINK_SERVICE_CONTRACTID , & rv ) ;
}
if ( mNetworkLinkService ) {
mNetworkLinkServiceInitialized = true ;
}
else {
// We can't really determine if the machine has a usable network connection,
// so let's cross our fingers!
mManageOfflineStatus = false ;
}
if ( mManageOfflineStatus )
2014-09-24 20:14:00 -07:00
OnNetworkLinkEvent ( NS_NETWORK_LINK_DATA_UNKNOWN ) ;
2011-10-18 02:46:59 -07:00
else
SetOffline ( false ) ;
return rv ;
}
2007-03-22 10:30:00 -07:00
nsIOService *
nsIOService : : GetInstance ( ) {
if ( ! gIOService ) {
gIOService = new nsIOService ( ) ;
if ( ! gIOService )
2012-07-30 07:20:58 -07:00
return nullptr ;
2007-03-22 10:30:00 -07:00
NS_ADDREF ( gIOService ) ;
nsresult rv = gIOService - > Init ( ) ;
if ( NS_FAILED ( rv ) ) {
NS_RELEASE ( gIOService ) ;
2012-07-30 07:20:58 -07:00
return nullptr ;
2007-03-22 10:30:00 -07:00
}
return gIOService ;
}
NS_ADDREF ( gIOService ) ;
return gIOService ;
}
2014-04-27 00:06:00 -07:00
NS_IMPL_ISUPPORTS ( nsIOService ,
nsIIOService ,
nsIIOService2 ,
nsINetUtil ,
nsISpeculativeConnect ,
nsIObserver ,
nsISupportsWeakReference )
2008-02-21 12:39:20 -08:00
2007-03-22 10:30:00 -07:00
////////////////////////////////////////////////////////////////////////////////
nsresult
2010-08-04 19:15:55 -07:00
nsIOService : : AsyncOnChannelRedirect ( nsIChannel * oldChan , nsIChannel * newChan ,
2012-08-22 08:56:38 -07:00
uint32_t flags ,
2010-08-04 19:15:55 -07:00
nsAsyncRedirectVerifyHelper * helper )
2007-03-22 10:30:00 -07:00
{
nsCOMPtr < nsIChannelEventSink > sink =
do_GetService ( NS_GLOBAL_CHANNELEVENTSINK_CONTRACTID ) ;
if ( sink ) {
2010-08-04 19:15:55 -07:00
nsresult rv = helper - > DelegateOnChannelRedirect ( sink , oldChan ,
newChan , flags ) ;
2007-03-22 10:30:00 -07:00
if ( NS_FAILED ( rv ) )
return rv ;
}
// Finally, our category
2013-10-10 05:48:03 -07:00
nsCOMArray < nsIChannelEventSink > entries ;
mChannelEventSinks . GetEntries ( entries ) ;
2012-08-22 08:56:38 -07:00
int32_t len = entries . Count ( ) ;
for ( int32_t i = 0 ; i < len ; + + i ) {
2010-08-04 19:15:55 -07:00
nsresult rv = helper - > DelegateOnChannelRedirect ( entries [ i ] , oldChan ,
newChan , flags ) ;
2007-03-22 10:30:00 -07:00
if ( NS_FAILED ( rv ) )
return rv ;
}
return NS_OK ;
}
nsresult
nsIOService : : CacheProtocolHandler ( const char * scheme , nsIProtocolHandler * handler )
{
for ( unsigned int i = 0 ; i < NS_N ( gScheme ) ; i + + )
{
if ( ! nsCRT : : strcasecmp ( scheme , gScheme [ i ] ) )
{
nsresult rv ;
NS_ASSERTION ( ! mWeakHandler [ i ] , " Protocol handler already cached " ) ;
// Make sure the handler supports weak references.
nsCOMPtr < nsISupportsWeakReference > factoryPtr = do_QueryInterface ( handler , & rv ) ;
if ( ! factoryPtr )
{
// Don't cache handlers that don't support weak reference as
// there is real danger of a circular reference.
# ifdef DEBUG_dp
printf ( " DEBUG: %s protcol handler doesn't support weak ref. Not cached. \n " , scheme ) ;
# endif /* DEBUG_dp */
return NS_ERROR_FAILURE ;
}
mWeakHandler [ i ] = do_GetWeakReference ( handler ) ;
return NS_OK ;
}
}
return NS_ERROR_FAILURE ;
}
nsresult
2012-08-22 08:56:38 -07:00
nsIOService : : GetCachedProtocolHandler ( const char * scheme , nsIProtocolHandler * * result , uint32_t start , uint32_t end )
2007-03-22 10:30:00 -07:00
{
2012-08-22 08:56:38 -07:00
uint32_t len = end - start - 1 ;
2007-03-22 10:30:00 -07:00
for ( unsigned int i = 0 ; i < NS_N ( gScheme ) ; i + + )
{
if ( ! mWeakHandler [ i ] )
continue ;
// handle unterminated strings
// start is inclusive, end is exclusive, len = end - start - 1
if ( end ? ( ! nsCRT : : strncasecmp ( scheme + start , gScheme [ i ] , len )
& & gScheme [ i ] [ len ] = = ' \0 ' )
: ( ! nsCRT : : strcasecmp ( scheme , gScheme [ i ] ) ) )
{
return CallQueryReferent ( mWeakHandler [ i ] . get ( ) , result ) ;
}
}
return NS_ERROR_FAILURE ;
}
NS_IMETHODIMP
nsIOService : : GetProtocolHandler ( const char * scheme , nsIProtocolHandler * * result )
{
nsresult rv ;
NS_ENSURE_ARG_POINTER ( scheme ) ;
// XXX we may want to speed this up by introducing our own protocol
// scheme -> protocol handler mapping, avoiding the string manipulation
// and service manager stuff
rv = GetCachedProtocolHandler ( scheme , result ) ;
if ( NS_SUCCEEDED ( rv ) )
return rv ;
2011-09-28 23:19:26 -07:00
bool externalProtocol = false ;
2012-01-16 17:48:29 -08:00
nsCOMPtr < nsIPrefBranch > prefBranch ;
2007-03-22 10:30:00 -07:00
GetPrefBranch ( getter_AddRefs ( prefBranch ) ) ;
if ( prefBranch ) {
2012-09-01 19:35:17 -07:00
nsAutoCString externalProtocolPref ( " network.protocol-handler.external. " ) ;
2007-03-22 10:30:00 -07:00
externalProtocolPref + = scheme ;
rv = prefBranch - > GetBoolPref ( externalProtocolPref . get ( ) , & externalProtocol ) ;
if ( NS_FAILED ( rv ) ) {
2011-10-17 07:59:28 -07:00
externalProtocol = false ;
2007-03-22 10:30:00 -07:00
}
}
if ( ! externalProtocol ) {
2012-09-01 19:35:17 -07:00
nsAutoCString contractID ( NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX ) ;
2007-03-22 10:30:00 -07:00
contractID + = scheme ;
ToLowerCase ( contractID ) ;
rv = CallGetService ( contractID . get ( ) , result ) ;
if ( NS_SUCCEEDED ( rv ) ) {
CacheProtocolHandler ( scheme , * result ) ;
return rv ;
}
# ifdef MOZ_X11
2011-03-23 20:38:03 -07:00
// check to see whether GVFS can handle this URI scheme. if it can
// create a nsIURI for the "scheme:", then we assume it has support for
// the requested protocol. otherwise, we failover to using the default
// protocol handler.
rv = CallGetService ( NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX " moz-gio " ,
result ) ;
if ( NS_SUCCEEDED ( rv ) ) {
2012-09-01 19:35:17 -07:00
nsAutoCString spec ( scheme ) ;
2011-03-23 20:38:03 -07:00
spec . Append ( ' : ' ) ;
nsIURI * uri ;
2012-07-30 07:20:58 -07:00
rv = ( * result ) - > NewURI ( spec , nullptr , nullptr , & uri ) ;
2011-03-23 20:38:03 -07:00
if ( NS_SUCCEEDED ( rv ) ) {
NS_RELEASE ( uri ) ;
return rv ;
}
NS_RELEASE ( * result ) ;
}
2007-11-08 22:13:26 -08:00
// check to see whether GnomeVFS can handle this URI scheme. if it can
// create a nsIURI for the "scheme:", then we assume it has support for
// the requested protocol. otherwise, we failover to using the default
// protocol handler.
2007-03-22 10:30:00 -07:00
2007-11-08 22:13:26 -08:00
// XXX should this be generalized into something that searches a
// category? (see bug 234714)
2007-03-22 10:30:00 -07:00
2007-11-08 22:13:26 -08:00
rv = CallGetService ( NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX " moz-gnomevfs " ,
result ) ;
2007-03-22 10:30:00 -07:00
if ( NS_SUCCEEDED ( rv ) ) {
2012-09-01 19:35:17 -07:00
nsAutoCString spec ( scheme ) ;
2007-11-08 22:13:26 -08:00
spec . Append ( ' : ' ) ;
nsIURI * uri ;
2012-07-30 07:20:58 -07:00
rv = ( * result ) - > NewURI ( spec , nullptr , nullptr , & uri ) ;
2007-11-08 22:13:26 -08:00
if ( NS_SUCCEEDED ( rv ) ) {
NS_RELEASE ( uri ) ;
return rv ;
}
2007-03-22 10:30:00 -07:00
2007-11-08 22:13:26 -08:00
NS_RELEASE ( * result ) ;
}
2007-03-22 10:30:00 -07:00
# endif
2007-11-08 22:13:26 -08:00
}
2007-03-22 10:30:00 -07:00
// Okay we don't have a protocol handler to handle this url type, so use
// the default protocol handler. This will cause urls to get dispatched
// out to the OS ('cause we can't do anything with them) when we try to
// read from a channel created by the default protocol handler.
rv = CallGetService ( NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX " default " ,
result ) ;
if ( NS_FAILED ( rv ) )
return NS_ERROR_UNKNOWN_PROTOCOL ;
return rv ;
}
NS_IMETHODIMP
nsIOService : : ExtractScheme ( const nsACString & inURI , nsACString & scheme )
{
2012-07-30 07:20:58 -07:00
return net_ExtractURLScheme ( inURI , nullptr , nullptr , & scheme ) ;
2007-03-22 10:30:00 -07:00
}
NS_IMETHODIMP
2012-08-22 08:56:38 -07:00
nsIOService : : GetProtocolFlags ( const char * scheme , uint32_t * flags )
2007-03-22 10:30:00 -07:00
{
nsCOMPtr < nsIProtocolHandler > handler ;
nsresult rv = GetProtocolHandler ( scheme , getter_AddRefs ( handler ) ) ;
if ( NS_FAILED ( rv ) ) return rv ;
rv = handler - > GetProtocolFlags ( flags ) ;
return rv ;
}
class AutoIncrement
{
public :
2014-08-05 06:20:24 -07:00
explicit AutoIncrement ( uint32_t * var ) : mVar ( var )
2007-03-22 10:30:00 -07:00
{
+ + * var ;
}
~ AutoIncrement ( )
{
- - * mVar ;
}
private :
2012-08-22 08:56:38 -07:00
uint32_t * mVar ;
2007-03-22 10:30:00 -07:00
} ;
nsresult
nsIOService : : NewURI ( const nsACString & aSpec , const char * aCharset , nsIURI * aBaseURI , nsIURI * * result )
{
NS_ASSERTION ( NS_IsMainThread ( ) , " wrong thread " ) ;
2012-08-22 08:56:38 -07:00
static uint32_t recursionCount = 0 ;
2007-03-22 10:30:00 -07:00
if ( recursionCount > = MAX_RECURSION_COUNT )
return NS_ERROR_MALFORMED_URI ;
AutoIncrement inc ( & recursionCount ) ;
2012-09-01 19:35:17 -07:00
nsAutoCString scheme ;
2007-03-22 10:30:00 -07:00
nsresult rv = ExtractScheme ( aSpec , scheme ) ;
if ( NS_FAILED ( rv ) ) {
// then aSpec is relative
if ( ! aBaseURI )
return NS_ERROR_MALFORMED_URI ;
rv = aBaseURI - > GetScheme ( scheme ) ;
if ( NS_FAILED ( rv ) ) return rv ;
}
// now get the handler for this scheme
nsCOMPtr < nsIProtocolHandler > handler ;
rv = GetProtocolHandler ( scheme . get ( ) , getter_AddRefs ( handler ) ) ;
if ( NS_FAILED ( rv ) ) return rv ;
return handler - > NewURI ( aSpec , aCharset , aBaseURI , result ) ;
}
NS_IMETHODIMP
nsIOService : : NewFileURI ( nsIFile * file , nsIURI * * result )
{
nsresult rv ;
NS_ENSURE_ARG_POINTER ( file ) ;
nsCOMPtr < nsIProtocolHandler > handler ;
rv = GetProtocolHandler ( " file " , getter_AddRefs ( handler ) ) ;
if ( NS_FAILED ( rv ) ) return rv ;
nsCOMPtr < nsIFileProtocolHandler > fileHandler ( do_QueryInterface ( handler , & rv ) ) ;
if ( NS_FAILED ( rv ) ) return rv ;
return fileHandler - > NewFileURI ( file , result ) ;
}
NS_IMETHODIMP
nsIOService : : NewChannelFromURI ( nsIURI * aURI , nsIChannel * * result )
2011-05-13 10:53:27 -07:00
{
2012-07-30 07:20:58 -07:00
return NewChannelFromURIWithProxyFlags ( aURI , nullptr , 0 , result ) ;
2011-05-13 10:53:27 -07:00
}
NS_IMETHODIMP
nsIOService : : NewChannelFromURIWithProxyFlags ( nsIURI * aURI ,
nsIURI * aProxyURI ,
2012-08-22 08:56:38 -07:00
uint32_t aProxyFlags ,
2011-05-13 10:53:27 -07:00
nsIChannel * * result )
2007-03-22 10:30:00 -07:00
{
nsresult rv ;
NS_ENSURE_ARG_POINTER ( aURI ) ;
2012-09-01 19:35:17 -07:00
nsAutoCString scheme ;
2007-03-22 10:30:00 -07:00
rv = aURI - > GetScheme ( scheme ) ;
if ( NS_FAILED ( rv ) )
return rv ;
nsCOMPtr < nsIProtocolHandler > handler ;
rv = GetProtocolHandler ( scheme . get ( ) , getter_AddRefs ( handler ) ) ;
if ( NS_FAILED ( rv ) )
return rv ;
2012-08-22 08:56:38 -07:00
uint32_t protoFlags ;
2007-03-22 10:30:00 -07:00
rv = handler - > GetProtocolFlags ( & protoFlags ) ;
if ( NS_FAILED ( rv ) )
return rv ;
2012-09-14 13:27:46 -07:00
nsCOMPtr < nsIProxiedProtocolHandler > pph = do_QueryInterface ( handler ) ;
if ( pph )
rv = pph - > NewProxiedChannel ( aURI , nullptr , aProxyFlags , aProxyURI , result ) ;
else
rv = handler - > NewChannel ( aURI , result ) ;
2014-10-03 09:59:10 -07:00
if ( NS_FAILED ( rv ) )
return rv ;
2009-11-18 15:21:13 -08:00
// Some extensions override the http protocol handler and provide their own
// implementation. The channels returned from that implementation doesn't
// seem to always implement the nsIUploadChannel2 interface, presumably
// because it's a new interface.
// Eventually we should remove this and simply require that http channels
// implement the new interface.
// See bug 529041
if ( ! gHasWarnedUploadChannel2 & & scheme . EqualsLiteral ( " http " ) ) {
nsCOMPtr < nsIUploadChannel2 > uploadChannel2 = do_QueryInterface ( * result ) ;
if ( ! uploadChannel2 ) {
nsCOMPtr < nsIConsoleService > consoleService =
do_GetService ( NS_CONSOLESERVICE_CONTRACTID ) ;
if ( consoleService ) {
consoleService - > LogStringMessage ( NS_LITERAL_STRING (
2009-11-18 16:22:25 -08:00
" Http channel implementation doesn't support nsIUploadChannel2. An extension has supplied a non-functional http protocol handler. This will break behavior and in future releases not work at all. "
) . get ( ) ) ;
2009-11-18 15:21:13 -08:00
}
2011-10-17 07:59:28 -07:00
gHasWarnedUploadChannel2 = true ;
2009-11-18 15:21:13 -08:00
}
}
return NS_OK ;
2007-03-22 10:30:00 -07:00
}
NS_IMETHODIMP
nsIOService : : NewChannel ( const nsACString & aSpec , const char * aCharset , nsIURI * aBaseURI , nsIChannel * * result )
{
nsresult rv ;
nsCOMPtr < nsIURI > uri ;
rv = NewURI ( aSpec , aCharset , aBaseURI , getter_AddRefs ( uri ) ) ;
if ( NS_FAILED ( rv ) ) return rv ;
return NewChannelFromURI ( uri , result ) ;
}
2011-09-28 23:19:26 -07:00
bool
2008-11-13 07:38:02 -08:00
nsIOService : : IsLinkUp ( )
{
2011-10-18 02:46:59 -07:00
InitializeNetworkLinkService ( ) ;
2008-11-13 07:38:02 -08:00
if ( ! mNetworkLinkService ) {
// We cannot decide, assume the link is up
2011-10-17 07:59:28 -07:00
return true ;
2008-11-13 07:38:02 -08:00
}
2011-09-28 23:19:26 -07:00
bool isLinkUp ;
2008-11-13 07:38:02 -08:00
nsresult rv ;
rv = mNetworkLinkService - > GetIsLinkUp ( & isLinkUp ) ;
if ( NS_FAILED ( rv ) ) {
2011-10-17 07:59:28 -07:00
return true ;
2008-11-13 07:38:02 -08:00
}
return isLinkUp ;
}
2007-03-22 10:30:00 -07:00
NS_IMETHODIMP
2011-09-28 23:19:26 -07:00
nsIOService : : GetOffline ( bool * offline )
2007-03-22 10:30:00 -07:00
{
* offline = mOffline ;
return NS_OK ;
}
NS_IMETHODIMP
2011-09-28 23:19:26 -07:00
nsIOService : : SetOffline ( bool offline )
2007-03-22 10:30:00 -07:00
{
2009-03-18 07:52:31 -07:00
// When someone wants to go online (!offline) after we got XPCOM shutdown
// throw ERROR_NOT_AVAILABLE to prevent return to online state.
2012-11-29 13:07:37 -08:00
if ( ( mShutdown | | mOfflineForProfileChange ) & & ! offline )
2009-03-18 07:52:31 -07:00
return NS_ERROR_NOT_AVAILABLE ;
2009-02-22 11:09:09 -08:00
// SetOffline() may re-enter while it's shutting down services.
// If that happens, save the most recent value and it will be
// processed when the first SetOffline() call is done bringing
// down the service.
mSetOfflineValue = offline ;
if ( mSettingOffline ) {
return NS_OK ;
}
2010-05-11 05:44:12 -07:00
2011-10-17 07:59:28 -07:00
mSettingOffline = true ;
2009-02-22 11:09:09 -08:00
2007-03-22 10:30:00 -07:00
nsCOMPtr < nsIObserverService > observerService =
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 09:59:13 -07:00
mozilla : : services : : GetObserverService ( ) ;
2007-03-22 10:30:00 -07:00
2010-05-11 05:44:12 -07:00
NS_ASSERTION ( observerService , " The observer service should not be null " ) ;
if ( XRE_GetProcessType ( ) = = GeckoProcessType_Default ) {
if ( observerService ) {
2012-07-30 07:20:58 -07:00
( void ) observerService - > NotifyObservers ( nullptr ,
2010-05-11 10:22:34 -07:00
NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC , offline ?
2013-12-12 17:50:01 -08:00
MOZ_UTF16 ( " true " ) :
MOZ_UTF16 ( " false " ) ) ;
2010-05-11 05:44:12 -07:00
}
}
2012-09-17 16:45:10 -07:00
nsIIOService * subject = static_cast < nsIIOService * > ( this ) ;
2009-02-22 11:09:09 -08:00
while ( mSetOfflineValue ! = mOffline ) {
offline = mSetOfflineValue ;
if ( offline & & ! mOffline ) {
NS_NAMED_LITERAL_STRING ( offlineString , NS_IOSERVICE_OFFLINE ) ;
2011-10-17 07:59:28 -07:00
mOffline = true ; // indicate we're trying to shutdown
2009-02-22 11:09:09 -08:00
2012-09-17 16:45:10 -07:00
// don't care if notifications fail
2009-02-22 11:09:09 -08:00
if ( observerService )
2012-09-17 16:45:10 -07:00
observerService - > NotifyObservers ( subject ,
2009-02-22 11:09:09 -08:00
NS_IOSERVICE_GOING_OFFLINE_TOPIC ,
offlineString . get ( ) ) ;
2012-09-17 16:45:10 -07:00
if ( mDNSService )
mDNSService - > SetOffline ( true ) ;
if ( mSocketTransportService )
mSocketTransportService - > SetOffline ( true ) ;
2009-02-22 11:09:09 -08:00
if ( observerService )
2012-09-17 16:45:10 -07:00
observerService - > NotifyObservers ( subject ,
2009-02-22 11:09:09 -08:00
NS_IOSERVICE_OFFLINE_STATUS_TOPIC ,
offlineString . get ( ) ) ;
2007-03-22 10:30:00 -07:00
}
2009-02-22 11:09:09 -08:00
else if ( ! offline & & mOffline ) {
// go online
if ( mDNSService ) {
2012-09-17 16:45:10 -07:00
mDNSService - > SetOffline ( false ) ;
2012-10-25 12:47:55 -07:00
DebugOnly < nsresult > rv = mDNSService - > Init ( ) ;
2009-02-22 11:09:09 -08:00
NS_ASSERTION ( NS_SUCCEEDED ( rv ) , " DNS service init failed " ) ;
}
2010-11-24 21:20:11 -08:00
InitializeSocketTransportService ( ) ;
2011-10-17 07:59:28 -07:00
mOffline = false ; // indicate success only AFTER we've
2009-02-22 11:09:09 -08:00
// brought up the services
// trigger a PAC reload when we come back online
if ( mProxyService )
mProxyService - > ReloadPAC ( ) ;
// don't care if notification fails
if ( observerService )
2012-09-17 16:45:10 -07:00
observerService - > NotifyObservers ( subject ,
2009-02-22 11:09:09 -08:00
NS_IOSERVICE_OFFLINE_STATUS_TOPIC ,
NS_LITERAL_STRING ( NS_IOSERVICE_ONLINE ) . get ( ) ) ;
2007-03-22 10:30:00 -07:00
}
}
2009-02-22 11:09:09 -08:00
2012-09-17 16:45:10 -07:00
// Don't notify here, as the above notifications (if used) suffice.
2012-11-29 13:07:37 -08:00
if ( ( mShutdown | | mOfflineForProfileChange ) & & mOffline ) {
2012-09-17 16:45:10 -07:00
// be sure to try and shutdown both (even if the first fails)...
// shutdown dns service first, because it has callbacks for socket transport
if ( mDNSService ) {
2012-10-25 12:47:55 -07:00
DebugOnly < nsresult > rv = mDNSService - > Shutdown ( ) ;
2012-09-17 16:45:10 -07:00
NS_ASSERTION ( NS_SUCCEEDED ( rv ) , " DNS service shutdown failed " ) ;
}
if ( mSocketTransportService ) {
2012-10-25 12:47:55 -07:00
DebugOnly < nsresult > rv = mSocketTransportService - > Shutdown ( ) ;
2012-09-17 16:45:10 -07:00
NS_ASSERTION ( NS_SUCCEEDED ( rv ) , " socket transport service shutdown failed " ) ;
}
}
2011-10-17 07:59:28 -07:00
mSettingOffline = false ;
2009-02-22 11:09:09 -08:00
2007-03-22 10:30:00 -07:00
return NS_OK ;
}
NS_IMETHODIMP
2012-08-22 08:56:38 -07:00
nsIOService : : AllowPort ( int32_t inPort , const char * scheme , bool * _retval )
2007-03-22 10:30:00 -07:00
{
2012-08-22 08:56:38 -07:00
int16_t port = inPort ;
2007-03-22 10:30:00 -07:00
if ( port = = - 1 ) {
2011-10-17 07:59:28 -07:00
* _retval = true ;
2007-03-22 10:30:00 -07:00
return NS_OK ;
}
2014-01-04 12:42:42 -08:00
if ( port = = 0 ) {
* _retval = false ;
return NS_OK ;
}
2007-03-22 10:30:00 -07:00
// first check to see if the port is in our blacklist:
2012-08-22 08:56:38 -07:00
int32_t badPortListCnt = mRestrictedPortList . Length ( ) ;
2007-03-22 10:30:00 -07:00
for ( int i = 0 ; i < badPortListCnt ; i + + )
{
2009-02-22 17:05:28 -08:00
if ( port = = mRestrictedPortList [ i ] )
2007-03-22 10:30:00 -07:00
{
2011-10-17 07:59:28 -07:00
* _retval = false ;
2007-03-22 10:30:00 -07:00
// check to see if the protocol wants to override
if ( ! scheme )
return NS_OK ;
nsCOMPtr < nsIProtocolHandler > handler ;
nsresult rv = GetProtocolHandler ( scheme , getter_AddRefs ( handler ) ) ;
if ( NS_FAILED ( rv ) ) return rv ;
// let the protocol handler decide
return handler - > AllowPort ( port , scheme , _retval ) ;
}
}
2011-10-17 07:59:28 -07:00
* _retval = true ;
2007-03-22 10:30:00 -07:00
return NS_OK ;
}
////////////////////////////////////////////////////////////////////////////////
void
nsIOService : : PrefsChanged ( nsIPrefBranch * prefs , const char * pref )
{
if ( ! prefs ) return ;
// Look for extra ports to block
if ( ! pref | | strcmp ( pref , PORT_PREF ( " banned " ) ) = = 0 )
2011-10-17 07:59:28 -07:00
ParsePortList ( prefs , PORT_PREF ( " banned " ) , false ) ;
2007-03-22 10:30:00 -07:00
// ...as well as previous blocks to remove.
if ( ! pref | | strcmp ( pref , PORT_PREF ( " banned.override " ) ) = = 0 )
2011-10-17 07:59:28 -07:00
ParsePortList ( prefs , PORT_PREF ( " banned.override " ) , true ) ;
2007-03-22 10:30:00 -07:00
if ( ! pref | | strcmp ( pref , AUTODIAL_PREF ) = = 0 ) {
2011-09-28 23:19:26 -07:00
bool enableAutodial = false ;
2007-03-22 10:30:00 -07:00
nsresult rv = prefs - > GetBoolPref ( AUTODIAL_PREF , & enableAutodial ) ;
// If pref not found, default to disabled.
2011-05-07 01:26:58 -07:00
mAutoDialEnabled = enableAutodial ;
2007-03-22 10:30:00 -07:00
if ( NS_SUCCEEDED ( rv ) ) {
if ( mSocketTransportService )
mSocketTransportService - > SetAutodialEnabled ( enableAutodial ) ;
}
}
2009-01-12 21:52:00 -08:00
if ( ! pref | | strcmp ( pref , MANAGE_OFFLINE_STATUS_PREF ) = = 0 ) {
2011-09-28 23:19:26 -07:00
bool manage ;
2013-01-14 16:29:35 -08:00
if ( mNetworkLinkServiceInitialized & &
NS_SUCCEEDED ( prefs - > GetBoolPref ( MANAGE_OFFLINE_STATUS_PREF ,
2009-01-12 21:52:00 -08:00
& manage ) ) )
SetManageOfflineStatus ( manage ) ;
}
2010-04-20 09:32:28 -07:00
if ( ! pref | | strcmp ( pref , NECKO_BUFFER_CACHE_COUNT_PREF ) = = 0 ) {
2012-08-22 08:56:38 -07:00
int32_t count ;
2010-04-20 09:32:28 -07:00
if ( NS_SUCCEEDED ( prefs - > GetIntPref ( NECKO_BUFFER_CACHE_COUNT_PREF ,
& count ) ) )
/* check for bogus values and default if we find such a value */
if ( count > 0 )
gDefaultSegmentCount = count ;
}
if ( ! pref | | strcmp ( pref , NECKO_BUFFER_CACHE_SIZE_PREF ) = = 0 ) {
2012-08-22 08:56:38 -07:00
int32_t size ;
2010-04-20 09:32:28 -07:00
if ( NS_SUCCEEDED ( prefs - > GetIntPref ( NECKO_BUFFER_CACHE_SIZE_PREF ,
& size ) ) )
/* check for bogus values and default if we find such a value
* the upper limit here is arbitrary . having a 1 mb segment size
* is pretty crazy . if you remove this , consider adding some
* integer rollover test .
*/
if ( size > 0 & & size < 1024 * 1024 )
gDefaultSegmentSize = size ;
2012-01-09 19:43:52 -08:00
NS_WARN_IF_FALSE ( ( ! ( size & ( size - 1 ) ) ) , " network segment size is not a power of 2! " ) ;
2010-04-20 09:32:28 -07:00
}
2014-09-19 03:36:00 -07:00
if ( ! pref | | strcmp ( pref , NETWORK_NOTIFY_CHANGED_PREF ) = = 0 ) {
bool allow ;
nsresult rv = prefs - > GetBoolPref ( NETWORK_NOTIFY_CHANGED_PREF , & allow ) ;
if ( NS_SUCCEEDED ( rv ) ) {
mNetworkNotifyChanged = allow ;
}
}
2007-03-22 10:30:00 -07:00
}
void
2011-09-28 23:19:26 -07:00
nsIOService : : ParsePortList ( nsIPrefBranch * prefBranch , const char * pref , bool remove )
2007-03-22 10:30:00 -07:00
{
nsXPIDLCString portList ;
// Get a pref string and chop it up into a list of ports.
prefBranch - > GetCharPref ( pref , getter_Copies ( portList ) ) ;
if ( portList ) {
2009-01-21 20:15:34 -08:00
nsTArray < nsCString > portListArray ;
ParseString ( portList , ' , ' , portListArray ) ;
2012-08-22 08:56:38 -07:00
uint32_t index ;
2009-01-21 20:15:34 -08:00
for ( index = 0 ; index < portListArray . Length ( ) ; index + + ) {
portListArray [ index ] . StripWhitespace ( ) ;
2012-08-22 08:56:38 -07:00
int32_t portBegin , portEnd ;
2007-03-22 10:30:00 -07:00
2009-01-21 20:15:34 -08:00
if ( PR_sscanf ( portListArray [ index ] . get ( ) , " %d-%d " , & portBegin , & portEnd ) = = 2 ) {
2007-03-22 10:30:00 -07:00
if ( ( portBegin < 65536 ) & & ( portEnd < 65536 ) ) {
2012-08-22 08:56:38 -07:00
int32_t curPort ;
2007-03-22 10:30:00 -07:00
if ( remove ) {
for ( curPort = portBegin ; curPort < = portEnd ; curPort + + )
2009-02-22 17:05:28 -08:00
mRestrictedPortList . RemoveElement ( curPort ) ;
2007-03-22 10:30:00 -07:00
} else {
for ( curPort = portBegin ; curPort < = portEnd ; curPort + + )
2009-02-22 17:05:28 -08:00
mRestrictedPortList . AppendElement ( curPort ) ;
2007-03-22 10:30:00 -07:00
}
}
} else {
2012-07-27 06:59:29 -07:00
nsresult aErrorCode ;
2012-08-22 08:56:38 -07:00
int32_t port = portListArray [ index ] . ToInteger ( & aErrorCode ) ;
2007-03-22 10:30:00 -07:00
if ( NS_SUCCEEDED ( aErrorCode ) & & port < 65536 ) {
if ( remove )
2009-02-22 17:05:28 -08:00
mRestrictedPortList . RemoveElement ( port ) ;
2007-03-22 10:30:00 -07:00
else
2009-02-22 17:05:28 -08:00
mRestrictedPortList . AppendElement ( port ) ;
2007-03-22 10:30:00 -07:00
}
}
}
}
}
void
2012-01-16 17:48:29 -08:00
nsIOService : : GetPrefBranch ( nsIPrefBranch * * result )
2007-03-22 10:30:00 -07:00
{
2012-07-30 07:20:58 -07:00
* result = nullptr ;
2007-03-22 10:30:00 -07:00
CallGetService ( NS_PREFSERVICE_CONTRACTID , result ) ;
}
// nsIObserver interface
NS_IMETHODIMP
nsIOService : : Observe ( nsISupports * subject ,
const char * topic ,
2014-01-04 07:02:17 -08:00
const char16_t * data )
2007-03-22 10:30:00 -07:00
{
if ( ! strcmp ( topic , NS_PREFBRANCH_PREFCHANGE_TOPIC_ID ) ) {
nsCOMPtr < nsIPrefBranch > prefBranch = do_QueryInterface ( subject ) ;
if ( prefBranch )
PrefsChanged ( prefBranch , NS_ConvertUTF16toUTF8 ( data ) . get ( ) ) ;
2014-09-19 03:34:00 -07:00
} else if ( ! strcmp ( topic , kProfileChangeNetTeardownTopic ) ) {
2007-03-22 10:30:00 -07:00
if ( ! mOffline ) {
2011-10-17 07:59:28 -07:00
mOfflineForProfileChange = true ;
2012-11-29 13:07:37 -08:00
SetOffline ( true ) ;
2007-03-22 10:30:00 -07:00
}
2014-09-19 03:34:00 -07:00
} else if ( ! strcmp ( topic , kProfileChangeNetRestoreTopic ) ) {
2007-03-22 10:30:00 -07:00
if ( mOfflineForProfileChange ) {
2011-10-17 07:59:28 -07:00
mOfflineForProfileChange = false ;
2007-03-22 10:30:00 -07:00
if ( ! mManageOfflineStatus | |
2014-09-24 20:14:00 -07:00
NS_FAILED ( OnNetworkLinkEvent ( NS_NETWORK_LINK_DATA_UNKNOWN ) ) ) {
2011-10-17 07:59:28 -07:00
SetOffline ( false ) ;
2007-03-22 10:30:00 -07:00
}
}
2014-09-19 03:34:00 -07:00
} else if ( ! strcmp ( topic , kProfileDoChange ) ) {
2011-10-18 02:46:59 -07:00
if ( data & & NS_LITERAL_STRING ( " startup " ) . Equals ( data ) ) {
// Lazy initialization of network link service (see bug 620472)
InitializeNetworkLinkService ( ) ;
// Set up the initilization flag regardless the actuall result.
// If we fail here, we will fail always on.
mNetworkLinkServiceInitialized = true ;
2013-01-14 16:29:35 -08:00
// And now reflect the preference setting
nsCOMPtr < nsIPrefBranch > prefBranch ;
GetPrefBranch ( getter_AddRefs ( prefBranch ) ) ;
PrefsChanged ( prefBranch , MANAGE_OFFLINE_STATUS_PREF ) ;
2011-10-18 02:46:59 -07:00
}
2014-09-19 03:34:00 -07:00
} else if ( ! strcmp ( topic , NS_XPCOM_SHUTDOWN_OBSERVER_ID ) ) {
2009-03-18 07:52:31 -07:00
// Remember we passed XPCOM shutdown notification to prevent any
// changes of the offline status from now. We must not allow going
// online after this point.
2011-10-17 07:59:28 -07:00
mShutdown = true ;
2009-03-18 07:52:31 -07:00
2011-10-17 07:59:28 -07:00
SetOffline ( true ) ;
2007-03-22 10:30:00 -07:00
// Break circular reference.
2012-07-30 07:20:58 -07:00
mProxyService = nullptr ;
2014-09-24 20:14:00 -07:00
} else if ( ! strcmp ( topic , NS_NETWORK_LINK_TOPIC ) ) {
2014-08-26 12:56:51 -07:00
if ( ! mOfflineForProfileChange & & mManageOfflineStatus ) {
2014-09-24 20:14:00 -07:00
OnNetworkLinkEvent ( NS_ConvertUTF16toUTF8 ( data ) . get ( ) ) ;
2007-03-22 10:30:00 -07:00
}
2014-09-19 03:34:00 -07:00
} else if ( ! strcmp ( topic , NS_WIDGET_WAKE_OBSERVER_TOPIC ) ) {
// coming back alive from sleep
nsCOMPtr < nsIObserverService > observerService =
mozilla : : services : : GetObserverService ( ) ;
NS_ASSERTION ( observerService , " The observer service should not be null " ) ;
2014-09-19 03:36:00 -07:00
if ( observerService & & mNetworkNotifyChanged ) {
2014-09-19 03:34:00 -07:00
( void ) observerService - >
NotifyObservers ( nullptr ,
NS_NETWORK_LINK_TOPIC ,
MOZ_UTF16 ( NS_NETWORK_LINK_DATA_CHANGED ) ) ;
}
2014-08-26 12:56:51 -07:00
}
2014-09-24 20:14:00 -07:00
2007-03-22 10:30:00 -07:00
return NS_OK ;
}
// nsINetUtil interface
NS_IMETHODIMP
nsIOService : : ParseContentType ( const nsACString & aTypeHeader ,
nsACString & aCharset ,
2011-09-28 23:19:26 -07:00
bool * aHadCharset ,
2007-03-22 10:30:00 -07:00
nsACString & aContentType )
{
net_ParseContentType ( aTypeHeader , aContentType , aCharset , aHadCharset ) ;
return NS_OK ;
}
NS_IMETHODIMP
nsIOService : : ProtocolHasFlags ( nsIURI * uri ,
2012-08-22 08:56:38 -07:00
uint32_t flags ,
2011-09-28 23:19:26 -07:00
bool * result )
2007-03-22 10:30:00 -07:00
{
NS_ENSURE_ARG ( uri ) ;
2011-10-17 07:59:28 -07:00
* result = false ;
2012-09-01 19:35:17 -07:00
nsAutoCString scheme ;
2007-03-22 10:30:00 -07:00
nsresult rv = uri - > GetScheme ( scheme ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
2012-08-22 08:56:38 -07:00
uint32_t protocolFlags ;
2007-03-22 10:30:00 -07:00
rv = GetProtocolFlags ( scheme . get ( ) , & protocolFlags ) ;
if ( NS_SUCCEEDED ( rv ) ) {
* result = ( protocolFlags & flags ) = = flags ;
}
return rv ;
}
NS_IMETHODIMP
nsIOService : : URIChainHasFlags ( nsIURI * uri ,
2012-08-22 08:56:38 -07:00
uint32_t flags ,
2011-09-28 23:19:26 -07:00
bool * result )
2007-03-22 10:30:00 -07:00
{
nsresult rv = ProtocolHasFlags ( uri , flags , result ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
if ( * result ) {
return rv ;
}
// Dig deeper into the chain. Note that this is not a do/while loop to
// avoid the extra addref/release on |uri| in the common (non-nested) case.
nsCOMPtr < nsINestedURI > nestedURI = do_QueryInterface ( uri ) ;
while ( nestedURI ) {
nsCOMPtr < nsIURI > innerURI ;
rv = nestedURI - > GetInnerURI ( getter_AddRefs ( innerURI ) ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
rv = ProtocolHasFlags ( innerURI , flags , result ) ;
if ( * result ) {
return rv ;
}
nestedURI = do_QueryInterface ( innerURI ) ;
}
return rv ;
}
NS_IMETHODIMP
nsIOService : : ToImmutableURI ( nsIURI * uri , nsIURI * * result )
{
if ( ! uri ) {
2012-07-30 07:20:58 -07:00
* result = nullptr ;
2007-03-22 10:30:00 -07:00
return NS_OK ;
}
nsresult rv = NS_EnsureSafeToReturn ( uri , result ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
NS_TryToSetImmutable ( * result ) ;
return NS_OK ;
}
2009-08-23 15:48:07 -07:00
NS_IMETHODIMP
nsIOService : : NewSimpleNestedURI ( nsIURI * aURI , nsIURI * * aResult )
{
NS_ENSURE_ARG ( aURI ) ;
nsCOMPtr < nsIURI > safeURI ;
nsresult rv = NS_EnsureSafeToReturn ( aURI , getter_AddRefs ( safeURI ) ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
NS_IF_ADDREF ( * aResult = new nsSimpleNestedURI ( safeURI ) ) ;
return * aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY ;
}
2007-03-22 10:30:00 -07:00
NS_IMETHODIMP
2014-09-24 20:14:00 -07:00
nsIOService : : SetManageOfflineStatus ( bool aManage )
{
2011-10-18 02:46:59 -07:00
nsresult rv = NS_OK ;
2012-03-08 08:24:17 -08:00
// SetManageOfflineStatus must throw when we fail to go from non-managed
2014-09-24 20:14:00 -07:00
// to managed. Usually because there is no link monitoring service
// available. Failure to do this switch is detected by a failure of
// OnNetworkLinkEvent(). When there is no network link available during
// call to InitializeNetworkLinkService(), application is put to offline
// mode. And when we change mMangeOfflineStatus to false on the next line
// we get stuck on being offline even though the link becomes later
// available.
2011-09-28 23:19:26 -07:00
bool wasManaged = mManageOfflineStatus ;
2007-03-22 10:30:00 -07:00
mManageOfflineStatus = aManage ;
2011-10-18 02:46:59 -07:00
2012-03-08 08:24:17 -08:00
InitializeNetworkLinkService ( ) ;
2011-10-18 02:46:59 -07:00
if ( mManageOfflineStatus & & ! wasManaged ) {
2014-09-24 20:14:00 -07:00
rv = OnNetworkLinkEvent ( NS_NETWORK_LINK_DATA_UNKNOWN ) ;
2011-10-18 02:46:59 -07:00
if ( NS_FAILED ( rv ) )
mManageOfflineStatus = false ;
}
return rv ;
2007-03-22 10:30:00 -07:00
}
NS_IMETHODIMP
2011-09-28 23:19:26 -07:00
nsIOService : : GetManageOfflineStatus ( bool * aManage ) {
2007-03-22 10:30:00 -07:00
* aManage = mManageOfflineStatus ;
return NS_OK ;
}
2014-09-24 20:14:00 -07:00
// input argument 'data' is already UTF8'ed
2007-03-22 10:30:00 -07:00
nsresult
2014-09-24 20:14:00 -07:00
nsIOService : : OnNetworkLinkEvent ( const char * data )
2007-03-22 10:30:00 -07:00
{
if ( ! mNetworkLinkService )
return NS_ERROR_FAILURE ;
2009-03-18 07:52:31 -07:00
if ( mShutdown )
return NS_ERROR_NOT_AVAILABLE ;
2014-09-24 20:14:00 -07:00
if ( mManageOfflineStatus )
return NS_OK ;
if ( ! strcmp ( data , NS_NETWORK_LINK_DATA_DOWN ) ) {
// check to make sure this won't collide with Autodial
if ( mSocketTransportService ) {
bool autodialEnabled = false ;
mSocketTransportService - > GetAutodialEnabled ( & autodialEnabled ) ;
// If autodialing-on-link-down is enabled, check if the OS auto
// dial option is set to always autodial. If so, then we are
// always up for the purposes of offline management.
if ( autodialEnabled ) {
2013-08-25 16:56:53 -07:00
# if defined(XP_WIN)
2014-09-24 20:14:00 -07:00
// On Windows, we should first check with the OS to see if
// autodial is enabled. If it is enabled then we are allowed
// to manage the offline state.
if ( nsNativeConnectionHelper : : IsAutodialEnabled ( ) ) {
return SetOffline ( false ) ;
}
2014-09-24 08:17:57 -07:00
# else
2014-09-24 20:14:00 -07:00
return SetOffline ( false ) ;
2007-03-22 10:30:00 -07:00
# endif
2014-09-24 20:14:00 -07:00
}
2007-03-22 10:30:00 -07:00
}
}
2009-11-18 07:20:45 -08:00
2011-09-28 23:19:26 -07:00
bool isUp ;
2014-09-24 20:14:00 -07:00
if ( ! strcmp ( data , NS_NETWORK_LINK_DATA_DOWN ) ) {
isUp = false ;
} else if ( ! strcmp ( data , NS_NETWORK_LINK_DATA_UP ) ) {
isUp = true ;
} else if ( ! strcmp ( data , NS_NETWORK_LINK_DATA_CHANGED ) ) {
// CHANGED events are handled by others
return NS_OK ;
} else if ( ! strcmp ( data , NS_NETWORK_LINK_DATA_UNKNOWN ) ) {
nsresult rv = mNetworkLinkService - > GetIsLinkUp ( & isUp ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
} else {
NS_WARNING ( " Unhandled network event! " ) ;
return NS_OK ;
}
2007-03-22 10:30:00 -07:00
return SetOffline ( ! isUp ) ;
}
NS_IMETHODIMP
nsIOService : : EscapeString ( const nsACString & aString ,
2012-08-22 08:56:38 -07:00
uint32_t aEscapeType ,
2007-03-22 10:30:00 -07:00
nsACString & aResult )
{
2012-03-24 01:18:09 -07:00
NS_ENSURE_ARG_MAX ( aEscapeType , 4 ) ;
2007-03-22 10:30:00 -07:00
2012-09-01 19:35:17 -07:00
nsAutoCString stringCopy ( aString ) ;
2007-03-22 10:30:00 -07:00
nsCString result ;
if ( ! NS_Escape ( stringCopy , result , ( nsEscapeMask ) aEscapeType ) )
return NS_ERROR_OUT_OF_MEMORY ;
aResult . Assign ( result ) ;
return NS_OK ;
}
2007-04-23 07:19:04 -07:00
2007-06-21 13:18:25 -07:00
NS_IMETHODIMP
nsIOService : : EscapeURL ( const nsACString & aStr ,
2012-08-22 08:56:38 -07:00
uint32_t aFlags , nsACString & aResult )
2007-04-23 07:19:04 -07:00
{
2007-06-21 13:18:25 -07:00
aResult . Truncate ( ) ;
2008-09-15 06:34:46 -07:00
NS_EscapeURL ( aStr . BeginReading ( ) , aStr . Length ( ) ,
aFlags | esc_AlwaysCopy , aResult ) ;
2007-06-21 13:18:25 -07:00
return NS_OK ;
}
2007-04-23 07:19:04 -07:00
2007-06-21 13:18:25 -07:00
NS_IMETHODIMP
nsIOService : : UnescapeString ( const nsACString & aStr ,
2012-08-22 08:56:38 -07:00
uint32_t aFlags , nsACString & aResult )
2007-06-21 13:18:25 -07:00
{
aResult . Truncate ( ) ;
2008-09-15 06:34:46 -07:00
NS_UnescapeURL ( aStr . BeginReading ( ) , aStr . Length ( ) ,
aFlags | esc_AlwaysCopy , aResult ) ;
2007-04-23 07:19:04 -07:00
return NS_OK ;
}
2007-06-21 13:18:25 -07:00
2007-12-03 13:34:44 -08:00
NS_IMETHODIMP
nsIOService : : ExtractCharsetFromContentType ( const nsACString & aTypeHeader ,
nsACString & aCharset ,
2012-08-22 08:56:38 -07:00
int32_t * aCharsetStart ,
int32_t * aCharsetEnd ,
2011-09-28 23:19:26 -07:00
bool * aHadCharset )
2007-12-03 13:34:44 -08:00
{
2012-09-01 19:35:17 -07:00
nsAutoCString ignored ;
2007-12-03 13:34:44 -08:00
net_ParseContentType ( aTypeHeader , ignored , aCharset , aHadCharset ,
aCharsetStart , aCharsetEnd ) ;
2008-02-28 20:24:32 -08:00
if ( * aHadCharset & & * aCharsetStart = = * aCharsetEnd ) {
2011-10-17 07:59:28 -07:00
* aHadCharset = false ;
2007-12-03 13:34:44 -08:00
}
return NS_OK ;
}
2012-04-25 05:54:42 -07:00
// nsISpeculativeConnect
2012-09-14 13:27:46 -07:00
class IOServiceProxyCallback MOZ_FINAL : public nsIProtocolProxyCallback
{
2014-06-24 09:36:44 -07:00
~ IOServiceProxyCallback ( ) { }
2012-09-14 13:27:46 -07:00
public :
NS_DECL_ISUPPORTS
NS_DECL_NSIPROTOCOLPROXYCALLBACK
IOServiceProxyCallback ( nsIInterfaceRequestor * aCallbacks ,
nsIOService * aIOService )
: mCallbacks ( aCallbacks )
, mIOService ( aIOService )
{ }
private :
nsRefPtr < nsIInterfaceRequestor > mCallbacks ;
nsRefPtr < nsIOService > mIOService ;
} ;
2014-04-27 00:06:00 -07:00
NS_IMPL_ISUPPORTS ( IOServiceProxyCallback , nsIProtocolProxyCallback )
2012-09-14 13:27:46 -07:00
2012-04-25 05:54:42 -07:00
NS_IMETHODIMP
2012-09-14 13:27:46 -07:00
IOServiceProxyCallback : : OnProxyAvailable ( nsICancelable * request , nsIURI * aURI ,
nsIProxyInfo * pi , nsresult status )
2012-04-25 05:54:42 -07:00
{
2012-09-14 13:27:46 -07:00
// Checking proxy status for speculative connect
nsAutoCString type ;
if ( NS_SUCCEEDED ( status ) & & pi & &
NS_SUCCEEDED ( pi - > GetType ( type ) ) & &
! type . EqualsLiteral ( " direct " ) ) {
// proxies dont do speculative connect
return NS_OK ;
}
2012-09-01 19:35:17 -07:00
nsAutoCString scheme ;
2012-04-25 05:54:42 -07:00
nsresult rv = aURI - > GetScheme ( scheme ) ;
if ( NS_FAILED ( rv ) )
return NS_OK ;
nsCOMPtr < nsIProtocolHandler > handler ;
2012-09-14 13:27:46 -07:00
rv = mIOService - > GetProtocolHandler ( scheme . get ( ) ,
getter_AddRefs ( handler ) ) ;
2012-04-25 05:54:42 -07:00
if ( NS_FAILED ( rv ) )
2012-09-14 13:27:46 -07:00
return NS_OK ;
2012-04-25 05:54:42 -07:00
nsCOMPtr < nsISpeculativeConnect > speculativeHandler =
do_QueryInterface ( handler ) ;
2012-04-27 13:18:21 -07:00
if ( ! speculativeHandler )
2012-04-25 05:54:42 -07:00
return NS_OK ;
2012-09-14 13:27:46 -07:00
speculativeHandler - > SpeculativeConnect ( aURI ,
2012-11-14 08:00:44 -08:00
mCallbacks ) ;
2012-09-14 13:27:46 -07:00
return NS_OK ;
}
NS_IMETHODIMP
nsIOService : : SpeculativeConnect ( nsIURI * aURI ,
2012-11-14 08:00:44 -08:00
nsIInterfaceRequestor * aCallbacks )
2012-09-14 13:27:46 -07:00
{
// Check for proxy information. If there is a proxy configured then a
// speculative connect should not be performed because the potential
// reward is slim with tcp peers closely located to the browser.
nsresult rv ;
nsCOMPtr < nsIProtocolProxyService > pps =
do_GetService ( NS_PROTOCOLPROXYSERVICE_CONTRACTID , & rv ) ;
if ( NS_FAILED ( rv ) )
return rv ;
nsCOMPtr < nsICancelable > cancelable ;
nsRefPtr < IOServiceProxyCallback > callback =
2012-11-14 08:00:44 -08:00
new IOServiceProxyCallback ( aCallbacks , this ) ;
2012-09-14 13:27:46 -07:00
return pps - > AsyncResolve ( aURI , 0 , callback , getter_AddRefs ( cancelable ) ) ;
2012-04-25 05:54:42 -07:00
}