2001-09-29 00:14:13 +04:00
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2006-05-02 22:54:19 +04:00
/* vim:set ts=4 sw=4 cindent et: */
2012-05-21 15:12:37 +04: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/. */
1999-06-08 01:33:30 +04:00
2016-03-19 03:11:42 +03:00
# include "mozilla/ArrayUtils.h"
2012-12-15 03:58:45 +04:00
# include "mozilla/DebugOnly.h"
1999-06-08 01:33:30 +04:00
# include "nsIOService.h"
2015-09-10 20:07:00 +03:00
# include "nsIDOMNode.h"
1999-06-08 01:33:30 +04:00
# include "nsIProtocolHandler.h"
2002-02-01 01:17:35 +03:00
# include "nsIFileProtocolHandler.h"
1999-06-08 01:33:30 +04:00
# include "nscore.h"
# include "nsIURI.h"
1999-06-08 23:04:13 +04:00
# include "prprf.h"
2013-09-22 07:04:57 +04:00
# include "nsIErrorService.h"
2001-01-17 22:51:28 +03:00
# include "netCore.h"
# include "nsIObserverService.h"
2001-10-09 02:27:14 +04:00
# include "nsIPrefService.h"
2002-09-04 03:36:13 +04:00
# include "nsXPCOM.h"
2001-09-13 06:21:05 +04:00
# include "nsIProxiedProtocolHandler.h"
# include "nsIProxyInfo.h"
2001-09-08 16:47:05 +04:00
# include "nsEscape.h"
2015-09-10 20:07:00 +03:00
# include "nsNetUtil.h"
2001-11-16 05:09:13 +03:00
# include "nsNetCID.h"
2003-01-18 05:15:14 +03:00
# include "nsCRT.h"
2015-05-29 20:41:41 +03:00
# include "nsSecCheckWrapChannel.h"
2009-08-24 02:48:07 +04:00
# include "nsSimpleNestedURI.h"
2009-01-22 07:15:34 +03:00
# include "nsTArray.h"
2009-11-19 02:21:13 +03:00
# include "nsIConsoleService.h"
# include "nsIUploadChannel2.h"
2010-05-11 16:44:12 +04:00
# include "nsXULAppAPI.h"
2016-03-19 03:11:42 +03:00
# include "nsIScriptError.h"
2014-08-23 07:05:56 +04:00
# include "nsIScriptSecurityManager.h"
2012-09-15 00:27:46 +04:00
# include "nsIProtocolProxyCallback.h"
# include "nsICancelable.h"
2013-09-22 07:04:57 +04:00
# include "nsINetworkLinkService.h"
# include "nsPISocketTransportService.h"
# include "nsAsyncRedirectVerifyHelper.h"
# include "nsURLHelper.h"
# include "nsPIDNSService.h"
# include "nsIProtocolProxyService2.h"
# include "MainThreadUtils.h"
2016-01-09 04:20:50 +03:00
# include "nsINode.h"
2014-09-19 14:34:00 +04:00
# include "nsIWidget.h"
2014-08-22 21:15:00 +04:00
# include "nsThreadUtils.h"
2014-12-12 20:05:21 +03:00
# include "mozilla/LoadInfo.h"
2014-08-22 21:15:00 +04:00
# include "mozilla/net/NeckoCommon.h"
2015-09-10 20:07:00 +03:00
# include "mozilla/Services.h"
2015-02-06 16:27:33 +03:00
# include "mozilla/Telemetry.h"
2014-10-14 01:35:51 +04:00
# include "mozilla/net/DNS.h"
2016-05-17 22:51:24 +03:00
# include "mozilla/ipc/URIUtils.h"
# include "mozilla/net/NeckoChild.h"
2014-10-14 01:35:51 +04:00
# include "CaptivePortalService.h"
2015-06-06 01:25:24 +03:00
# include "ReferrerPolicy.h"
2015-12-07 02:33:14 +03:00
# include "nsContentSecurityManager.h"
2016-03-19 03:11:42 +03:00
# include "nsContentUtils.h"
2016-06-07 16:17:42 +03:00
# include "xpcpublic.h"
2010-05-20 03:22:19 +04:00
2014-08-23 07:05:56 +04:00
# ifdef MOZ_WIDGET_GONK
# include "nsINetworkManager.h"
2015-07-29 09:14:00 +03:00
# include "nsINetworkInterface.h"
2014-08-23 07:05:56 +04:00
# endif
2016-05-19 05:02:57 +03:00
namespace mozilla {
namespace net {
2012-10-25 23:47:55 +04:00
2009-01-13 08:52:00 +03:00
# define PORT_PREF_PREFIX "network.security.ports."
# define PORT_PREF(x) PORT_PREF_PREFIX x
# define MANAGE_OFFLINE_STATUS_PREF "network.manage-offline-status"
2015-03-26 14:19:47 +03:00
# define OFFLINE_MIRRORS_CONNECTIVITY "network.offline-mirrors-connectivity"
2001-10-09 02:27:14 +04:00
2012-01-10 07:43:52 +04: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 20:32:28 +04:00
# define NECKO_BUFFER_CACHE_COUNT_PREF "network.buffer.cache.count"
# define NECKO_BUFFER_CACHE_SIZE_PREF "network.buffer.cache.size"
2014-09-19 14:36:00 +04:00
# define NETWORK_NOTIFY_CHANGED_PREF "network.notify.changed"
2014-10-14 01:35:51 +04:00
# define NETWORK_CAPTIVE_PORTAL_PREF "network.captive-portal-service.enabled"
2010-04-20 20:32:28 +04:00
2007-03-12 08:56:45 +03:00
# define MAX_RECURSION_COUNT 50
2012-07-30 18:20:58 +04:00
nsIOService * gIOService = nullptr ;
2011-09-29 10:19:26 +04:00
static bool gHasWarnedUploadChannel2 ;
2006-02-22 17:07:21 +03:00
2016-05-19 05:02:57 +03:00
static LazyLogModule gIOServiceLog ( " nsIOService " ) ;
2015-11-18 17:25:39 +03:00
# undef LOG
2016-05-19 05:02:57 +03:00
# define LOG(args) MOZ_LOG(gIOServiceLog, LogLevel::Debug, args)
2015-11-18 17:25:39 +03:00
2014-09-25 07:14:00 +04:00
// A general port blacklist. Connections to these ports will not be allowed
// unless the protocol overrides.
2001-06-06 04:10:09 +04:00
//
// TODO: I am sure that there are more ports to be added.
// This cut is based on the classic mozilla codebase
2016-03-30 06:04:00 +03:00
int16_t gBadPortList [ ] = {
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
2001-06-06 04:10:09 +04:00
101 , // hostriame
2016-03-30 06:04:00 +03:00
102 , // iso-tsap
103 , // gppitnp
104 , // acr-nema
109 , // pop2
110 , // pop3
111 , // sunrpc
113 , // auth
115 , // sftp
2001-06-06 04:10:09 +04:00
117 , // uucp-path
2016-03-30 06:04:00 +03:00
119 , // nntp
2001-06-06 04:10:09 +04:00
123 , // NTP
2016-03-30 06:04:00 +03:00
135 , // loc-srv / epmap
2001-06-06 04:10:09 +04:00
139 , // netbios
2016-03-30 06:04:00 +03:00
143 , // imap2
2001-06-06 04:10:09 +04:00
179 , // BGP
2016-03-30 06:04:00 +03:00
389 , // ldap
2006-07-06 23:40:38 +04:00
465 , // smtp+ssl
2016-03-30 06:04:00 +03:00
512 , // print / exec
513 , // login
514 , // shell
515 , // printer
526 , // tempo
530 , // courier
531 , // Chat
532 , // netnews
540 , // uucp
556 , // remotefs
2006-07-06 23:40:38 +04:00
563 , // nntp+ssl
2001-06-06 04:10:09 +04:00
587 , //
2016-03-30 06:04:00 +03:00
601 , //
2006-07-06 23:40:38 +04:00
636 , // ldap+ssl
993 , // imap+ssl
995 , // pop3+ssl
2001-06-06 04:10:09 +04:00
2049 , // nfs
2016-03-30 06:04:00 +03:00
3659 , // apple-sasl / PasswordServer
2001-06-06 04:10:09 +04:00
4045 , // lockd
2016-03-30 06:04:00 +03:00
6000 , // x11
6665 , // Alternate IRC [Apple addition]
6666 , // Alternate IRC [Apple addition]
6667 , // Standard IRC [Apple addition]
6668 , // Alternate IRC [Apple addition]
6669 , // Alternate IRC [Apple addition]
2001-06-06 04:10:09 +04:00
0 , // This MUST be zero so that we can populating the array
} ;
1999-08-29 20:42:27 +04:00
2001-11-07 07:26:19 +03:00
static const char kProfileChangeNetTeardownTopic [ ] = " profile-change-net-teardown " ;
static const char kProfileChangeNetRestoreTopic [ ] = " profile-change-net-restore " ;
2011-10-18 13:46:59 +04:00
static const char kProfileDoChange [ ] = " profile-do-change " ;
2014-08-23 07:05:56 +04:00
static const char kNetworkActiveChanged [ ] = " network-active-changed " ;
2001-11-07 07:26:19 +03:00
2012-01-10 07:43:52 +04:00
// Necko buffer defaults
2012-08-22 19:56:38 +04:00
uint32_t nsIOService : : gDefaultSegmentSize = 4096 ;
uint32_t nsIOService : : gDefaultSegmentCount = 24 ;
2002-07-02 22:15:19 +04:00
2015-02-06 16:27:33 +03:00
bool nsIOService : : sTelemetryEnabled = false ;
2014-08-23 07:05:56 +04:00
NS_IMPL_ISUPPORTS ( nsAppOfflineInfo , nsIAppOfflineInfo )
1999-06-08 01:33:30 +04:00
////////////////////////////////////////////////////////////////////////////////
nsIOService : : nsIOService ( )
2011-10-17 18:59:28 +04:00
: mOffline ( true )
, mOfflineForProfileChange ( false )
2015-05-02 00:14:39 +03:00
, mManageLinkStatus ( false )
, mConnectivity ( true )
2015-03-26 14:19:47 +03:00
, mOfflineMirrorsConnectivity ( true )
2011-10-17 18:59:28 +04:00
, mSettingOffline ( false )
, mSetOfflineValue ( false )
, mShutdown ( false )
2016-02-04 06:14:00 +03:00
, mHttpHandlerAlreadyShutingDown ( false )
2011-10-18 13:46:59 +04:00
, mNetworkLinkServiceInitialized ( false )
2006-02-22 17:07:21 +03:00
, mChannelEventSinks ( NS_CHANNEL_EVENT_SINK_CATEGORY )
2014-09-19 14:36:00 +04:00
, mNetworkNotifyChanged ( true )
2014-08-23 07:05:56 +04:00
, mPreviousWifiState ( - 1 )
2015-07-07 12:13:00 +03:00
, mLastOfflineStateChange ( PR_IntervalNow ( ) )
, mLastConnectivityChange ( PR_IntervalNow ( ) )
, mLastNetworkLinkChange ( PR_IntervalNow ( ) )
2016-01-18 10:20:00 +03:00
, mNetTearingDownStarted ( 0 )
1999-06-08 01:33:30 +04:00
{
}
nsresult
nsIOService : : Init ( )
{
2003-01-18 05:15:14 +03:00
nsresult rv ;
2010-11-25 08:20:11 +03:00
// We need to get references to the DNS service so that we can shut it
2000-01-19 10:58:40 +03:00
// down later. If we wait until the nsIOService is being shut down,
// GetService will fail at that point.
2000-06-13 07:00:53 +04:00
2007-09-05 17:04:54 +04:00
mDNSService = do_GetService ( NS_DNSSERVICE_CONTRACTID , & rv ) ;
2007-06-11 04:01:48 +04:00
if ( NS_FAILED ( rv ) ) {
2003-01-18 05:15:14 +03:00
NS_WARNING ( " failed to get DNS service " ) ;
2007-06-11 04:01:48 +04:00
return rv ;
}
2000-07-25 09:45:56 +04:00
2003-01-18 05:15:14 +03:00
// XXX hack until xpidl supports error info directly (bug 13423)
2007-09-05 17:04:54 +04:00
nsCOMPtr < nsIErrorService > errorService = do_GetService ( NS_ERRORSERVICE_CONTRACTID ) ;
2003-01-18 05:15:14 +03:00
if ( errorService ) {
errorService - > RegisterErrorStringBundle ( NS_ERROR_MODULE_NETWORK , NECKO_MSGS_URL ) ;
}
else
NS_WARNING ( " failed to get error service " ) ;
2014-10-14 01:35:51 +04:00
InitializeCaptivePortalService ( ) ;
2001-06-06 04:10:09 +04:00
// setup our bad port list stuff
2003-01-18 05:15:14 +03:00
for ( int i = 0 ; gBadPortList [ i ] ; i + + )
2009-02-23 04:05:28 +03:00
mRestrictedPortList . AppendElement ( gBadPortList [ i ] ) ;
2001-06-06 04:10:09 +04:00
2001-10-09 02:27:14 +04:00
// Further modifications to the port list come from prefs
2012-01-17 05:48:29 +04:00
nsCOMPtr < nsIPrefBranch > prefBranch ;
2001-10-09 02:27:14 +04:00
GetPrefBranch ( getter_AddRefs ( prefBranch ) ) ;
if ( prefBranch ) {
2011-10-17 18:59:28 +04:00
prefBranch - > AddObserver ( PORT_PREF_PREFIX , this , true ) ;
prefBranch - > AddObserver ( MANAGE_OFFLINE_STATUS_PREF , this , true ) ;
2013-03-14 19:05:54 +04:00
prefBranch - > AddObserver ( NECKO_BUFFER_CACHE_COUNT_PREF , this , true ) ;
prefBranch - > AddObserver ( NECKO_BUFFER_CACHE_SIZE_PREF , this , true ) ;
2014-09-19 14:36:00 +04:00
prefBranch - > AddObserver ( NETWORK_NOTIFY_CHANGED_PREF , this , true ) ;
2014-10-14 01:35:51 +04:00
prefBranch - > AddObserver ( NETWORK_CAPTIVE_PORTAL_PREF , this , true ) ;
2001-10-09 02:27:14 +04:00
PrefsChanged ( prefBranch ) ;
2001-06-06 04:10:09 +04:00
}
2001-11-07 07:26:19 +03:00
// Register for profile change notifications
2016-05-19 05:02:57 +03:00
nsCOMPtr < nsIObserverService > observerService = services : : GetObserverService ( ) ;
2001-11-07 07:26:19 +03:00
if ( observerService ) {
2011-10-17 18:59:28 +04:00
observerService - > AddObserver ( this , kProfileChangeNetTeardownTopic , true ) ;
observerService - > AddObserver ( this , kProfileChangeNetRestoreTopic , true ) ;
2011-10-18 13:46:59 +04:00
observerService - > AddObserver ( this , kProfileDoChange , true ) ;
2011-10-17 18:59:28 +04:00
observerService - > AddObserver ( this , NS_XPCOM_SHUTDOWN_OBSERVER_ID , true ) ;
observerService - > AddObserver ( this , NS_NETWORK_LINK_TOPIC , true ) ;
2014-09-19 14:34:00 +04:00
observerService - > AddObserver ( this , NS_WIDGET_WAKE_OBSERVER_TOPIC , true ) ;
2014-08-23 07:05:56 +04:00
observerService - > AddObserver ( this , kNetworkActiveChanged , true ) ;
2001-11-07 07:26:19 +03:00
}
2003-01-18 05:15:14 +03:00
else
NS_WARNING ( " failed to get observer service " ) ;
2010-05-20 03:22:19 +04:00
2015-02-06 16:27:33 +03:00
Preferences : : AddBoolVarCache ( & sTelemetryEnabled , " toolkit.telemetry.enabled " , false ) ;
2015-03-26 14:19:47 +03:00
Preferences : : AddBoolVarCache ( & mOfflineMirrorsConnectivity , OFFLINE_MIRRORS_CONNECTIVITY , true ) ;
2015-02-06 16:27:33 +03:00
2006-02-22 17:07:21 +03:00
gIOService = this ;
2010-07-29 05:05:19 +04:00
2011-10-18 13:46:59 +04:00
InitializeNetworkLinkService ( ) ;
2015-10-04 14:43:00 +03:00
2015-04-03 16:23:18 +03:00
SetOffline ( false ) ;
2006-04-05 01:26:17 +04:00
2001-06-06 04:10:09 +04:00
return NS_OK ;
2000-06-13 07:00:53 +04:00
}
1999-06-08 01:33:30 +04:00
nsIOService : : ~ nsIOService ( )
{
2012-07-30 18:20:58 +04:00
gIOService = nullptr ;
2010-11-25 08:20:11 +03:00
}
2014-10-14 01:35:51 +04:00
nsresult
nsIOService : : InitializeCaptivePortalService ( )
{
if ( XRE_GetProcessType ( ) ! = GeckoProcessType_Default ) {
// We only initalize a captive portal service in the main process
return NS_OK ;
}
mCaptivePortalService = do_GetService ( NS_CAPTIVEPORTAL_CID ) ;
if ( mCaptivePortalService ) {
return static_cast < CaptivePortalService * > ( mCaptivePortalService . get ( ) ) - > Initialize ( ) ;
}
return NS_OK ;
}
2010-11-25 08:20:11 +03: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 " ) ;
2012-09-18 03:45:10 +04:00
mSocketTransportService - > SetOffline ( false ) ;
2010-11-25 08:20:11 +03:00
}
return rv ;
}
1999-06-08 01:33:30 +04:00
2011-10-18 13:46:59 +04: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
2015-07-04 04:29:00 +03:00
if ( XRE_IsParentProcess ( ) )
2011-10-18 13:46:59 +04:00
{
mNetworkLinkService = do_GetService ( NS_NETWORK_LINK_SERVICE_CONTRACTID , & rv ) ;
}
if ( mNetworkLinkService ) {
mNetworkLinkServiceInitialized = true ;
}
2015-05-02 00:14:39 +03:00
// After initializing the networkLinkService, query the connectivity state
OnNetworkLinkEvent ( NS_NETWORK_LINK_DATA_UNKNOWN ) ;
2011-10-18 13:46:59 +04:00
return rv ;
}
2006-03-01 21:45:14 +03:00
nsIOService *
nsIOService : : GetInstance ( ) {
if ( ! gIOService ) {
gIOService = new nsIOService ( ) ;
if ( ! gIOService )
2012-07-30 18:20:58 +04:00
return nullptr ;
2006-03-01 21:45:14 +03:00
NS_ADDREF ( gIOService ) ;
nsresult rv = gIOService - > Init ( ) ;
if ( NS_FAILED ( rv ) ) {
NS_RELEASE ( gIOService ) ;
2012-07-30 18:20:58 +04:00
return nullptr ;
2006-03-01 21:45:14 +03:00
}
return gIOService ;
}
NS_ADDREF ( gIOService ) ;
return gIOService ;
}
2014-04-27 11:06:00 +04:00
NS_IMPL_ISUPPORTS ( nsIOService ,
nsIIOService ,
nsIIOService2 ,
nsINetUtil ,
nsISpeculativeConnect ,
nsIObserver ,
2015-05-02 00:14:39 +03:00
nsIIOServiceInternal ,
2014-04-27 11:06:00 +04:00
nsISupportsWeakReference )
2008-02-21 23:39:20 +03:00
1999-06-08 01:33:30 +04:00
////////////////////////////////////////////////////////////////////////////////
2016-05-18 00:55:52 +03:00
nsresult
nsIOService : : RecheckCaptivePortal ( )
{
MOZ_ASSERT ( NS_IsMainThread ( ) , " Must be called on the main thread " ) ;
if ( mCaptivePortalService ) {
mCaptivePortalService - > RecheckCaptivePortal ( ) ;
}
return NS_OK ;
}
2014-10-14 01:35:51 +04:00
nsresult
nsIOService : : RecheckCaptivePortalIfLocalRedirect ( nsIChannel * newChan )
{
nsresult rv ;
if ( ! mCaptivePortalService ) {
return NS_OK ;
}
nsCOMPtr < nsIURI > uri ;
rv = newChan - > GetURI ( getter_AddRefs ( uri ) ) ;
if ( NS_FAILED ( rv ) ) {
return rv ;
}
nsCString host ;
rv = uri - > GetHost ( host ) ;
if ( NS_FAILED ( rv ) ) {
return rv ;
}
PRNetAddr prAddr ;
if ( PR_StringToNetAddr ( host . BeginReading ( ) , & prAddr ) ! = PR_SUCCESS ) {
// The redirect wasn't to an IP literal, so there's probably no need
// to trigger the captive portal detection right now. It can wait.
return NS_OK ;
}
2016-05-19 05:02:57 +03:00
NetAddr netAddr ;
2014-10-14 01:35:51 +04:00
PRNetAddrToNetAddr ( & prAddr , & netAddr ) ;
if ( IsIPAddrLocal ( & netAddr ) ) {
// Redirects to local IP addresses are probably captive portals
mCaptivePortalService - > RecheckCaptivePortal ( ) ;
}
return NS_OK ;
}
2006-02-22 17:07:21 +03:00
nsresult
2010-08-05 06:15:55 +04:00
nsIOService : : AsyncOnChannelRedirect ( nsIChannel * oldChan , nsIChannel * newChan ,
2012-08-22 19:56:38 +04:00
uint32_t flags ,
2010-08-05 06:15:55 +04:00
nsAsyncRedirectVerifyHelper * helper )
2006-02-22 17:07:21 +03:00
{
2014-10-14 01:35:51 +04:00
// If a redirect to a local network address occurs, then chances are we
// are in a captive portal, so we trigger a recheck.
RecheckCaptivePortalIfLocalRedirect ( newChan ) ;
2015-12-07 02:33:14 +03:00
// This is silly. I wish there was a simpler way to get at the global
// reference of the contentSecurityManager. But it lives in the XPCOM
// service registry.
2006-02-22 17:07:21 +03:00
nsCOMPtr < nsIChannelEventSink > sink =
2015-12-07 02:33:14 +03:00
do_GetService ( NS_CONTENTSECURITYMANAGER_CONTRACTID ) ;
2006-02-22 17:07:21 +03:00
if ( sink ) {
2010-08-05 06:15:55 +04:00
nsresult rv = helper - > DelegateOnChannelRedirect ( sink , oldChan ,
newChan , flags ) ;
2006-02-22 17:07:21 +03:00
if ( NS_FAILED ( rv ) )
return rv ;
}
// Finally, our category
2013-10-10 16:48:03 +04:00
nsCOMArray < nsIChannelEventSink > entries ;
mChannelEventSinks . GetEntries ( entries ) ;
2012-08-22 19:56:38 +04:00
int32_t len = entries . Count ( ) ;
for ( int32_t i = 0 ; i < len ; + + i ) {
2010-08-05 06:15:55 +04:00
nsresult rv = helper - > DelegateOnChannelRedirect ( entries [ i ] , oldChan ,
newChan , flags ) ;
2006-02-22 17:07:21 +03:00
if ( NS_FAILED ( rv ) )
return rv ;
}
return NS_OK ;
}
2002-09-13 23:32:45 +04:00
nsresult
2000-08-22 10:16:50 +04:00
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 )
{
2005-11-25 11:16:51 +03:00
// Don't cache handlers that don't support weak reference as
2000-08-22 10:16:50 +04:00
// there is real danger of a circular reference.
2000-10-29 02:17:53 +04:00
# ifdef DEBUG_dp
printf ( " DEBUG: %s protcol handler doesn't support weak ref. Not cached. \n " , scheme ) ;
# endif /* DEBUG_dp */
2000-08-22 10:16:50 +04:00
return NS_ERROR_FAILURE ;
}
2003-07-25 23:06:59 +04:00
mWeakHandler [ i ] = do_GetWeakReference ( handler ) ;
2000-08-22 10:16:50 +04:00
return NS_OK ;
}
}
return NS_ERROR_FAILURE ;
}
2002-09-13 23:32:45 +04:00
nsresult
2012-08-22 19:56:38 +04:00
nsIOService : : GetCachedProtocolHandler ( const char * scheme , nsIProtocolHandler * * result , uint32_t start , uint32_t end )
2000-08-22 10:16:50 +04:00
{
2012-08-22 19:56:38 +04:00
uint32_t len = end - start - 1 ;
2000-08-22 10:16:50 +04:00
for ( unsigned int i = 0 ; i < NS_N ( gScheme ) ; i + + )
{
2001-10-31 01:20:06 +03:00
if ( ! mWeakHandler [ i ] )
continue ;
2001-08-17 08:01:38 +04:00
// handle unterminated strings
// start is inclusive, end is exclusive, len = end - start - 1
2001-10-31 01:20:06 +03:00
if ( end ? ( ! nsCRT : : strncasecmp ( scheme + start , gScheme [ i ] , len )
& & gScheme [ i ] [ len ] = = ' \0 ' )
: ( ! nsCRT : : strcasecmp ( scheme , gScheme [ i ] ) ) )
2001-08-17 08:01:38 +04:00
{
2002-11-06 16:03:49 +03:00
return CallQueryReferent ( mWeakHandler [ i ] . get ( ) , result ) ;
2001-08-17 08:01:38 +04:00
}
2000-08-22 10:16:50 +04:00
}
return NS_ERROR_FAILURE ;
}
1999-06-08 01:33:30 +04:00
NS_IMETHODIMP
nsIOService : : GetProtocolHandler ( const char * scheme , nsIProtocolHandler * * result )
{
nsresult rv ;
2000-05-04 01:47:56 +04:00
NS_ENSURE_ARG_POINTER ( scheme ) ;
1999-06-08 01:33:30 +04:00
// 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
2000-08-22 10:16:50 +04:00
rv = GetCachedProtocolHandler ( scheme , result ) ;
2004-08-25 01:50:15 +04:00
if ( NS_SUCCEEDED ( rv ) )
return rv ;
2000-08-22 10:16:50 +04:00
2011-09-29 10:19:26 +04:00
bool externalProtocol = false ;
2012-01-17 05:48:29 +04:00
nsCOMPtr < nsIPrefBranch > prefBranch ;
2002-03-26 18:58:26 +03:00
GetPrefBranch ( getter_AddRefs ( prefBranch ) ) ;
if ( prefBranch ) {
2012-09-02 06:35:17 +04:00
nsAutoCString externalProtocolPref ( " network.protocol-handler.external. " ) ;
2002-03-26 18:58:26 +03:00
externalProtocolPref + = scheme ;
rv = prefBranch - > GetBoolPref ( externalProtocolPref . get ( ) , & externalProtocol ) ;
2002-10-09 04:54:43 +04:00
if ( NS_FAILED ( rv ) ) {
2011-10-17 18:59:28 +04:00
externalProtocol = false ;
2002-10-09 04:54:43 +04:00
}
2002-03-26 18:58:26 +03:00
}
1999-06-08 01:33:30 +04:00
2002-03-26 18:58:26 +03:00
if ( ! externalProtocol ) {
2012-09-02 06:35:17 +04:00
nsAutoCString contractID ( NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX ) ;
2002-03-26 18:58:26 +03:00
contractID + = scheme ;
ToLowerCase ( contractID ) ;
rv = CallGetService ( contractID . get ( ) , result ) ;
2004-08-25 01:50:15 +04:00
if ( NS_SUCCEEDED ( rv ) ) {
CacheProtocolHandler ( scheme , * result ) ;
return rv ;
}
2015-03-07 08:06:34 +03:00
# ifdef MOZ_ENABLE_GIO
2011-03-24 06:38:03 +03: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-02 06:35:17 +04:00
nsAutoCString spec ( scheme ) ;
2011-03-24 06:38:03 +03:00
spec . Append ( ' : ' ) ;
nsIURI * uri ;
2012-07-30 18:20:58 +04:00
rv = ( * result ) - > NewURI ( spec , nullptr , nullptr , & uri ) ;
2011-03-24 06:38:03 +03:00
if ( NS_SUCCEEDED ( rv ) ) {
NS_RELEASE ( uri ) ;
return rv ;
}
NS_RELEASE ( * result ) ;
}
2004-08-25 01:50:15 +04:00
# endif
2007-11-09 09:13:26 +03:00
}
1999-06-08 01:33:30 +04:00
2004-08-25 01:50:15 +04: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.
2000-08-22 10:16:50 +04:00
2004-08-25 01:50:15 +04:00
rv = CallGetService ( NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX " default " ,
result ) ;
if ( NS_FAILED ( rv ) )
return NS_ERROR_UNKNOWN_PROTOCOL ;
return rv ;
1999-06-08 01:33:30 +04:00
}
1999-11-12 09:13:13 +03:00
NS_IMETHODIMP
2002-03-06 10:48:55 +03:00
nsIOService : : ExtractScheme ( const nsACString & inURI , nsACString & scheme )
1999-07-10 15:26:43 +04:00
{
2016-02-05 16:45:08 +03:00
return net_ExtractURLScheme ( inURI , scheme ) ;
2001-06-22 02:02:47 +04:00
}
2001-08-08 00:42:57 +04:00
NS_IMETHODIMP
2012-08-22 19:56:38 +04:00
nsIOService : : GetProtocolFlags ( const char * scheme , uint32_t * flags )
2001-08-08 00:42:57 +04:00
{
nsCOMPtr < nsIProtocolHandler > handler ;
nsresult rv = GetProtocolHandler ( scheme , getter_AddRefs ( handler ) ) ;
2002-03-06 10:48:55 +03:00
if ( NS_FAILED ( rv ) ) return rv ;
2015-07-27 23:27:38 +03:00
// We can't call DoGetProtocolFlags here because we don't have a URI. This
// API is used by (and only used by) extensions, which is why it's still
// around. Calling this on a scheme with dynamic flags will throw.
2001-09-13 06:21:05 +04:00
rv = handler - > GetProtocolFlags ( flags ) ;
2001-08-08 00:42:57 +04:00
return rv ;
}
2007-03-12 08:56:45 +03:00
class AutoIncrement
{
public :
2014-08-05 17:20:24 +04:00
explicit AutoIncrement ( uint32_t * var ) : mVar ( var )
2007-03-12 08:56:45 +03:00
{
+ + * var ;
}
~ AutoIncrement ( )
{
- - * mVar ;
}
private :
2012-08-22 19:56:38 +04:00
uint32_t * mVar ;
2007-03-12 08:56:45 +03:00
} ;
1999-09-26 14:11:36 +04:00
nsresult
2002-03-06 10:48:55 +03:00
nsIOService : : NewURI ( const nsACString & aSpec , const char * aCharset , nsIURI * aBaseURI , nsIURI * * result )
1999-06-08 01:33:30 +04:00
{
2007-03-12 08:56:45 +03:00
NS_ASSERTION ( NS_IsMainThread ( ) , " wrong thread " ) ;
2012-08-22 19:56:38 +04:00
static uint32_t recursionCount = 0 ;
2007-03-12 08:56:45 +03:00
if ( recursionCount > = MAX_RECURSION_COUNT )
return NS_ERROR_MALFORMED_URI ;
AutoIncrement inc ( & recursionCount ) ;
2001-08-17 08:01:38 +04:00
2012-09-02 06:35:17 +04:00
nsAutoCString scheme ;
2007-03-12 08:56:45 +03:00
nsresult rv = ExtractScheme ( aSpec , scheme ) ;
2002-08-30 01:31:55 +04:00
if ( NS_FAILED ( rv ) ) {
1999-07-27 12:45:20 +04:00
// then aSpec is relative
2001-08-17 08:01:38 +04:00
if ( ! aBaseURI )
1999-07-27 12:45:20 +04:00
return NS_ERROR_MALFORMED_URI ;
2002-03-06 10:48:55 +03:00
2016-07-27 01:38:46 +03:00
if ( ! aSpec . IsEmpty ( ) & & aSpec [ 0 ] = = ' # ' ) {
// Looks like a reference instead of a fully-specified URI.
// --> initialize |uri| as a clone of |aBaseURI|, with ref appended.
return aBaseURI - > CloneWithNewRef ( aSpec , result ) ;
}
2002-03-06 10:48:55 +03:00
rv = aBaseURI - > GetScheme ( scheme ) ;
if ( NS_FAILED ( rv ) ) return rv ;
2001-08-17 08:01:38 +04:00
}
2002-03-06 10:48:55 +03:00
// now get the handler for this scheme
nsCOMPtr < nsIProtocolHandler > handler ;
rv = GetProtocolHandler ( scheme . get ( ) , getter_AddRefs ( handler ) ) ;
1999-07-10 15:26:43 +04:00
if ( NS_FAILED ( rv ) ) return rv ;
1999-06-08 01:33:30 +04:00
2002-03-06 10:48:55 +03:00
return handler - > NewURI ( aSpec , aCharset , aBaseURI , result ) ;
1999-06-08 01:33:30 +04:00
}
2001-06-22 02:02:47 +04:00
NS_IMETHODIMP
2002-02-01 01:17:35 +03:00
nsIOService : : NewFileURI ( nsIFile * file , nsIURI * * result )
2001-06-22 02:02:47 +04:00
{
nsresult rv ;
2002-02-01 01:17:35 +03:00
NS_ENSURE_ARG_POINTER ( file ) ;
nsCOMPtr < nsIProtocolHandler > handler ;
rv = GetProtocolHandler ( " file " , getter_AddRefs ( handler ) ) ;
2001-06-22 02:02:47 +04:00
if ( NS_FAILED ( rv ) ) return rv ;
2002-02-01 01:17:35 +03:00
nsCOMPtr < nsIFileProtocolHandler > fileHandler ( do_QueryInterface ( handler , & rv ) ) ;
if ( NS_FAILED ( rv ) ) return rv ;
return fileHandler - > NewFileURI ( file , result ) ;
2001-06-22 02:02:47 +04:00
}
2014-10-23 04:20:12 +04:00
NS_IMETHODIMP
nsIOService : : NewChannelFromURI2 ( nsIURI * aURI ,
nsIDOMNode * aLoadingNode ,
nsIPrincipal * aLoadingPrincipal ,
nsIPrincipal * aTriggeringPrincipal ,
uint32_t aSecurityFlags ,
uint32_t aContentPolicyType ,
nsIChannel * * result )
{
return NewChannelFromURIWithProxyFlags2 ( aURI ,
nullptr , // aProxyURI
0 , // aProxyFlags
aLoadingNode ,
aLoadingPrincipal ,
aTriggeringPrincipal ,
aSecurityFlags ,
aContentPolicyType ,
result ) ;
}
2016-03-19 03:11:42 +03:00
/* ***** DEPRECATED *****
* please use NewChannelFromURI2 providing the right arguments for :
* * aLoadingNode
* * aLoadingPrincipal
* * aTriggeringPrincipal
* * aSecurityFlags
* * aContentPolicyType
*
* See nsIIoService . idl for a detailed description of those arguments
*/
NS_IMETHODIMP
nsIOService : : NewChannelFromURI ( nsIURI * aURI , nsIChannel * * result )
{
NS_ASSERTION ( false , " Deprecated, use NewChannelFromURI2 providing loadInfo arguments! " ) ;
const char16_t * params [ ] = {
2016-07-21 08:03:25 +03:00
u " nsIOService::NewChannelFromURI() " ,
u " nsIOService::NewChannelFromURI2() "
2016-03-19 03:11:42 +03:00
} ;
nsContentUtils : : ReportToConsole ( nsIScriptError : : warningFlag ,
NS_LITERAL_CSTRING ( " Security by Default " ) ,
nullptr , // aDocument
nsContentUtils : : eNECKO_PROPERTIES ,
" APIDeprecationWarning " ,
params , ArrayLength ( params ) ) ;
return NewChannelFromURI2 ( aURI ,
nullptr , // aLoadingNode
nsContentUtils : : GetSystemPrincipal ( ) ,
nullptr , // aTriggeringPrincipal
nsILoadInfo : : SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL ,
nsIContentPolicy : : TYPE_OTHER ,
result ) ;
}
2014-12-13 01:24:57 +03:00
NS_IMETHODIMP
nsIOService : : NewChannelFromURIWithLoadInfo ( nsIURI * aURI ,
nsILoadInfo * aLoadInfo ,
nsIChannel * * result )
{
return NewChannelFromURIWithProxyFlagsInternal ( aURI ,
nullptr , // aProxyURI
0 , // aProxyFlags
aLoadInfo ,
result ) ;
}
nsresult
nsIOService : : NewChannelFromURIWithProxyFlagsInternal ( nsIURI * aURI ,
nsIURI * aProxyURI ,
uint32_t aProxyFlags ,
nsILoadInfo * aLoadInfo ,
nsIChannel * * result )
1999-06-08 01:33:30 +04:00
{
1999-06-08 22:28:10 +04:00
nsresult rv ;
2000-05-04 01:47:56 +04:00
NS_ENSURE_ARG_POINTER ( aURI ) ;
1999-06-08 22:28:10 +04:00
2012-09-02 06:35:17 +04:00
nsAutoCString scheme ;
2002-03-06 10:48:55 +03:00
rv = aURI - > GetScheme ( scheme ) ;
2005-03-25 06:41:33 +03:00
if ( NS_FAILED ( rv ) )
return rv ;
1999-06-08 22:28:10 +04:00
2001-09-13 06:21:05 +04:00
nsCOMPtr < nsIProtocolHandler > handler ;
2005-03-25 06:41:33 +03:00
rv = GetProtocolHandler ( scheme . get ( ) , getter_AddRefs ( handler ) ) ;
if ( NS_FAILED ( rv ) )
return rv ;
2001-09-13 06:21:05 +04:00
2012-08-22 19:56:38 +04:00
uint32_t protoFlags ;
2015-07-27 23:27:38 +03:00
rv = handler - > DoGetProtocolFlags ( aURI , & protoFlags ) ;
2005-03-25 06:41:33 +03:00
if ( NS_FAILED ( rv ) )
return rv ;
2001-09-13 06:21:05 +04:00
2014-12-12 20:05:21 +03:00
// Ideally we are creating new channels by calling NewChannel2 (NewProxiedChannel2).
// Keep in mind that Addons can implement their own Protocolhandlers, hence
// NewChannel2() might *not* be implemented.
// We do not want to break those addons, therefore we first try to create a channel
2015-05-29 20:41:41 +03:00
// calling NewChannel2(); if that fails:
// * we fall back to creating a channel by calling NewChannel()
// * wrap the addon channel
// * and attach the loadInfo to the channel wrapper
nsCOMPtr < nsIChannel > channel ;
2012-09-15 00:27:46 +04:00
nsCOMPtr < nsIProxiedProtocolHandler > pph = do_QueryInterface ( handler ) ;
2014-12-12 20:05:21 +03:00
if ( pph ) {
rv = pph - > NewProxiedChannel2 ( aURI , nullptr , aProxyFlags , aProxyURI ,
2015-05-29 20:41:41 +03:00
aLoadInfo , getter_AddRefs ( channel ) ) ;
2014-12-12 20:05:21 +03:00
// if calling NewProxiedChannel2() fails we try to fall back to
// creating a new proxied channel by calling NewProxiedChannel().
if ( NS_FAILED ( rv ) ) {
rv = pph - > NewProxiedChannel ( aURI , nullptr , aProxyFlags , aProxyURI ,
2015-05-29 20:41:41 +03:00
getter_AddRefs ( channel ) ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
2015-10-16 07:07:00 +03:00
// The protocol handler does not implement NewProxiedChannel2, so
// maybe we need to wrap the channel (see comment in MaybeWrap
// function).
channel = nsSecCheckWrapChannel : : MaybeWrap ( channel , aLoadInfo ) ;
2014-12-12 20:05:21 +03:00
}
}
else {
2015-05-29 20:41:41 +03:00
rv = handler - > NewChannel2 ( aURI , aLoadInfo , getter_AddRefs ( channel ) ) ;
2014-12-12 20:05:21 +03:00
// if calling newChannel2() fails we try to fall back to
// creating a new channel by calling NewChannel().
if ( NS_FAILED ( rv ) ) {
2015-05-29 20:41:41 +03:00
rv = handler - > NewChannel ( aURI , getter_AddRefs ( channel ) ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
2015-10-16 07:07:00 +03:00
// The protocol handler does not implement NewChannel2, so
// maybe we need to wrap the channel (see comment in MaybeWrap
// function).
channel = nsSecCheckWrapChannel : : MaybeWrap ( channel , aLoadInfo ) ;
2014-12-12 20:05:21 +03:00
}
}
2015-05-29 20:41:41 +03:00
// Make sure that all the individual protocolhandlers attach a loadInfo.
if ( aLoadInfo ) {
2015-01-12 07:21:37 +03:00
// make sure we have the same instance of loadInfo on the newly created channel
2015-12-01 00:25:29 +03:00
nsCOMPtr < nsILoadInfo > loadInfo = channel - > GetLoadInfo ( ) ;
2015-01-12 07:21:37 +03:00
if ( aLoadInfo ! = loadInfo ) {
MOZ_ASSERT ( false , " newly created channel must have a loadinfo attached " ) ;
return NS_ERROR_UNEXPECTED ;
}
2014-12-12 20:05:21 +03:00
// If we're sandboxed, make sure to clear any owner the channel
// might already have.
if ( loadInfo - > GetLoadingSandboxed ( ) ) {
2015-05-29 20:41:41 +03:00
channel - > SetOwner ( nullptr ) ;
2014-12-12 20:05:21 +03:00
}
}
2009-11-19 02:21:13 +03: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 " ) ) {
2015-05-29 20:41:41 +03:00
nsCOMPtr < nsIUploadChannel2 > uploadChannel2 = do_QueryInterface ( channel ) ;
2009-11-19 02:21:13 +03:00
if ( ! uploadChannel2 ) {
nsCOMPtr < nsIConsoleService > consoleService =
do_GetService ( NS_CONSOLESERVICE_CONTRACTID ) ;
if ( consoleService ) {
consoleService - > LogStringMessage ( NS_LITERAL_STRING (
2009-11-19 03:22:25 +03: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-19 02:21:13 +03:00
}
2011-10-17 18:59:28 +04:00
gHasWarnedUploadChannel2 = true ;
2009-11-19 02:21:13 +03:00
}
}
2015-05-29 20:41:41 +03:00
channel . forget ( result ) ;
2009-11-19 02:21:13 +03:00
return NS_OK ;
1999-06-08 01:33:30 +04:00
}
2014-12-13 01:24:57 +03:00
NS_IMETHODIMP
nsIOService : : NewChannelFromURIWithProxyFlags2 ( nsIURI * aURI ,
nsIURI * aProxyURI ,
uint32_t aProxyFlags ,
nsIDOMNode * aLoadingNode ,
nsIPrincipal * aLoadingPrincipal ,
nsIPrincipal * aTriggeringPrincipal ,
uint32_t aSecurityFlags ,
uint32_t aContentPolicyType ,
nsIChannel * * result )
{
// Ideally all callers of NewChannelFromURIWithProxyFlags2 provide the
// necessary arguments to create a loadinfo. Keep in mind that addons
// might still call NewChannelFromURIWithProxyFlags() which forwards
// its calls to NewChannelFromURIWithProxyFlags2 using *null* values
// as the arguments for aLoadingNode, aLoadingPrincipal, and also
// aTriggeringPrincipal.
// We do not want to break those addons, hence we only create a Loadinfo
// if 'aLoadingNode' or 'aLoadingPrincipal' are provided. Note, that
// either aLoadingNode or aLoadingPrincipal is required to succesfully
// create a LoadInfo object.
2016-04-14 02:30:16 +03:00
// Except in the case of top level TYPE_DOCUMENT loads, where the
// loadingNode and loadingPrincipal are allowed to have null values.
2014-12-13 01:24:57 +03:00
nsCOMPtr < nsILoadInfo > loadInfo ;
2016-04-14 02:30:16 +03:00
// TYPE_DOCUMENT loads don't require a loadingNode or principal, but other
// types do.
if ( aLoadingNode | | aLoadingPrincipal | |
aContentPolicyType = = nsIContentPolicy : : TYPE_DOCUMENT ) {
2014-12-13 01:24:57 +03:00
nsCOMPtr < nsINode > loadingNode ( do_QueryInterface ( aLoadingNode ) ) ;
2016-05-19 05:02:57 +03:00
loadInfo = new LoadInfo ( aLoadingPrincipal ,
aTriggeringPrincipal ,
loadingNode ,
aSecurityFlags ,
aContentPolicyType ) ;
2014-12-13 01:24:57 +03:00
}
2015-05-14 03:58:52 +03:00
NS_ASSERTION ( loadInfo , " Please pass security info when creating a channel " ) ;
2014-12-13 01:24:57 +03:00
return NewChannelFromURIWithProxyFlagsInternal ( aURI ,
aProxyURI ,
aProxyFlags ,
loadInfo ,
result ) ;
}
2016-03-19 03:11:42 +03:00
/* ***** DEPRECATED *****
* please use NewChannelFromURIWithProxyFlags2 providing the right arguments for :
* * aLoadingNode
* * aLoadingPrincipal
* * aTriggeringPrincipal
* * aSecurityFlags
* * aContentPolicyType
*
* See nsIIoService . idl for a detailed description of those arguments
*/
NS_IMETHODIMP
nsIOService : : NewChannelFromURIWithProxyFlags ( nsIURI * aURI ,
nsIURI * aProxyURI ,
uint32_t aProxyFlags ,
nsIChannel * * result )
{
NS_ASSERTION ( false , " Deprecated, use NewChannelFromURIWithProxyFlags2 providing loadInfo arguments! " ) ;
const char16_t * params [ ] = {
2016-07-21 08:03:25 +03:00
u " nsIOService::NewChannelFromURIWithProxyFlags() " ,
u " nsIOService::NewChannelFromURIWithProxyFlags2() "
2016-03-19 03:11:42 +03:00
} ;
nsContentUtils : : ReportToConsole ( nsIScriptError : : warningFlag ,
NS_LITERAL_CSTRING ( " Security by Default " ) ,
nullptr , // aDocument
nsContentUtils : : eNECKO_PROPERTIES ,
" APIDeprecationWarning " ,
params , ArrayLength ( params ) ) ;
return NewChannelFromURIWithProxyFlags2 ( aURI ,
aProxyURI ,
aProxyFlags ,
nullptr , // aLoadingNode
nsContentUtils : : GetSystemPrincipal ( ) ,
nullptr , // aTriggeringPrincipal
nsILoadInfo : : SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL ,
nsIContentPolicy : : TYPE_OTHER ,
result ) ;
}
2014-10-23 04:20:12 +04:00
NS_IMETHODIMP
nsIOService : : NewChannel2 ( const nsACString & aSpec ,
const char * aCharset ,
nsIURI * aBaseURI ,
nsIDOMNode * aLoadingNode ,
nsIPrincipal * aLoadingPrincipal ,
nsIPrincipal * aTriggeringPrincipal ,
uint32_t aSecurityFlags ,
uint32_t aContentPolicyType ,
nsIChannel * * result )
1999-06-08 01:33:30 +04:00
{
1999-06-08 22:28:10 +04:00
nsresult rv ;
1999-09-26 14:11:36 +04:00
nsCOMPtr < nsIURI > uri ;
2002-03-06 10:48:55 +03:00
rv = NewURI ( aSpec , aCharset , aBaseURI , getter_AddRefs ( uri ) ) ;
1999-06-08 22:28:10 +04:00
if ( NS_FAILED ( rv ) ) return rv ;
1999-11-17 11:14:52 +03:00
2014-10-23 04:20:12 +04:00
return NewChannelFromURI2 ( uri ,
aLoadingNode ,
aLoadingPrincipal ,
aTriggeringPrincipal ,
aSecurityFlags ,
aContentPolicyType ,
result ) ;
}
2016-03-19 03:11:42 +03:00
/* ***** DEPRECATED *****
* please use NewChannel2 providing the right arguments for :
* * aLoadingNode
* * aLoadingPrincipal
* * aTriggeringPrincipal
* * aSecurityFlags
* * aContentPolicyType
*
* See nsIIoService . idl for a detailed description of those arguments
*/
NS_IMETHODIMP
nsIOService : : NewChannel ( const nsACString & aSpec , const char * aCharset , nsIURI * aBaseURI , nsIChannel * * result )
{
NS_ASSERTION ( false , " Deprecated, use NewChannel2 providing loadInfo arguments! " ) ;
const char16_t * params [ ] = {
2016-07-21 08:03:25 +03:00
u " nsIOService::NewChannel() " ,
u " nsIOService::NewChannel2() "
2016-03-19 03:11:42 +03:00
} ;
nsContentUtils : : ReportToConsole ( nsIScriptError : : warningFlag ,
NS_LITERAL_CSTRING ( " Security by Default " ) ,
nullptr , // aDocument
nsContentUtils : : eNECKO_PROPERTIES ,
" APIDeprecationWarning " ,
params , ArrayLength ( params ) ) ;
// Call NewChannel2 providing default arguments for the loadInfo.
return NewChannel2 ( aSpec ,
aCharset ,
aBaseURI ,
nullptr , // aLoadingNode
nsContentUtils : : GetSystemPrincipal ( ) , // aLoadingPrincipal
nullptr , // aTriggeringPrincipal
nsILoadInfo : : SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL ,
nsIContentPolicy : : TYPE_OTHER ,
result ) ;
}
2011-09-29 10:19:26 +04:00
bool
2008-11-13 18:38:02 +03:00
nsIOService : : IsLinkUp ( )
{
2011-10-18 13:46:59 +04:00
InitializeNetworkLinkService ( ) ;
2008-11-13 18:38:02 +03:00
if ( ! mNetworkLinkService ) {
// We cannot decide, assume the link is up
2011-10-17 18:59:28 +04:00
return true ;
2008-11-13 18:38:02 +03:00
}
2011-09-29 10:19:26 +04:00
bool isLinkUp ;
2008-11-13 18:38:02 +03:00
nsresult rv ;
rv = mNetworkLinkService - > GetIsLinkUp ( & isLinkUp ) ;
if ( NS_FAILED ( rv ) ) {
2011-10-17 18:59:28 +04:00
return true ;
2008-11-13 18:38:02 +03:00
}
return isLinkUp ;
}
2000-01-05 05:44:23 +03:00
NS_IMETHODIMP
2011-09-29 10:19:26 +04:00
nsIOService : : GetOffline ( bool * offline )
2000-01-05 05:44:23 +03:00
{
2015-03-26 14:19:47 +03:00
if ( mOfflineMirrorsConnectivity ) {
* offline = mOffline | | ! mConnectivity ;
} else {
* offline = mOffline ;
}
2000-01-05 05:44:23 +03:00
return NS_OK ;
}
NS_IMETHODIMP
2011-09-29 10:19:26 +04:00
nsIOService : : SetOffline ( bool offline )
2000-01-05 05:44:23 +03:00
{
2015-11-18 17:25:39 +03:00
LOG ( ( " nsIOService::SetOffline offline=%d \n " , offline ) ) ;
2009-03-18 17:52:31 +03: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-30 01:07:37 +04:00
if ( ( mShutdown | | mOfflineForProfileChange ) & & ! offline )
2009-03-18 17:52:31 +03:00
return NS_ERROR_NOT_AVAILABLE ;
2009-02-22 22:09:09 +03: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 16:44:12 +04:00
2011-10-17 18:59:28 +04:00
mSettingOffline = true ;
2009-02-22 22:09:09 +03:00
2016-05-19 05:02:57 +03:00
nsCOMPtr < nsIObserverService > observerService = services : : GetObserverService ( ) ;
2001-01-17 22:51:28 +03:00
2010-05-11 16:44:12 +04:00
NS_ASSERTION ( observerService , " The observer service should not be null " ) ;
2015-07-04 04:29:00 +03:00
if ( XRE_IsParentProcess ( ) ) {
2010-05-11 16:44:12 +04:00
if ( observerService ) {
2012-07-30 18:20:58 +04:00
( void ) observerService - > NotifyObservers ( nullptr ,
2010-05-11 21:22:34 +04:00
NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC , offline ?
2016-07-21 08:03:25 +03:00
u " true " :
u " false " ) ;
2010-05-11 16:44:12 +04:00
}
}
2012-09-18 03:45:10 +04:00
nsIIOService * subject = static_cast < nsIIOService * > ( this ) ;
2009-02-22 22:09:09 +03:00
while ( mSetOfflineValue ! = mOffline ) {
offline = mSetOfflineValue ;
if ( offline & & ! mOffline ) {
NS_NAMED_LITERAL_STRING ( offlineString , NS_IOSERVICE_OFFLINE ) ;
2011-10-17 18:59:28 +04:00
mOffline = true ; // indicate we're trying to shutdown
2009-02-22 22:09:09 +03:00
2012-09-18 03:45:10 +04:00
// don't care if notifications fail
2009-02-22 22:09:09 +03:00
if ( observerService )
2012-09-18 03:45:10 +04:00
observerService - > NotifyObservers ( subject ,
2009-02-22 22:09:09 +03:00
NS_IOSERVICE_GOING_OFFLINE_TOPIC ,
offlineString . get ( ) ) ;
2012-09-18 03:45:10 +04:00
if ( mSocketTransportService )
mSocketTransportService - > SetOffline ( true ) ;
2009-02-22 22:09:09 +03:00
2015-07-07 12:13:00 +03:00
mLastOfflineStateChange = PR_IntervalNow ( ) ;
2009-02-22 22:09:09 +03:00
if ( observerService )
2012-09-18 03:45:10 +04:00
observerService - > NotifyObservers ( subject ,
2009-02-22 22:09:09 +03:00
NS_IOSERVICE_OFFLINE_STATUS_TOPIC ,
offlineString . get ( ) ) ;
2003-01-18 05:15:14 +03:00
}
2009-02-22 22:09:09 +03:00
else if ( ! offline & & mOffline ) {
// go online
if ( mDNSService ) {
2012-10-25 23:47:55 +04:00
DebugOnly < nsresult > rv = mDNSService - > Init ( ) ;
2009-02-22 22:09:09 +03:00
NS_ASSERTION ( NS_SUCCEEDED ( rv ) , " DNS service init failed " ) ;
}
2010-11-25 08:20:11 +03:00
InitializeSocketTransportService ( ) ;
2011-10-17 18:59:28 +04:00
mOffline = false ; // indicate success only AFTER we've
2009-02-22 22:09:09 +03:00
// brought up the services
// trigger a PAC reload when we come back online
if ( mProxyService )
mProxyService - > ReloadPAC ( ) ;
2015-07-07 12:13:00 +03:00
mLastOfflineStateChange = PR_IntervalNow ( ) ;
2009-02-22 22:09:09 +03:00
// don't care if notification fails
2015-05-02 00:14:39 +03:00
// Only send the ONLINE notification if there is connectivity
2015-07-07 12:13:00 +03:00
if ( observerService & & mConnectivity ) {
2012-09-18 03:45:10 +04:00
observerService - > NotifyObservers ( subject ,
2009-02-22 22:09:09 +03:00
NS_IOSERVICE_OFFLINE_STATUS_TOPIC ,
2016-07-20 07:07:53 +03:00
( u " " NS_IOSERVICE_ONLINE ) ) ;
2015-07-07 12:13:00 +03:00
}
2003-01-18 05:15:14 +03:00
}
2000-03-28 02:17:48 +04:00
}
2009-02-22 22:09:09 +03:00
2012-09-18 03:45:10 +04:00
// Don't notify here, as the above notifications (if used) suffice.
2012-11-30 01:07:37 +04:00
if ( ( mShutdown | | mOfflineForProfileChange ) & & mOffline ) {
2012-09-18 03:45:10 +04: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 23:47:55 +04:00
DebugOnly < nsresult > rv = mDNSService - > Shutdown ( ) ;
2012-09-18 03:45:10 +04:00
NS_ASSERTION ( NS_SUCCEEDED ( rv ) , " DNS service shutdown failed " ) ;
}
if ( mSocketTransportService ) {
2012-10-25 23:47:55 +04:00
DebugOnly < nsresult > rv = mSocketTransportService - > Shutdown ( ) ;
2012-09-18 03:45:10 +04:00
NS_ASSERTION ( NS_SUCCEEDED ( rv ) , " socket transport service shutdown failed " ) ;
}
}
2011-10-17 18:59:28 +04:00
mSettingOffline = false ;
2009-02-22 22:09:09 +03:00
2000-01-05 05:44:23 +03:00
return NS_OK ;
}
2015-05-02 00:14:39 +03:00
NS_IMETHODIMP
nsIOService : : GetConnectivity ( bool * aConnectivity )
{
* aConnectivity = mConnectivity ;
return NS_OK ;
}
NS_IMETHODIMP
nsIOService : : SetConnectivity ( bool aConnectivity )
{
2015-11-18 17:25:39 +03:00
LOG ( ( " nsIOService::SetConnectivity aConnectivity=%d \n " , aConnectivity ) ) ;
2015-05-02 00:14:39 +03:00
// This should only be called from ContentChild to pass the connectivity
// value from the chrome process to the content process.
2015-07-04 04:29:00 +03:00
if ( XRE_IsParentProcess ( ) ) {
2015-05-02 00:14:39 +03:00
return NS_ERROR_NOT_AVAILABLE ;
}
return SetConnectivityInternal ( aConnectivity ) ;
}
nsresult
nsIOService : : SetConnectivityInternal ( bool aConnectivity )
{
2015-11-18 17:25:39 +03:00
LOG ( ( " nsIOService::SetConnectivityInternal aConnectivity=%d \n " , aConnectivity ) ) ;
2015-05-02 00:14:39 +03:00
if ( mConnectivity = = aConnectivity ) {
// Nothing to do here.
return NS_OK ;
}
mConnectivity = aConnectivity ;
2015-07-07 12:13:00 +03:00
// This is used for PR_Connect PR_Close telemetry so it is important that
// we have statistic about network change event even if we are offline.
mLastConnectivityChange = PR_IntervalNow ( ) ;
2016-05-19 05:02:57 +03:00
nsCOMPtr < nsIObserverService > observerService = services : : GetObserverService ( ) ;
2015-05-02 00:14:39 +03:00
if ( ! observerService ) {
return NS_OK ;
}
// This notification sends the connectivity to the child processes
2015-07-04 04:29:00 +03:00
if ( XRE_IsParentProcess ( ) ) {
2015-05-02 00:14:39 +03:00
observerService - > NotifyObservers ( nullptr ,
NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC , aConnectivity ?
2016-07-21 08:03:25 +03:00
u " true " :
u " false " ) ;
2015-05-02 00:14:39 +03:00
}
if ( mOffline ) {
// We don't need to send any notifications if we're offline
return NS_OK ;
}
if ( aConnectivity ) {
// If we were previously offline due to connectivity=false,
// send the ONLINE notification
observerService - > NotifyObservers (
static_cast < nsIIOService * > ( this ) ,
NS_IOSERVICE_OFFLINE_STATUS_TOPIC ,
2016-07-20 07:07:53 +03:00
( u " " NS_IOSERVICE_ONLINE ) ) ;
2015-05-02 00:14:39 +03:00
} else {
// If we were previously online and lost connectivity
// send the OFFLINE notification
2016-07-20 07:07:53 +03:00
const nsLiteralString offlineString ( u " " NS_IOSERVICE_OFFLINE ) ;
2015-05-02 00:14:39 +03:00
observerService - > NotifyObservers ( static_cast < nsIIOService * > ( this ) ,
NS_IOSERVICE_GOING_OFFLINE_TOPIC ,
offlineString . get ( ) ) ;
observerService - > NotifyObservers ( static_cast < nsIIOService * > ( this ) ,
NS_IOSERVICE_OFFLINE_STATUS_TOPIC ,
offlineString . get ( ) ) ;
}
return NS_OK ;
}
2000-08-22 11:03:33 +04:00
2001-06-06 04:10:09 +04:00
NS_IMETHODIMP
2012-08-22 19:56:38 +04:00
nsIOService : : AllowPort ( int32_t inPort , const char * scheme , bool * _retval )
2001-06-06 04:10:09 +04:00
{
2012-08-22 19:56:38 +04:00
int16_t port = inPort ;
2001-06-06 04:10:09 +04:00
if ( port = = - 1 ) {
2011-10-17 18:59:28 +04:00
* _retval = true ;
2001-06-06 04:10:09 +04:00
return NS_OK ;
}
2014-01-05 00:42:42 +04:00
if ( port = = 0 ) {
* _retval = false ;
return NS_OK ;
}
2001-06-06 04:10:09 +04:00
// first check to see if the port is in our blacklist:
2012-08-22 19:56:38 +04:00
int32_t badPortListCnt = mRestrictedPortList . Length ( ) ;
2001-06-06 04:10:09 +04:00
for ( int i = 0 ; i < badPortListCnt ; i + + )
{
2009-02-23 04:05:28 +03:00
if ( port = = mRestrictedPortList [ i ] )
2001-06-06 04:10:09 +04:00
{
2011-10-17 18:59:28 +04:00
* _retval = false ;
2001-06-06 04:10:09 +04: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 18:59:28 +04:00
* _retval = true ;
2001-06-06 04:10:09 +04:00
return NS_OK ;
}
2000-01-27 11:57:14 +03:00
////////////////////////////////////////////////////////////////////////////////
2001-10-09 02:27:14 +04:00
void
nsIOService : : PrefsChanged ( nsIPrefBranch * prefs , const char * pref )
{
if ( ! prefs ) return ;
// Look for extra ports to block
2003-06-25 05:13:30 +04:00
if ( ! pref | | strcmp ( pref , PORT_PREF ( " banned " ) ) = = 0 )
2011-10-17 18:59:28 +04:00
ParsePortList ( prefs , PORT_PREF ( " banned " ) , false ) ;
2001-10-09 02:27:14 +04:00
// ...as well as previous blocks to remove.
2003-06-25 05:13:30 +04:00
if ( ! pref | | strcmp ( pref , PORT_PREF ( " banned.override " ) ) = = 0 )
2011-10-17 18:59:28 +04:00
ParsePortList ( prefs , PORT_PREF ( " banned.override " ) , true ) ;
2002-06-29 03:03:52 +04:00
2009-01-13 08:52:00 +03:00
if ( ! pref | | strcmp ( pref , MANAGE_OFFLINE_STATUS_PREF ) = = 0 ) {
2011-09-29 10:19:26 +04:00
bool manage ;
2013-01-15 04:29:35 +04:00
if ( mNetworkLinkServiceInitialized & &
NS_SUCCEEDED ( prefs - > GetBoolPref ( MANAGE_OFFLINE_STATUS_PREF ,
2015-11-18 17:25:39 +03:00
& manage ) ) ) {
LOG ( ( " nsIOService::PrefsChanged ManageOfflineStatus manage=%d \n " , manage ) ) ;
2009-01-13 08:52:00 +03:00
SetManageOfflineStatus ( manage ) ;
2015-11-18 17:25:39 +03:00
}
2009-01-13 08:52:00 +03:00
}
2010-04-20 20:32:28 +04:00
if ( ! pref | | strcmp ( pref , NECKO_BUFFER_CACHE_COUNT_PREF ) = = 0 ) {
2012-08-22 19:56:38 +04:00
int32_t count ;
2010-04-20 20:32:28 +04: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 19:56:38 +04:00
int32_t size ;
2010-04-20 20:32:28 +04: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-10 07:43:52 +04:00
NS_WARN_IF_FALSE ( ( ! ( size & ( size - 1 ) ) ) , " network segment size is not a power of 2! " ) ;
2010-04-20 20:32:28 +04:00
}
2014-09-19 14:36:00 +04: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 ;
}
}
2014-10-14 01:35:51 +04:00
if ( ! pref | | strcmp ( pref , NETWORK_CAPTIVE_PORTAL_PREF ) = = 0 ) {
bool captivePortalEnabled ;
nsresult rv = prefs - > GetBoolPref ( NETWORK_CAPTIVE_PORTAL_PREF , & captivePortalEnabled ) ;
if ( NS_SUCCEEDED ( rv ) & & mCaptivePortalService ) {
2016-06-07 16:17:42 +03:00
if ( captivePortalEnabled & & ! xpc : : AreNonLocalConnectionsDisabled ( ) ) {
2014-10-14 01:35:51 +04:00
static_cast < CaptivePortalService * > ( mCaptivePortalService . get ( ) ) - > Start ( ) ;
} else {
static_cast < CaptivePortalService * > ( mCaptivePortalService . get ( ) ) - > Stop ( ) ;
}
}
}
2001-10-09 02:27:14 +04:00
}
void
2011-09-29 10:19:26 +04:00
nsIOService : : ParsePortList ( nsIPrefBranch * prefBranch , const char * pref , bool remove )
2001-10-09 02:27:14 +04: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-22 07:15:34 +03:00
nsTArray < nsCString > portListArray ;
ParseString ( portList , ' , ' , portListArray ) ;
2012-08-22 19:56:38 +04:00
uint32_t index ;
2009-01-22 07:15:34 +03:00
for ( index = 0 ; index < portListArray . Length ( ) ; index + + ) {
portListArray [ index ] . StripWhitespace ( ) ;
2012-08-22 19:56:38 +04:00
int32_t portBegin , portEnd ;
2002-06-14 00:51:03 +04:00
2009-01-22 07:15:34 +03:00
if ( PR_sscanf ( portListArray [ index ] . get ( ) , " %d-%d " , & portBegin , & portEnd ) = = 2 ) {
2002-06-14 00:51:03 +04:00
if ( ( portBegin < 65536 ) & & ( portEnd < 65536 ) ) {
2012-08-22 19:56:38 +04:00
int32_t curPort ;
2002-06-14 00:51:03 +04:00
if ( remove ) {
for ( curPort = portBegin ; curPort < = portEnd ; curPort + + )
2009-02-23 04:05:28 +03:00
mRestrictedPortList . RemoveElement ( curPort ) ;
2002-06-14 00:51:03 +04:00
} else {
for ( curPort = portBegin ; curPort < = portEnd ; curPort + + )
2009-02-23 04:05:28 +03:00
mRestrictedPortList . AppendElement ( curPort ) ;
2002-06-14 00:51:03 +04:00
}
}
} else {
2012-07-27 17:59:29 +04:00
nsresult aErrorCode ;
2012-08-22 19:56:38 +04:00
int32_t port = portListArray [ index ] . ToInteger ( & aErrorCode ) ;
2002-06-14 00:51:03 +04:00
if ( NS_SUCCEEDED ( aErrorCode ) & & port < 65536 ) {
if ( remove )
2009-02-23 04:05:28 +03:00
mRestrictedPortList . RemoveElement ( port ) ;
2002-06-14 00:51:03 +04:00
else
2009-02-23 04:05:28 +03:00
mRestrictedPortList . AppendElement ( port ) ;
2002-06-14 00:51:03 +04:00
}
}
2001-10-09 02:27:14 +04:00
}
}
}
void
2012-01-17 05:48:29 +04:00
nsIOService : : GetPrefBranch ( nsIPrefBranch * * result )
2001-10-09 02:27:14 +04:00
{
2012-07-30 18:20:58 +04:00
* result = nullptr ;
2004-01-29 02:45:17 +03:00
CallGetService ( NS_PREFSERVICE_CONTRACTID , result ) ;
2001-10-09 02:27:14 +04:00
}
2014-08-23 07:05:56 +04:00
// This returns true if wifi-only apps should have connectivity.
2014-08-22 21:15:00 +04:00
// Always returns false in the child process (should not depend on this method)
2014-08-23 07:05:56 +04:00
static bool
IsWifiActive ( )
{
// We don't need to do this check inside the child process
2014-08-22 21:15:00 +04:00
if ( IsNeckoChild ( ) ) {
2014-08-23 07:05:56 +04:00
return false ;
}
# ifdef MOZ_WIDGET_GONK
// On B2G we query the network manager for the active interface
nsCOMPtr < nsINetworkManager > networkManager =
do_GetService ( " @mozilla.org/network/manager;1 " ) ;
if ( ! networkManager ) {
return false ;
}
2015-07-29 09:14:00 +03:00
nsCOMPtr < nsINetworkInfo > activeNetworkInfo ;
networkManager - > GetActiveNetworkInfo ( getter_AddRefs ( activeNetworkInfo ) ) ;
if ( ! activeNetworkInfo ) {
2014-08-23 07:05:56 +04:00
return false ;
}
int32_t type ;
2015-07-29 09:14:00 +03:00
if ( NS_FAILED ( activeNetworkInfo - > GetType ( & type ) ) ) {
2014-08-23 07:05:56 +04:00
return false ;
}
switch ( type ) {
2015-07-29 09:14:00 +03:00
case nsINetworkInfo : : NETWORK_TYPE_WIFI :
case nsINetworkInfo : : NETWORK_TYPE_WIFI_P2P :
2014-08-23 07:05:56 +04:00
return true ;
default :
return false ;
}
# else
// On anything else than B2G we return true so than wifi-only
// apps don't think they are offline.
return true ;
# endif
}
2015-07-31 23:39:48 +03:00
class
2016-04-26 03:23:21 +03:00
nsWakeupNotifier : public Runnable
2015-07-31 23:39:48 +03:00
{
public :
explicit nsWakeupNotifier ( nsIIOServiceInternal * ioService )
: mIOService ( ioService )
{ }
NS_IMETHOD Run ( )
{
return mIOService - > NotifyWakeup ( ) ;
}
private :
virtual ~ nsWakeupNotifier ( ) { }
nsCOMPtr < nsIIOServiceInternal > mIOService ;
} ;
NS_IMETHODIMP
nsIOService : : NotifyWakeup ( )
{
2016-05-19 05:02:57 +03:00
nsCOMPtr < nsIObserverService > observerService = services : : GetObserverService ( ) ;
2015-07-31 23:39:48 +03:00
NS_ASSERTION ( observerService , " The observer service should not be null " ) ;
if ( observerService & & mNetworkNotifyChanged ) {
( void ) observerService - >
NotifyObservers ( nullptr ,
NS_NETWORK_LINK_TOPIC ,
2016-07-20 07:07:53 +03:00
( u " " NS_NETWORK_LINK_DATA_CHANGED ) ) ;
2015-07-31 23:39:48 +03:00
}
2016-05-18 00:55:52 +03:00
RecheckCaptivePortal ( ) ;
2015-07-31 23:39:48 +03:00
return NS_OK ;
}
2016-02-04 06:14:00 +03:00
void
nsIOService : : SetHttpHandlerAlreadyShutingDown ( )
{
if ( ! mShutdown & & ! mOfflineForProfileChange ) {
mNetTearingDownStarted = PR_IntervalNow ( ) ;
mHttpHandlerAlreadyShutingDown = true ;
}
}
2001-10-09 02:27:14 +04:00
// nsIObserver interface
NS_IMETHODIMP
nsIOService : : Observe ( nsISupports * subject ,
2001-10-20 00:52:59 +04:00
const char * topic ,
2014-01-04 19:02:17 +04:00
const char16_t * data )
2001-10-09 02:27:14 +04:00
{
2002-05-31 03:11:49 +04:00
if ( ! strcmp ( topic , NS_PREFBRANCH_PREFCHANGE_TOPIC_ID ) ) {
2001-10-09 02:27:14 +04:00
nsCOMPtr < nsIPrefBranch > prefBranch = do_QueryInterface ( subject ) ;
if ( prefBranch )
2006-02-03 17:18:39 +03:00
PrefsChanged ( prefBranch , NS_ConvertUTF16toUTF8 ( data ) . get ( ) ) ;
2014-09-19 14:34:00 +04:00
} else if ( ! strcmp ( topic , kProfileChangeNetTeardownTopic ) ) {
2016-02-04 06:14:00 +03:00
if ( ! mHttpHandlerAlreadyShutingDown ) {
mNetTearingDownStarted = PR_IntervalNow ( ) ;
}
mHttpHandlerAlreadyShutingDown = false ;
2001-11-07 07:26:19 +03:00
if ( ! mOffline ) {
2011-10-17 18:59:28 +04:00
mOfflineForProfileChange = true ;
2012-11-30 01:07:37 +04:00
SetOffline ( true ) ;
2001-11-07 07:26:19 +03:00
}
2014-09-19 14:34:00 +04:00
} else if ( ! strcmp ( topic , kProfileChangeNetRestoreTopic ) ) {
2001-11-07 07:26:19 +03:00
if ( mOfflineForProfileChange ) {
2011-10-17 18:59:28 +04:00
mOfflineForProfileChange = false ;
2015-05-02 00:14:39 +03:00
SetOffline ( false ) ;
}
2014-09-19 14:34:00 +04:00
} else if ( ! strcmp ( topic , kProfileDoChange ) ) {
2011-10-18 13:46:59 +04: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 ;
2015-05-02 00:14:39 +03:00
2013-01-15 04:29:35 +04:00
// And now reflect the preference setting
nsCOMPtr < nsIPrefBranch > prefBranch ;
GetPrefBranch ( getter_AddRefs ( prefBranch ) ) ;
PrefsChanged ( prefBranch , MANAGE_OFFLINE_STATUS_PREF ) ;
2011-10-18 13:46:59 +04:00
}
2014-09-19 14:34:00 +04:00
} else if ( ! strcmp ( topic , NS_XPCOM_SHUTDOWN_OBSERVER_ID ) ) {
2009-03-18 17:52:31 +03: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 18:59:28 +04:00
mShutdown = true ;
2016-02-04 06:14:00 +03:00
if ( ! mHttpHandlerAlreadyShutingDown & & ! mOfflineForProfileChange ) {
2016-01-18 10:20:00 +03:00
mNetTearingDownStarted = PR_IntervalNow ( ) ;
}
2016-02-04 06:14:00 +03:00
mHttpHandlerAlreadyShutingDown = false ;
2011-10-17 18:59:28 +04:00
SetOffline ( true ) ;
2003-01-18 05:15:14 +03:00
2014-10-14 01:35:51 +04:00
if ( mCaptivePortalService ) {
static_cast < CaptivePortalService * > ( mCaptivePortalService . get ( ) ) - > Stop ( ) ;
2015-07-13 16:50:58 +03:00
mCaptivePortalService = nullptr ;
2014-10-14 01:35:51 +04:00
}
2002-11-06 16:03:49 +03:00
// Break circular reference.
2012-07-30 18:20:58 +04:00
mProxyService = nullptr ;
2014-09-25 07:14:00 +04:00
} else if ( ! strcmp ( topic , NS_NETWORK_LINK_TOPIC ) ) {
2015-05-02 00:14:39 +03:00
OnNetworkLinkEvent ( NS_ConvertUTF16toUTF8 ( data ) . get ( ) ) ;
2014-09-19 14:34:00 +04:00
} else if ( ! strcmp ( topic , NS_WIDGET_WAKE_OBSERVER_TOPIC ) ) {
// coming back alive from sleep
2015-07-31 23:39:48 +03:00
// this indirection brought to you by:
// https://bugzilla.mozilla.org/show_bug.cgi?id=1152048#c19
nsCOMPtr < nsIRunnable > wakeupNotifier = new nsWakeupNotifier ( this ) ;
NS_DispatchToMainThread ( wakeupNotifier ) ;
2014-08-23 07:05:56 +04:00
} else if ( ! strcmp ( topic , kNetworkActiveChanged ) ) {
# ifdef MOZ_WIDGET_GONK
if ( IsNeckoChild ( ) ) {
return NS_OK ;
}
2015-07-29 09:14:00 +03:00
nsCOMPtr < nsINetworkInfo > interface = do_QueryInterface ( subject ) ;
2014-08-23 07:05:56 +04:00
if ( ! interface ) {
return NS_ERROR_FAILURE ;
}
int32_t state ;
if ( NS_FAILED ( interface - > GetState ( & state ) ) ) {
return NS_ERROR_FAILURE ;
}
bool wifiActive = IsWifiActive ( ) ;
int32_t newWifiState = wifiActive ?
2015-07-29 09:14:00 +03:00
nsINetworkInfo : : NETWORK_TYPE_WIFI :
nsINetworkInfo : : NETWORK_TYPE_MOBILE ;
2014-08-23 07:05:56 +04:00
if ( mPreviousWifiState ! = newWifiState ) {
// Notify wifi-only apps of their new status
int32_t status = wifiActive ?
nsIAppOfflineInfo : : ONLINE : nsIAppOfflineInfo : : OFFLINE ;
2015-11-20 03:46:35 +03:00
for ( auto it = mAppsOfflineStatus . Iter ( ) ; ! it . Done ( ) ; it . Next ( ) ) {
2015-11-30 02:25:32 +03:00
if ( it . UserData ( ) = = nsIAppOfflineInfo : : WIFI_ONLY ) {
NotifyAppOfflineStatus ( it . Key ( ) , status ) ;
2015-11-20 03:46:35 +03:00
}
}
2014-08-23 07:05:56 +04:00
}
mPreviousWifiState = newWifiState ;
# endif
2014-08-26 23:56:51 +04:00
}
2014-09-25 07:14:00 +04:00
2001-10-09 02:27:14 +04:00
return NS_OK ;
}
2005-07-26 00:27:04 +04:00
2015-10-01 21:36:19 +03:00
// nsINetUtil interface
NS_IMETHODIMP
nsIOService : : ParseRequestContentType ( const nsACString & aTypeHeader ,
nsACString & aCharset ,
bool * aHadCharset ,
nsACString & aContentType )
{
net_ParseRequestContentType ( aTypeHeader , aContentType , aCharset , aHadCharset ) ;
return NS_OK ;
}
2005-07-26 00:27:04 +04:00
// nsINetUtil interface
NS_IMETHODIMP
2015-10-01 19:50:13 +03:00
nsIOService : : ParseResponseContentType ( const nsACString & aTypeHeader ,
nsACString & aCharset ,
bool * aHadCharset ,
nsACString & aContentType )
2005-07-26 00:27:04 +04:00
{
2006-04-05 01:26:17 +04:00
net_ParseContentType ( aTypeHeader , aContentType , aCharset , aHadCharset ) ;
return NS_OK ;
}
2006-05-02 22:54:19 +04:00
NS_IMETHODIMP
nsIOService : : ProtocolHasFlags ( nsIURI * uri ,
2012-08-22 19:56:38 +04:00
uint32_t flags ,
2011-09-29 10:19:26 +04:00
bool * result )
2006-05-02 22:54:19 +04:00
{
NS_ENSURE_ARG ( uri ) ;
2011-10-17 18:59:28 +04:00
* result = false ;
2012-09-02 06:35:17 +04:00
nsAutoCString scheme ;
2006-05-02 22:54:19 +04:00
nsresult rv = uri - > GetScheme ( scheme ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
2015-07-27 23:27:38 +03:00
// Grab the protocol flags from the URI.
2012-08-22 19:56:38 +04:00
uint32_t protocolFlags ;
2015-07-27 23:27:38 +03:00
nsCOMPtr < nsIProtocolHandler > handler ;
rv = GetProtocolHandler ( scheme . get ( ) , getter_AddRefs ( handler ) ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
rv = handler - > DoGetProtocolFlags ( uri , & protocolFlags ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
2006-05-02 22:54:19 +04:00
2015-07-27 23:27:38 +03:00
* result = ( protocolFlags & flags ) = = flags ;
return NS_OK ;
2006-05-02 22:54:19 +04:00
}
NS_IMETHODIMP
nsIOService : : URIChainHasFlags ( nsIURI * uri ,
2012-08-22 19:56:38 +04:00
uint32_t flags ,
2011-09-29 10:19:26 +04:00
bool * result )
2006-05-02 22:54:19 +04: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 ;
}
2006-05-31 21:57:14 +04:00
NS_IMETHODIMP
nsIOService : : ToImmutableURI ( nsIURI * uri , nsIURI * * result )
{
if ( ! uri ) {
2012-07-30 18:20:58 +04:00
* result = nullptr ;
2006-05-31 21:57:14 +04:00
return NS_OK ;
}
nsresult rv = NS_EnsureSafeToReturn ( uri , result ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
NS_TryToSetImmutable ( * result ) ;
return NS_OK ;
}
2009-08-24 02:48:07 +04: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 ;
}
2006-04-05 01:26:17 +04:00
NS_IMETHODIMP
2014-09-25 07:14:00 +04:00
nsIOService : : SetManageOfflineStatus ( bool aManage )
{
2015-11-18 17:25:39 +03:00
LOG ( ( " nsIOService::SetManageOfflineStatus aManage=%d \n " , aManage ) ) ;
2015-05-02 00:14:39 +03:00
mManageLinkStatus = aManage ;
2011-10-18 13:46:59 +04:00
2015-05-02 00:14:39 +03:00
// When detection is not activated, the default connectivity state is true.
if ( ! mManageLinkStatus ) {
SetConnectivityInternal ( true ) ;
return NS_OK ;
}
2011-10-18 13:46:59 +04:00
2012-03-08 20:24:17 +04:00
InitializeNetworkLinkService ( ) ;
2015-05-02 00:14:39 +03:00
// If the NetworkLinkService is already initialized, it does not call
// OnNetworkLinkEvent. This is needed, when mManageLinkStatus goes from
// false to true.
OnNetworkLinkEvent ( NS_NETWORK_LINK_DATA_UNKNOWN ) ;
return NS_OK ;
2006-04-05 01:26:17 +04:00
}
NS_IMETHODIMP
2015-05-02 00:14:39 +03:00
nsIOService : : GetManageOfflineStatus ( bool * aManage )
{
* aManage = mManageLinkStatus ;
2006-04-05 01:26:17 +04:00
return NS_OK ;
}
2014-09-25 07:14:00 +04:00
// input argument 'data' is already UTF8'ed
2006-04-05 01:26:17 +04:00
nsresult
2014-09-25 07:14:00 +04:00
nsIOService : : OnNetworkLinkEvent ( const char * data )
2006-04-05 01:26:17 +04:00
{
2015-11-18 17:25:39 +03:00
LOG ( ( " nsIOService::OnNetworkLinkEvent data:%s \n " , data ) ) ;
2006-04-05 01:26:17 +04:00
if ( ! mNetworkLinkService )
return NS_ERROR_FAILURE ;
2009-03-18 17:52:31 +03:00
if ( mShutdown )
return NS_ERROR_NOT_AVAILABLE ;
2014-09-25 07:14:00 +04:00
2015-05-02 00:14:39 +03:00
if ( ! mManageLinkStatus ) {
2015-11-18 17:25:39 +03:00
LOG ( ( " nsIOService::OnNetworkLinkEvent mManageLinkStatus=false \n " ) ) ;
return NS_OK ;
2015-02-20 18:10:33 +03:00
}
2015-05-02 00:14:39 +03:00
bool isUp = true ;
2015-03-12 11:46:00 +03:00
if ( ! strcmp ( data , NS_NETWORK_LINK_DATA_CHANGED ) ) {
2015-07-07 12:13:00 +03:00
mLastNetworkLinkChange = PR_IntervalNow ( ) ;
2015-03-12 11:46:00 +03:00
// CHANGED means UP/DOWN didn't change
return NS_OK ;
} else if ( ! strcmp ( data , NS_NETWORK_LINK_DATA_DOWN ) ) {
2014-09-25 07:14:00 +04:00
isUp = false ;
} else if ( ! strcmp ( data , NS_NETWORK_LINK_DATA_UP ) ) {
2016-05-18 00:55:52 +03:00
// Interface is up. Triggering a captive portal recheck.
RecheckCaptivePortal ( ) ;
2014-09-25 07:14:00 +04:00
isUp = true ;
2015-03-12 11:46:00 +03:00
} else if ( ! strcmp ( data , NS_NETWORK_LINK_DATA_UNKNOWN ) ) {
2014-09-25 07:14:00 +04:00
nsresult rv = mNetworkLinkService - > GetIsLinkUp ( & isUp ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
} else {
NS_WARNING ( " Unhandled network event! " ) ;
return NS_OK ;
}
2015-02-16 20:25:40 +03:00
2015-05-02 00:14:39 +03:00
return SetConnectivityInternal ( isUp ) ;
2005-07-26 00:27:04 +04:00
}
2006-05-02 20:27:23 +04:00
NS_IMETHODIMP
nsIOService : : EscapeString ( const nsACString & aString ,
2012-08-22 19:56:38 +04:00
uint32_t aEscapeType ,
2006-05-02 20:27:23 +04:00
nsACString & aResult )
{
2012-03-24 12:18:09 +04:00
NS_ENSURE_ARG_MAX ( aEscapeType , 4 ) ;
2006-05-02 20:27:23 +04:00
2012-09-02 06:35:17 +04:00
nsAutoCString stringCopy ( aString ) ;
2006-05-02 20:27:23 +04: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 18:19:04 +04:00
2007-06-22 00:18:25 +04:00
NS_IMETHODIMP
nsIOService : : EscapeURL ( const nsACString & aStr ,
2012-08-22 19:56:38 +04:00
uint32_t aFlags , nsACString & aResult )
2007-04-23 18:19:04 +04:00
{
2007-06-22 00:18:25 +04:00
aResult . Truncate ( ) ;
2008-09-15 17:34:46 +04:00
NS_EscapeURL ( aStr . BeginReading ( ) , aStr . Length ( ) ,
aFlags | esc_AlwaysCopy , aResult ) ;
2007-06-22 00:18:25 +04:00
return NS_OK ;
}
2007-04-23 18:19:04 +04:00
2007-06-22 00:18:25 +04:00
NS_IMETHODIMP
nsIOService : : UnescapeString ( const nsACString & aStr ,
2012-08-22 19:56:38 +04:00
uint32_t aFlags , nsACString & aResult )
2007-06-22 00:18:25 +04:00
{
aResult . Truncate ( ) ;
2008-09-15 17:34:46 +04:00
NS_UnescapeURL ( aStr . BeginReading ( ) , aStr . Length ( ) ,
aFlags | esc_AlwaysCopy , aResult ) ;
2007-04-23 18:19:04 +04:00
return NS_OK ;
}
2007-06-22 00:18:25 +04:00
2007-12-04 00:34:44 +03:00
NS_IMETHODIMP
nsIOService : : ExtractCharsetFromContentType ( const nsACString & aTypeHeader ,
nsACString & aCharset ,
2012-08-22 19:56:38 +04:00
int32_t * aCharsetStart ,
int32_t * aCharsetEnd ,
2011-09-29 10:19:26 +04:00
bool * aHadCharset )
2007-12-04 00:34:44 +03:00
{
2012-09-02 06:35:17 +04:00
nsAutoCString ignored ;
2007-12-04 00:34:44 +03:00
net_ParseContentType ( aTypeHeader , ignored , aCharset , aHadCharset ,
aCharsetStart , aCharsetEnd ) ;
2008-02-29 07:24:32 +03:00
if ( * aHadCharset & & * aCharsetStart = = * aCharsetEnd ) {
2011-10-17 18:59:28 +04:00
* aHadCharset = false ;
2007-12-04 00:34:44 +03:00
}
return NS_OK ;
}
2012-04-25 16:54:42 +04:00
2015-06-06 01:25:24 +03:00
// parse policyString to policy enum value (see ReferrerPolicy.h)
NS_IMETHODIMP
nsIOService : : ParseAttributePolicyString ( const nsAString & policyString ,
uint32_t * outPolicyEnum )
{
NS_ENSURE_ARG ( outPolicyEnum ) ;
2016-05-19 05:02:57 +03:00
* outPolicyEnum = ( uint32_t ) AttributeReferrerPolicyFromString ( policyString ) ;
2015-06-06 01:25:24 +03:00
return NS_OK ;
}
2012-04-25 16:54:42 +04:00
// nsISpeculativeConnect
2015-03-21 19:28:04 +03:00
class IOServiceProxyCallback final : public nsIProtocolProxyCallback
2012-09-15 00:27:46 +04:00
{
2014-06-24 20:36:44 +04:00
~ IOServiceProxyCallback ( ) { }
2012-09-15 00:27:46 +04:00
public :
NS_DECL_ISUPPORTS
NS_DECL_NSIPROTOCOLPROXYCALLBACK
IOServiceProxyCallback ( nsIInterfaceRequestor * aCallbacks ,
nsIOService * aIOService )
: mCallbacks ( aCallbacks )
, mIOService ( aIOService )
{ }
private :
2015-10-18 08:24:48 +03:00
RefPtr < nsIInterfaceRequestor > mCallbacks ;
RefPtr < nsIOService > mIOService ;
2012-09-15 00:27:46 +04:00
} ;
2014-04-27 11:06:00 +04:00
NS_IMPL_ISUPPORTS ( IOServiceProxyCallback , nsIProtocolProxyCallback )
2012-09-15 00:27:46 +04:00
2012-04-25 16:54:42 +04:00
NS_IMETHODIMP
2015-01-21 23:13:00 +03:00
IOServiceProxyCallback : : OnProxyAvailable ( nsICancelable * request , nsIChannel * channel ,
2012-09-15 00:27:46 +04:00
nsIProxyInfo * pi , nsresult status )
2012-04-25 16:54:42 +04:00
{
2012-09-15 00:27:46 +04: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 ;
}
2015-01-21 23:13:00 +03:00
nsCOMPtr < nsIURI > uri ;
nsresult rv = channel - > GetURI ( getter_AddRefs ( uri ) ) ;
if ( NS_FAILED ( rv ) ) {
return NS_OK ;
}
2012-09-02 06:35:17 +04:00
nsAutoCString scheme ;
2015-01-21 23:13:00 +03:00
rv = uri - > GetScheme ( scheme ) ;
2012-04-25 16:54:42 +04:00
if ( NS_FAILED ( rv ) )
return NS_OK ;
nsCOMPtr < nsIProtocolHandler > handler ;
2012-09-15 00:27:46 +04:00
rv = mIOService - > GetProtocolHandler ( scheme . get ( ) ,
getter_AddRefs ( handler ) ) ;
2012-04-25 16:54:42 +04:00
if ( NS_FAILED ( rv ) )
2012-09-15 00:27:46 +04:00
return NS_OK ;
2012-04-25 16:54:42 +04:00
nsCOMPtr < nsISpeculativeConnect > speculativeHandler =
do_QueryInterface ( handler ) ;
2012-04-28 00:18:21 +04:00
if ( ! speculativeHandler )
2012-04-25 16:54:42 +04:00
return NS_OK ;
2015-05-06 04:15:36 +03:00
nsLoadFlags loadFlags = 0 ;
channel - > GetLoadFlags ( & loadFlags ) ;
if ( loadFlags & nsIRequest : : LOAD_ANONYMOUS ) {
speculativeHandler - > SpeculativeAnonymousConnect ( uri , mCallbacks ) ;
} else {
speculativeHandler - > SpeculativeConnect ( uri , mCallbacks ) ;
}
2012-09-15 00:27:46 +04:00
return NS_OK ;
}
2015-05-06 04:15:36 +03:00
nsresult
nsIOService : : SpeculativeConnectInternal ( nsIURI * aURI ,
nsIInterfaceRequestor * aCallbacks ,
bool aAnonymous )
2012-09-15 00:27:46 +04:00
{
2016-05-17 22:51:24 +03:00
if ( IsNeckoChild ( ) ) {
ipc : : URIParams params ;
SerializeURI ( aURI , params ) ;
gNeckoChild - > SendSpeculativeConnect ( params , aAnonymous ) ;
return NS_OK ;
}
2012-09-15 00:27:46 +04: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 ) ;
2015-03-20 22:27:34 +03:00
NS_ENSURE_SUCCESS ( rv , rv ) ;
2012-09-15 00:27:46 +04:00
2015-03-20 22:27:34 +03:00
nsCOMPtr < nsIScriptSecurityManager > secMan (
do_GetService ( NS_SCRIPTSECURITYMANAGER_CONTRACTID , & rv ) ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
nsCOMPtr < nsIPrincipal > systemPrincipal ;
rv = secMan - > GetSystemPrincipal ( getter_AddRefs ( systemPrincipal ) ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
// dummy channel used to create a TCP connection.
// we perform security checks on the *real* channel, responsible
// for any network loads. this real channel just checks the TCP
// pool if there is an available connection created by the
// channel we create underneath - hence it's safe to use
// the systemPrincipal as the loadingPrincipal for this channel.
2015-01-21 23:13:00 +03:00
nsCOMPtr < nsIChannel > channel ;
2015-03-20 22:27:34 +03:00
rv = NewChannelFromURI2 ( aURI ,
nullptr , // aLoadingNode,
systemPrincipal ,
nullptr , //aTriggeringPrincipal,
2016-03-10 00:55:59 +03:00
nsILoadInfo : : SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL ,
2015-03-20 22:27:34 +03:00
nsIContentPolicy : : TYPE_OTHER ,
getter_AddRefs ( channel ) ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
2015-01-21 23:13:00 +03:00
2015-05-06 04:15:36 +03:00
if ( aAnonymous ) {
nsLoadFlags loadFlags = 0 ;
channel - > GetLoadFlags ( & loadFlags ) ;
loadFlags | = nsIRequest : : LOAD_ANONYMOUS ;
channel - > SetLoadFlags ( loadFlags ) ;
}
2012-09-15 00:27:46 +04:00
nsCOMPtr < nsICancelable > cancelable ;
2015-10-18 08:24:48 +03:00
RefPtr < IOServiceProxyCallback > callback =
2012-11-14 20:00:44 +04:00
new IOServiceProxyCallback ( aCallbacks , this ) ;
2015-03-14 00:32:18 +03:00
nsCOMPtr < nsIProtocolProxyService2 > pps2 = do_QueryInterface ( pps ) ;
if ( pps2 ) {
return pps2 - > AsyncResolve2 ( channel , 0 , callback , getter_AddRefs ( cancelable ) ) ;
}
2015-01-21 23:13:00 +03:00
return pps - > AsyncResolve ( channel , 0 , callback , getter_AddRefs ( cancelable ) ) ;
2012-04-25 16:54:42 +04:00
}
2014-08-23 07:05:56 +04:00
2015-05-06 04:15:36 +03:00
NS_IMETHODIMP
nsIOService : : SpeculativeConnect ( nsIURI * aURI ,
nsIInterfaceRequestor * aCallbacks )
{
return SpeculativeConnectInternal ( aURI , aCallbacks , false ) ;
}
NS_IMETHODIMP
nsIOService : : SpeculativeAnonymousConnect ( nsIURI * aURI ,
nsIInterfaceRequestor * aCallbacks )
{
return SpeculativeConnectInternal ( aURI , aCallbacks , true ) ;
}
2014-08-23 07:05:56 +04:00
void
nsIOService : : NotifyAppOfflineStatus ( uint32_t appId , int32_t state )
{
MOZ_RELEASE_ASSERT ( NS_IsMainThread ( ) ,
" Should be called on the main thread " ) ;
2016-05-19 05:02:57 +03:00
nsCOMPtr < nsIObserverService > observerService = services : : GetObserverService ( ) ;
2014-08-23 07:05:56 +04:00
MOZ_ASSERT ( observerService , " The observer service should not be null " ) ;
if ( observerService ) {
2015-10-18 08:24:48 +03:00
RefPtr < nsAppOfflineInfo > info = new nsAppOfflineInfo ( appId , state ) ;
2014-08-23 07:05:56 +04:00
observerService - > NotifyObservers (
info ,
NS_IOSERVICE_APP_OFFLINE_STATUS_TOPIC ,
2016-07-21 08:03:25 +03:00
u " all data in nsIAppOfflineInfo subject argument " ) ;
2014-08-23 07:05:56 +04:00
}
}
namespace {
2016-04-26 03:23:21 +03:00
class SetAppOfflineMainThread : public Runnable
2014-08-23 07:05:56 +04:00
{
public :
SetAppOfflineMainThread ( uint32_t aAppId , int32_t aState )
: mAppId ( aAppId )
, mState ( aState )
{
}
NS_IMETHOD Run ( )
{
MOZ_ASSERT ( NS_IsMainThread ( ) ) ;
gIOService - > SetAppOfflineInternal ( mAppId , mState ) ;
return NS_OK ;
}
private :
uint32_t mAppId ;
int32_t mState ;
} ;
2015-07-13 18:25:42 +03:00
} // namespace
2014-08-23 07:05:56 +04:00
NS_IMETHODIMP
nsIOService : : SetAppOffline ( uint32_t aAppId , int32_t aState )
{
2014-08-22 21:15:00 +04:00
NS_ENSURE_TRUE ( ! IsNeckoChild ( ) ,
2014-08-23 07:05:56 +04:00
NS_ERROR_FAILURE ) ;
NS_ENSURE_TRUE ( aAppId ! = nsIScriptSecurityManager : : NO_APP_ID ,
NS_ERROR_INVALID_ARG ) ;
NS_ENSURE_TRUE ( aAppId ! = nsIScriptSecurityManager : : UNKNOWN_APP_ID ,
NS_ERROR_INVALID_ARG ) ;
if ( ! NS_IsMainThread ( ) ) {
NS_DispatchToMainThread ( new SetAppOfflineMainThread ( aAppId , aState ) ) ;
return NS_OK ;
}
SetAppOfflineInternal ( aAppId , aState ) ;
return NS_OK ;
}
2014-08-23 06:44:04 +04:00
// This method may be called in both the parent and the child process
// In parent it only gets called in from nsIOService::SetAppOffline
// and SetAppOfflineMainThread::Run
// In the child, it may get called from NeckoChild::RecvAppOfflineStatus
// and TabChild::RecvAppOfflineStatus.
// Note that in the child process, apps should never be in a WIFI_ONLY
// because wifi status is not available on the child
2014-08-23 07:05:56 +04:00
void
nsIOService : : SetAppOfflineInternal ( uint32_t aAppId , int32_t aState )
{
MOZ_ASSERT ( NS_IsMainThread ( ) ) ;
NS_ENSURE_TRUE_VOID ( NS_IsMainThread ( ) ) ;
2014-08-23 06:44:04 +04:00
int32_t state = nsIAppOfflineInfo : : ONLINE ;
mAppsOfflineStatus . Get ( aAppId , & state ) ;
if ( state = = aState ) {
2014-08-23 07:05:56 +04:00
// The app is already in this state. Nothing needs to be done.
return ;
}
2014-08-23 06:44:04 +04:00
// wifiActive will always be false in the child process
// but it will be true in the parent process on Desktop Firefox as it does
// not have wifi-detection capabilities
2014-08-23 07:05:56 +04:00
bool wifiActive = IsWifiActive ( ) ;
bool offline = ( state = = nsIAppOfflineInfo : : OFFLINE ) | |
( state = = nsIAppOfflineInfo : : WIFI_ONLY & & ! wifiActive ) ;
switch ( aState ) {
case nsIAppOfflineInfo : : OFFLINE :
mAppsOfflineStatus . Put ( aAppId , nsIAppOfflineInfo : : OFFLINE ) ;
if ( ! offline ) {
NotifyAppOfflineStatus ( aAppId , nsIAppOfflineInfo : : OFFLINE ) ;
}
break ;
case nsIAppOfflineInfo : : WIFI_ONLY :
2014-08-22 21:15:00 +04:00
MOZ_RELEASE_ASSERT ( ! IsNeckoChild ( ) ) ;
2014-08-23 07:05:56 +04:00
mAppsOfflineStatus . Put ( aAppId , nsIAppOfflineInfo : : WIFI_ONLY ) ;
if ( offline & & wifiActive ) {
NotifyAppOfflineStatus ( aAppId , nsIAppOfflineInfo : : ONLINE ) ;
} else if ( ! offline & & ! wifiActive ) {
NotifyAppOfflineStatus ( aAppId , nsIAppOfflineInfo : : OFFLINE ) ;
}
break ;
case nsIAppOfflineInfo : : ONLINE :
mAppsOfflineStatus . Remove ( aAppId ) ;
if ( offline ) {
NotifyAppOfflineStatus ( aAppId , nsIAppOfflineInfo : : ONLINE ) ;
}
break ;
default :
break ;
}
}
2014-10-07 18:08:07 +04:00
NS_IMETHODIMP
nsIOService : : GetAppOfflineState ( uint32_t aAppId , int32_t * aResult )
{
NS_ENSURE_ARG ( aResult ) ;
if ( aAppId = = NECKO_NO_APP_ID | |
aAppId = = NECKO_UNKNOWN_APP_ID ) {
return NS_ERROR_NOT_AVAILABLE ;
}
* aResult = nsIAppOfflineInfo : : ONLINE ;
mAppsOfflineStatus . Get ( aAppId , aResult ) ;
return NS_OK ;
}
2014-08-23 07:05:56 +04:00
NS_IMETHODIMP
nsIOService : : IsAppOffline ( uint32_t aAppId , bool * aResult )
{
NS_ENSURE_ARG ( aResult ) ;
2014-08-27 06:25:47 +04:00
* aResult = false ;
2014-08-23 07:05:56 +04:00
if ( aAppId = = NECKO_NO_APP_ID | |
aAppId = = NECKO_UNKNOWN_APP_ID ) {
return NS_ERROR_NOT_AVAILABLE ;
}
int32_t state ;
if ( mAppsOfflineStatus . Get ( aAppId , & state ) ) {
switch ( state ) {
case nsIAppOfflineInfo : : OFFLINE :
* aResult = true ;
break ;
case nsIAppOfflineInfo : : WIFI_ONLY :
2014-08-22 21:15:00 +04:00
MOZ_RELEASE_ASSERT ( ! IsNeckoChild ( ) ) ;
2014-08-23 07:05:56 +04:00
* aResult = ! IsWifiActive ( ) ;
break ;
default :
// The app is online by default
break ;
}
}
return NS_OK ;
}
2016-05-19 05:02:57 +03:00
} // namespace net
} // namespace mozilla