1999-06-07 21:33:30 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* The contents of this file are subject to the Netscape Public
|
|
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.mozilla.org/NPL/
|
1999-06-07 21:33:30 +00:00
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* Software distributed under the License is distributed on an "AS
|
|
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
|
|
* implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
1999-06-07 21:33:30 +00:00
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
1999-06-07 21:33:30 +00:00
|
|
|
* Communications Corporation. Portions created by Netscape are
|
1999-11-06 03:40:37 +00:00
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
1999-06-07 21:33:30 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "nsIOService.h"
|
|
|
|
#include "nsIProtocolHandler.h"
|
|
|
|
#include "nscore.h"
|
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsIEventQueueService.h"
|
|
|
|
#include "nsIFileTransportService.h"
|
|
|
|
#include "nsIURI.h"
|
1999-06-12 08:07:05 +00:00
|
|
|
#include "nsIStreamListener.h"
|
1999-06-08 19:04:13 +00:00
|
|
|
#include "prprf.h"
|
1999-06-24 22:58:42 +00:00
|
|
|
#include "nsLoadGroup.h"
|
1999-07-03 04:05:14 +00:00
|
|
|
#include "nsInputStreamChannel.h"
|
1999-07-10 05:00:23 +00:00
|
|
|
#include "nsXPIDLString.h"
|
2000-07-25 05:45:56 +00:00
|
|
|
#include "nsIErrorService.h"
|
2001-01-17 19:51:28 +00:00
|
|
|
#include "netCore.h"
|
|
|
|
#include "nsIObserverService.h"
|
2001-05-11 21:04:09 +00:00
|
|
|
#include "nsIHttpProtocolHandler.h"
|
2001-06-06 00:10:09 +00:00
|
|
|
#include "nsIPref.h"
|
2001-06-21 22:02:47 +00:00
|
|
|
#include "nsICategoryManager.h"
|
|
|
|
#include "nsIURLParser.h"
|
|
|
|
#include "nsISupportsPrimitives.h"
|
2001-09-13 02:21:05 +00:00
|
|
|
#include "nsIProxiedProtocolHandler.h"
|
|
|
|
#include "nsIProxyInfo.h"
|
2001-08-17 02:03:34 +00:00
|
|
|
#include "nsITimelineService.h"
|
2001-09-08 12:47:05 +00:00
|
|
|
#include "nsEscape.h"
|
1999-06-07 21:33:30 +00:00
|
|
|
|
|
|
|
static NS_DEFINE_CID(kFileTransportService, NS_FILETRANSPORTSERVICE_CID);
|
|
|
|
static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID);
|
2000-01-05 03:44:42 +00:00
|
|
|
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
|
|
|
|
static NS_DEFINE_CID(kDNSServiceCID, NS_DNSSERVICE_CID);
|
2000-07-25 05:45:56 +00:00
|
|
|
static NS_DEFINE_CID(kErrorServiceCID, NS_ERRORSERVICE_CID);
|
2001-05-11 21:04:09 +00:00
|
|
|
static NS_DEFINE_CID(kProtocolProxyServiceCID, NS_PROTOCOLPROXYSERVICE_CID);
|
2001-06-06 00:10:09 +00:00
|
|
|
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
2001-06-21 22:02:47 +00:00
|
|
|
static NS_DEFINE_CID(kStdURLParserCID, NS_STANDARDURLPARSER_CID);
|
|
|
|
|
2001-06-06 00:10:09 +00:00
|
|
|
// A general port blacklist. Connections to these ports will not be avoided unless
|
|
|
|
// the protocol overrides.
|
|
|
|
//
|
|
|
|
// TODO: I am sure that there are more ports to be added.
|
|
|
|
// This cut is based on the classic mozilla codebase
|
|
|
|
|
2001-08-16 04:53:16 +00:00
|
|
|
PRInt16 gBadPortList[] = {
|
2001-06-06 00:10:09 +00: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
|
|
|
|
512, // print / exec
|
|
|
|
513, // login
|
|
|
|
514, // shell
|
|
|
|
515, // printer
|
|
|
|
526, // tempo
|
|
|
|
530, // courier
|
|
|
|
531, // Chat
|
|
|
|
532, // netnews
|
|
|
|
540, // uucp
|
|
|
|
556, // remotefs
|
|
|
|
587, //
|
|
|
|
601, //
|
|
|
|
1080, // SOCKS
|
|
|
|
2049, // nfs
|
|
|
|
4045, // lockd
|
|
|
|
6000, // x11
|
|
|
|
0, // This MUST be zero so that we can populating the array
|
|
|
|
};
|
1999-08-29 16:42:27 +00:00
|
|
|
|
1999-06-07 21:33:30 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
nsIOService::nsIOService()
|
2000-02-08 06:27:34 +00:00
|
|
|
: mOffline(PR_FALSE)
|
1999-06-07 21:33:30 +00:00
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsIOService::Init()
|
|
|
|
{
|
2000-02-08 06:27:34 +00:00
|
|
|
nsresult rv = NS_OK;
|
2001-02-21 20:38:08 +00:00
|
|
|
|
|
|
|
// Hold onto the eventQueue service. We do not want any eventqueues to go away
|
|
|
|
// when we shutdown until we process all remaining transports
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
mEventQueueService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
|
|
|
|
|
|
|
|
|
2000-01-19 07:58:40 +00:00
|
|
|
// We need to get references to these services so that we can shut them
|
|
|
|
// down later. If we wait until the nsIOService is being shut down,
|
|
|
|
// GetService will fail at that point.
|
|
|
|
rv = nsServiceManager::GetService(kSocketTransportServiceCID,
|
|
|
|
NS_GET_IID(nsISocketTransportService),
|
|
|
|
getter_AddRefs(mSocketTransportService));
|
2000-02-08 06:27:34 +00:00
|
|
|
|
2000-01-19 07:58:40 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-06-13 03:00:53 +00:00
|
|
|
|
2000-01-19 07:58:40 +00:00
|
|
|
rv = nsServiceManager::GetService(kFileTransportService,
|
|
|
|
NS_GET_IID(nsIFileTransportService),
|
|
|
|
getter_AddRefs(mFileTransportService));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2001-05-11 21:04:09 +00:00
|
|
|
|
2000-01-19 07:58:40 +00:00
|
|
|
rv = nsServiceManager::GetService(kDNSServiceCID,
|
|
|
|
NS_GET_IID(nsIDNSService),
|
|
|
|
getter_AddRefs(mDNSService));
|
2001-05-11 21:04:09 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = nsServiceManager::GetService(kProtocolProxyServiceCID,
|
|
|
|
NS_GET_IID(nsIProtocolProxyService),
|
|
|
|
getter_AddRefs(mProxyService));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-07-25 05:45:56 +00:00
|
|
|
|
|
|
|
// XXX hack until xpidl supports error info directly (http://bugzilla.mozilla.org/show_bug.cgi?id=13423)
|
|
|
|
nsCOMPtr<nsIErrorService> errorService = do_GetService(kErrorServiceCID, &rv);
|
2001-06-06 00:10:09 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
rv = errorService->RegisterErrorStringBundle(NS_ERROR_MODULE_NETWORK, NECKO_MSGS_URL);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_READ_FROM, "ReadFrom");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_WROTE_TO, "WroteTo");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_RESOLVING_HOST, "ResolvingHost");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_CONNECTED_TO, "ConnectedTo");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_SENDING_TO, "SendingTo");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_RECEIVING_FROM, "ReceivingFrom");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_CONNECTING_TO, "ConnectingTo");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// setup our bad port list stuff
|
|
|
|
for(int i=0; gBadPortList[i]; i++)
|
|
|
|
{
|
|
|
|
mRestrictedPortList.AppendElement((void*)gBadPortList[i]);
|
2000-07-25 05:45:56 +00:00
|
|
|
}
|
2001-06-06 00:10:09 +00:00
|
|
|
|
|
|
|
// Lets make it really easy to block extra ports:
|
2001-07-25 07:54:28 +00:00
|
|
|
nsCOMPtr<nsIPref> prefService(do_GetService(kPrefServiceCID, &rv));
|
2001-06-06 00:10:09 +00:00
|
|
|
if (NS_FAILED(rv) && !prefService) {
|
|
|
|
NS_ASSERTION(0, "Prefs not found!");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* portList = nsnull;
|
|
|
|
prefService->CopyCharPref("network.security.ports.banned", &portList);
|
|
|
|
if (portList) {
|
|
|
|
char* tokp;
|
|
|
|
char* currentPos = portList;
|
|
|
|
while ( (tokp = nsCRT::strtok(currentPos, ",", ¤tPos)) != nsnull )
|
|
|
|
{
|
|
|
|
nsCAutoString tmp(tokp);
|
|
|
|
tmp.StripWhitespace();
|
|
|
|
|
|
|
|
PRInt32 aErrorCode;
|
|
|
|
PRInt32 value = tmp.ToInteger(&aErrorCode);
|
|
|
|
mRestrictedPortList.AppendElement((void*)value);
|
|
|
|
}
|
|
|
|
|
|
|
|
PL_strfree(portList);
|
|
|
|
}
|
|
|
|
|
|
|
|
portList = nsnull;
|
|
|
|
prefService->CopyCharPref("network.security.ports.banned.override", &portList);
|
|
|
|
if (portList) {
|
|
|
|
char* tokp;
|
|
|
|
char* currentPos = portList;
|
|
|
|
while ( (tokp = nsCRT::strtok(currentPos, ",", ¤tPos)) != nsnull )
|
|
|
|
{
|
|
|
|
nsCAutoString tmp(tokp);
|
|
|
|
tmp.StripWhitespace();
|
|
|
|
|
|
|
|
PRInt32 aErrorCode;
|
|
|
|
PRInt32 value = tmp.ToInteger(&aErrorCode);
|
|
|
|
mRestrictedPortList.RemoveElement((void*)value);
|
|
|
|
}
|
|
|
|
|
|
|
|
PL_strfree(portList);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
2000-06-13 03:00:53 +00:00
|
|
|
}
|
|
|
|
|
1999-06-07 21:33:30 +00:00
|
|
|
|
|
|
|
nsIOService::~nsIOService()
|
|
|
|
{
|
2001-08-21 21:49:04 +00:00
|
|
|
// mURLParsers is a voidarray; we must release ourselves
|
|
|
|
for (PRInt32 i = 0; i < mURLParsers.Count(); i++)
|
|
|
|
{
|
|
|
|
nsISupports *temp;
|
|
|
|
temp = NS_STATIC_CAST(nsISupports*, mURLParsers[i]);
|
|
|
|
NS_IF_RELEASE(temp);
|
|
|
|
}
|
2000-02-08 06:27:34 +00:00
|
|
|
(void)SetOffline(PR_TRUE);
|
2001-02-21 20:38:08 +00:00
|
|
|
if (mFileTransportService)
|
|
|
|
(void)mFileTransportService->Shutdown();
|
|
|
|
}
|
1999-06-07 21:33:30 +00:00
|
|
|
|
|
|
|
NS_METHOD
|
|
|
|
nsIOService::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
|
|
|
{
|
2000-06-13 03:00:53 +00:00
|
|
|
static nsISupports *_rValue = nsnull;
|
|
|
|
|
1999-07-23 16:35:53 +00:00
|
|
|
nsresult rv;
|
2000-05-03 21:47:56 +00:00
|
|
|
NS_ENSURE_NO_AGGREGATION(aOuter);
|
1999-06-07 21:33:30 +00:00
|
|
|
|
2000-06-13 03:00:53 +00:00
|
|
|
if (_rValue)
|
|
|
|
{
|
|
|
|
NS_ADDREF (_rValue);
|
|
|
|
*aResult = _rValue;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-07-10 05:00:23 +00:00
|
|
|
nsIOService* _ios = new nsIOService();
|
|
|
|
if (_ios == nsnull)
|
1999-06-07 21:33:30 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
1999-07-10 05:00:23 +00:00
|
|
|
NS_ADDREF(_ios);
|
1999-07-23 16:35:53 +00:00
|
|
|
rv = _ios->Init();
|
2000-06-13 03:00:53 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
{
|
1999-07-23 16:35:53 +00:00
|
|
|
delete _ios;
|
|
|
|
return rv;
|
|
|
|
}
|
2000-06-13 03:00:53 +00:00
|
|
|
|
1999-07-23 16:35:53 +00:00
|
|
|
rv = _ios->QueryInterface(aIID, aResult);
|
2000-06-13 03:00:53 +00:00
|
|
|
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
{
|
|
|
|
delete _ios;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
_rValue = NS_STATIC_CAST (nsISupports*, *aResult);
|
|
|
|
NS_RELEASE (_rValue);
|
|
|
|
_rValue = nsnull;
|
|
|
|
|
1999-06-07 21:33:30 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2000-03-05 21:26:01 +00:00
|
|
|
NS_IMPL_THREADSAFE_ISUPPORTS1(nsIOService, nsIIOService);
|
1999-06-07 21:33:30 +00:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#define MAX_SCHEME_LENGTH 64 // XXX big enough?
|
|
|
|
|
2000-09-13 23:57:52 +00:00
|
|
|
#define MAX_NET_CONTRACTID_LENGTH (MAX_SCHEME_LENGTH + NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX_LENGTH + 1)
|
1999-06-07 21:33:30 +00:00
|
|
|
|
2000-08-22 06:16:50 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
// Dont cache handlers that dont support weak reference as
|
|
|
|
// there is real danger of a circular reference.
|
2000-10-28 22:17:53 +00:00
|
|
|
#ifdef DEBUG_dp
|
|
|
|
printf("DEBUG: %s protcol handler doesn't support weak ref. Not cached.\n", scheme);
|
|
|
|
#endif /* DEBUG_dp */
|
2000-08-22 06:16:50 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
mWeakHandler[i] = getter_AddRefs(NS_GetWeakReference(handler));
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2001-08-17 04:46:35 +00:00
|
|
|
nsIOService::GetCachedProtocolHandler(const char *scheme, nsIProtocolHandler **result, PRUint32 start, PRUint32 end)
|
2000-08-22 06:16:50 +00:00
|
|
|
{
|
|
|
|
for (unsigned int i=0; i<NS_N(gScheme); i++)
|
|
|
|
{
|
2001-08-17 04:01:38 +00:00
|
|
|
// handle unterminated strings
|
|
|
|
// start is inclusive, end is exclusive, len = end - start - 1
|
|
|
|
if (end != 0 ? !nsCRT::strncasecmp(&scheme[start], gScheme[i],
|
|
|
|
(end-start)-1) :
|
|
|
|
!nsCRT::strcasecmp(scheme, gScheme[i]))
|
|
|
|
{
|
2000-08-22 06:16:50 +00:00
|
|
|
if (mWeakHandler[i])
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIProtocolHandler> temp = do_QueryReferent(mWeakHandler[i]);
|
|
|
|
if (temp)
|
|
|
|
{
|
|
|
|
*result = temp.get();
|
|
|
|
NS_ADDREF(*result);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
2001-08-17 04:01:38 +00:00
|
|
|
}
|
2000-08-22 06:16:50 +00:00
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2001-06-21 22:02:47 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsIOService::CacheURLParser(const char *scheme, nsIURLParser *parser)
|
|
|
|
{
|
2001-08-21 21:49:04 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(scheme);
|
|
|
|
NS_ENSURE_ARG_POINTER(parser);
|
2001-06-21 22:02:47 +00:00
|
|
|
for (unsigned int i=0; i<NS_N(gScheme); i++)
|
|
|
|
{
|
|
|
|
if (!nsCRT::strcasecmp(scheme, gScheme[i]))
|
|
|
|
{
|
2001-08-21 21:49:04 +00:00
|
|
|
// we're going to store this in an nsVoidArray, which extends,
|
|
|
|
// unlike nsSupportsArray, which doesn't. We must release
|
|
|
|
// them on delete!
|
|
|
|
// grab this before overwriting it
|
|
|
|
nsIURLParser *old_parser = NS_STATIC_CAST(nsIURLParser*,
|
|
|
|
mURLParsers[i]);
|
|
|
|
NS_ADDREF(parser);
|
|
|
|
mURLParsers.ReplaceElementAt(parser, i);
|
|
|
|
// release any old entry, if any, AFTER adding new entry in
|
|
|
|
// case they were the same (paranoia)
|
|
|
|
NS_IF_RELEASE(old_parser);
|
2001-06-21 22:02:47 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsIOService::GetCachedURLParser(const char *scheme, nsIURLParser **result)
|
|
|
|
{
|
|
|
|
for (unsigned int i=0; i<NS_N(gScheme); i++)
|
|
|
|
{
|
|
|
|
if (!nsCRT::strcasecmp(scheme, gScheme[i]))
|
2001-08-21 21:49:04 +00:00
|
|
|
{
|
|
|
|
*result = NS_STATIC_CAST(nsIURLParser*, mURLParsers[i]);
|
|
|
|
NS_IF_ADDREF(*result);
|
|
|
|
return *result ? NS_OK : NS_ERROR_FAILURE;
|
|
|
|
}
|
2001-06-21 22:02:47 +00:00
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2000-08-22 06:16:50 +00:00
|
|
|
|
1999-06-07 21:33:30 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsIOService::GetProtocolHandler(const char* scheme, nsIProtocolHandler* *result)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
2000-09-13 23:57:52 +00:00
|
|
|
NS_ASSERTION(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX_LENGTH
|
|
|
|
== nsCRT::strlen(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX),
|
|
|
|
"need to fix NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX_LENGTH");
|
1999-06-07 21:33:30 +00:00
|
|
|
|
2000-05-03 21:47:56 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(scheme);
|
1999-06-07 21:33:30 +00: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 06:16:50 +00:00
|
|
|
rv = GetCachedProtocolHandler(scheme, result);
|
|
|
|
if (NS_SUCCEEDED(rv)) return NS_OK;
|
|
|
|
|
2000-09-13 23:57:52 +00:00
|
|
|
char buf[MAX_NET_CONTRACTID_LENGTH];
|
|
|
|
nsCAutoString contractID(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX);
|
|
|
|
contractID += scheme;
|
|
|
|
contractID.ToLowerCase();
|
|
|
|
contractID.ToCString(buf, MAX_NET_CONTRACTID_LENGTH);
|
1999-06-07 21:33:30 +00:00
|
|
|
|
1999-11-02 01:40:14 +00:00
|
|
|
rv = nsServiceManager::GetService(buf, NS_GET_IID(nsIProtocolHandler), (nsISupports **)result);
|
1999-07-30 04:17:23 +00:00
|
|
|
if (NS_FAILED(rv))
|
2001-02-07 05:54:35 +00: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 = nsServiceManager::GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX"default", NS_GET_IID(nsIProtocolHandler), (nsISupports **)result);
|
|
|
|
if (NS_FAILED(rv)) return NS_ERROR_UNKNOWN_PROTOCOL;
|
|
|
|
}
|
1999-06-07 21:33:30 +00:00
|
|
|
|
2000-08-22 06:16:50 +00:00
|
|
|
CacheProtocolHandler(scheme, *result);
|
|
|
|
|
1999-06-07 21:33:30 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-12 06:13:13 +00:00
|
|
|
NS_IMETHODIMP
|
2000-05-07 10:49:29 +00:00
|
|
|
nsIOService::ExtractScheme(const char* inURI, PRUint32 *startPos,
|
|
|
|
PRUint32 *endPos, char* *scheme)
|
1999-07-10 11:26:43 +00:00
|
|
|
{
|
2000-05-07 10:49:29 +00:00
|
|
|
return ExtractURLScheme(inURI, startPos, endPos, scheme);
|
1999-07-10 11:26:43 +00:00
|
|
|
}
|
|
|
|
|
2001-06-21 22:02:47 +00:00
|
|
|
/* nsIURLParser getParserForScheme (in string scheme); */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsIOService::GetParserForScheme(const char *scheme, nsIURLParser **_retval)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
rv = GetCachedURLParser(scheme, _retval);
|
|
|
|
if (NS_SUCCEEDED(rv) && *_retval) return NS_OK;
|
|
|
|
|
|
|
|
|
|
|
|
if (!scheme) {
|
|
|
|
if (!mDefaultURLParser) {
|
|
|
|
rv = nsServiceManager::GetService(kStdURLParserCID,
|
|
|
|
NS_GET_IID(nsIURLParser),
|
|
|
|
getter_AddRefs(mDefaultURLParser));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
*_retval = mDefaultURLParser;
|
|
|
|
NS_ADDREF(*_retval);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsICategoryManager> catmgr(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> parserList;
|
|
|
|
rv = catmgr->EnumerateCategory(NS_IURLPARSER_KEY, getter_AddRefs(parserList));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupportsString> entry;
|
|
|
|
|
|
|
|
// Walk the list of parsers...
|
|
|
|
while (1) {
|
|
|
|
rv = parserList->GetNext(getter_AddRefs(entry));
|
2001-06-27 02:29:19 +00:00
|
|
|
if (NS_FAILED(rv)) break;
|
2001-06-21 22:02:47 +00:00
|
|
|
|
|
|
|
// get the entry string
|
|
|
|
nsXPIDLCString entryString;
|
|
|
|
rv = entry->GetData(getter_Copies(entryString));
|
2001-06-27 02:29:19 +00:00
|
|
|
if (NS_FAILED(rv)) break;
|
2001-06-21 22:02:47 +00:00
|
|
|
|
|
|
|
if (nsCRT::strcmp(entryString, scheme) == 0) {
|
|
|
|
nsXPIDLCString contractID;
|
|
|
|
rv = catmgr->GetCategoryEntry(NS_IURLPARSER_KEY,(const char *)entryString, getter_Copies(contractID));
|
2001-06-27 02:29:19 +00:00
|
|
|
if (NS_FAILED(rv)) break;
|
2001-06-21 22:02:47 +00:00
|
|
|
|
2001-08-21 21:49:04 +00:00
|
|
|
rv = nsServiceManager::GetService(contractID, NS_GET_IID(nsIURLParser), (nsISupports **)_retval);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
if (*_retval)
|
|
|
|
CacheURLParser(scheme, *_retval);
|
2001-08-21 22:43:47 +00:00
|
|
|
return *_retval ? NS_OK : NS_ERROR_FAILURE;
|
2001-06-21 22:02:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// no registered url parser. Just use the default...
|
|
|
|
if (!mDefaultURLParser) {
|
|
|
|
rv = nsServiceManager::GetService(kStdURLParserCID,
|
|
|
|
NS_GET_IID(nsIURLParser),
|
|
|
|
getter_AddRefs(mDefaultURLParser));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
*_retval = mDefaultURLParser;
|
|
|
|
NS_ADDREF(*_retval);
|
|
|
|
CacheURLParser(scheme, *_retval);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void CalculateStartEndPos(const char*string, const char* substring, PRUint32 *startPos, PRUint32 *endPos)
|
|
|
|
{
|
|
|
|
// we will only get the first appearance of a substring...
|
|
|
|
char* inst = PL_strstr(string, substring);
|
|
|
|
|
|
|
|
if (startPos)
|
|
|
|
*startPos = (PRUint32)(inst - string);
|
|
|
|
if (endPos)
|
2001-08-14 07:59:59 +00:00
|
|
|
*endPos = NS_PTR_TO_INT32(inst) + PL_strlen(substring);
|
2001-06-21 22:02:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Crap. How do I ensure that startPos and endPos are correct.
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsIOService::ExtractUrlPart(const char *urlString, PRInt16 flag, PRUint32 *startPos, PRUint32 *endPos, char **urlPart)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsXPIDLCString scheme;
|
|
|
|
|
|
|
|
ExtractScheme(urlString, startPos, endPos, getter_Copies(scheme));
|
|
|
|
|
|
|
|
if (flag == url_Scheme) {
|
|
|
|
CalculateStartEndPos(urlString, scheme, startPos, endPos);
|
|
|
|
|
|
|
|
if (urlPart)
|
|
|
|
*urlPart = nsCRT::strdup(scheme.get());
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURLParser> parser;
|
|
|
|
rv = GetParserForScheme(scheme, getter_AddRefs(parser));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
PRInt32 port;
|
2001-08-31 21:37:30 +00:00
|
|
|
nsXPIDLCString dummyScheme, username, password, host, path, o_path;
|
2001-06-21 22:02:47 +00:00
|
|
|
|
|
|
|
rv = parser->ParseAtScheme(urlString,
|
|
|
|
getter_Copies(dummyScheme),
|
|
|
|
getter_Copies(username),
|
|
|
|
getter_Copies(password),
|
|
|
|
getter_Copies(host),
|
|
|
|
&port,
|
|
|
|
getter_Copies(path));
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (flag == url_Username) {
|
|
|
|
CalculateStartEndPos(urlString, username, startPos, endPos);
|
|
|
|
if (urlPart)
|
|
|
|
*urlPart = nsCRT::strdup(username.get());
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag == url_Password) {
|
|
|
|
CalculateStartEndPos(urlString, password, startPos, endPos);
|
|
|
|
if (urlPart)
|
|
|
|
*urlPart = nsCRT::strdup(password.get());
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag == url_Host) {
|
|
|
|
CalculateStartEndPos(urlString, host, startPos, endPos);
|
|
|
|
if (urlPart)
|
|
|
|
*urlPart = nsCRT::strdup(host.get());
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag == url_Directory) {
|
|
|
|
CalculateStartEndPos(urlString, path, startPos, endPos);
|
|
|
|
if (urlPart)
|
|
|
|
*urlPart = nsCRT::strdup(path.get());
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsXPIDLCString fileBaseName, fileExtension, param, query, ref;
|
|
|
|
|
|
|
|
rv = parser->ParseAtDirectory(path,
|
2001-08-31 21:37:30 +00:00
|
|
|
getter_Copies(o_path),
|
2001-06-21 22:02:47 +00:00
|
|
|
getter_Copies(fileBaseName),
|
|
|
|
getter_Copies(fileExtension),
|
|
|
|
getter_Copies(param),
|
|
|
|
getter_Copies(query),
|
|
|
|
getter_Copies(ref));
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
|
|
|
|
if (flag == url_FileBaseName) {
|
|
|
|
CalculateStartEndPos(urlString, fileBaseName, startPos, endPos);
|
|
|
|
if (urlPart)
|
|
|
|
*urlPart = nsCRT::strdup(fileBaseName.get());
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag == url_FileExtension) {
|
|
|
|
CalculateStartEndPos(urlString, fileBaseName, startPos, endPos);
|
|
|
|
if (urlPart)
|
|
|
|
*urlPart = nsCRT::strdup(fileExtension.get());
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag == url_Param) {
|
|
|
|
CalculateStartEndPos(urlString, fileBaseName, startPos, endPos);
|
|
|
|
if (urlPart)
|
|
|
|
*urlPart = nsCRT::strdup(param.get());
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag == url_Query) {
|
|
|
|
CalculateStartEndPos(urlString, fileBaseName, startPos, endPos);
|
|
|
|
if (urlPart)
|
|
|
|
*urlPart = nsCRT::strdup(query.get());
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag == url_Ref) {
|
|
|
|
CalculateStartEndPos(urlString, fileBaseName, startPos, endPos);
|
|
|
|
if (urlPart)
|
|
|
|
*urlPart = nsCRT::strdup(ref.get());
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-08-07 20:42:57 +00:00
|
|
|
NS_IMETHODIMP
|
2001-09-13 02:21:05 +00:00
|
|
|
nsIOService::GetProtocolFlags(const char* scheme, PRUint32 *flags)
|
2001-08-07 20:42:57 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIProtocolHandler> handler;
|
|
|
|
nsresult rv = GetProtocolHandler(scheme, getter_AddRefs(handler));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2001-09-13 02:21:05 +00:00
|
|
|
rv = handler->GetProtocolFlags(flags);
|
2001-08-07 20:42:57 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-09-26 10:11:36 +00:00
|
|
|
nsresult
|
2001-05-11 21:04:09 +00:00
|
|
|
nsIOService::NewURI(const char* aSpec, nsIURI* aBaseURI, nsIURI* *result)
|
1999-06-07 21:33:30 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-07-27 08:45:20 +00:00
|
|
|
nsIURI* base;
|
2000-05-03 21:47:56 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aSpec);
|
2001-08-17 04:01:38 +00:00
|
|
|
nsXPIDLCString scheme;
|
|
|
|
nsCOMPtr<nsIProtocolHandler> handler;
|
|
|
|
PRUint32 start,end;
|
|
|
|
|
|
|
|
rv = ExtractScheme(aSpec, &start, &end, nsnull);
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
{
|
1999-07-27 08:45:20 +00:00
|
|
|
// then aSpec is absolute
|
|
|
|
// ignore aBaseURI in this case
|
|
|
|
base = nsnull;
|
2001-08-17 04:01:38 +00:00
|
|
|
rv = GetCachedProtocolHandler(aSpec, getter_AddRefs(handler),
|
|
|
|
start,end);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
{
|
|
|
|
// not cached; we'll do an allocation
|
|
|
|
rv = ExtractScheme(aSpec, nsnull, nsnull, getter_Copies(scheme));
|
|
|
|
}
|
|
|
|
// else scheme == nsnull, and we succeeded
|
1999-07-27 08:45:20 +00:00
|
|
|
}
|
2001-08-17 04:01:38 +00:00
|
|
|
else
|
|
|
|
{
|
1999-07-27 08:45:20 +00:00
|
|
|
// then aSpec is relative
|
2001-08-17 04:01:38 +00:00
|
|
|
if (!aBaseURI)
|
1999-07-27 08:45:20 +00:00
|
|
|
return NS_ERROR_MALFORMED_URI;
|
2001-08-17 04:01:38 +00:00
|
|
|
rv = aBaseURI->GetScheme(getter_Copies(scheme));
|
1999-07-27 08:45:20 +00:00
|
|
|
base = aBaseURI;
|
1999-07-10 11:26:43 +00:00
|
|
|
}
|
2001-08-17 04:01:38 +00:00
|
|
|
// scheme is non-null if we allocated it.
|
|
|
|
// base is null if absolute, set if relative
|
|
|
|
// rv is success if all is ok, failure if we need to cleanup and exit
|
|
|
|
if (NS_SUCCEEDED(rv) && scheme.get())
|
|
|
|
{
|
|
|
|
// we allocated scheme; get the handler for it
|
|
|
|
rv = GetProtocolHandler(scheme, getter_AddRefs(handler));
|
|
|
|
}
|
1999-07-10 11:26:43 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-06-07 21:33:30 +00:00
|
|
|
|
1999-07-27 08:45:20 +00:00
|
|
|
return handler->NewURI(aSpec, base, result);
|
1999-06-07 21:33:30 +00:00
|
|
|
}
|
|
|
|
|
2001-06-21 22:02:47 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsIOService::NewFileURI(nsIFile *aSpec, nsIURI **_retval)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
NS_ENSURE_ARG_POINTER(aSpec);
|
|
|
|
|
|
|
|
nsXPIDLCString urlString;
|
|
|
|
rv = aSpec->GetURL(getter_Copies(urlString));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
return NewURI(urlString, nsnull, _retval);
|
|
|
|
}
|
|
|
|
|
1999-06-07 21:33:30 +00:00
|
|
|
NS_IMETHODIMP
|
2000-03-29 03:58:50 +00:00
|
|
|
nsIOService::NewChannelFromURI(nsIURI *aURI, nsIChannel **result)
|
1999-06-07 21:33:30 +00:00
|
|
|
{
|
1999-06-08 18:28:10 +00:00
|
|
|
nsresult rv;
|
2000-05-03 21:47:56 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aURI);
|
2001-08-17 02:03:34 +00:00
|
|
|
NS_TIMELINE_MARK_URI("nsIOService::NewChannelFromURI(%s)", aURI);
|
1999-06-08 18:28:10 +00:00
|
|
|
|
1999-07-10 05:00:23 +00:00
|
|
|
nsXPIDLCString scheme;
|
|
|
|
rv = aURI->GetScheme(getter_Copies(scheme));
|
1999-06-08 18:28:10 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2001-09-13 02:21:05 +00:00
|
|
|
nsCOMPtr<nsIProxyInfo> pi;
|
|
|
|
rv = mProxyService->ExamineForProxy(aURI, getter_AddRefs(pi));
|
1999-06-08 18:28:10 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2001-09-13 02:21:05 +00:00
|
|
|
nsCOMPtr<nsIProtocolHandler> handler;
|
|
|
|
|
|
|
|
if (pi && !nsCRT::strcmp(pi->Type(),"http")) {
|
|
|
|
// we are going to proxy this channel using an http proxy
|
|
|
|
rv = GetProtocolHandler("http", getter_AddRefs(handler));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
} else {
|
|
|
|
rv = GetProtocolHandler(scheme.get(), getter_AddRefs(handler));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2001-05-11 21:04:09 +00:00
|
|
|
}
|
|
|
|
|
2001-09-13 02:21:05 +00:00
|
|
|
nsCOMPtr<nsIProxiedProtocolHandler> pph = do_QueryInterface(handler);
|
|
|
|
|
|
|
|
if (pph)
|
|
|
|
rv = pph->NewProxiedChannel(aURI, pi, result);
|
|
|
|
else
|
|
|
|
rv = handler->NewChannel(aURI, result);
|
|
|
|
|
1999-06-08 18:28:10 +00:00
|
|
|
return rv;
|
1999-06-07 21:33:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2000-03-29 03:58:50 +00:00
|
|
|
nsIOService::NewChannel(const char *aSpec, nsIURI *aBaseURI, nsIChannel **result)
|
1999-06-07 21:33:30 +00:00
|
|
|
{
|
1999-06-08 18:28:10 +00:00
|
|
|
nsresult rv;
|
1999-09-26 10:11:36 +00:00
|
|
|
nsCOMPtr<nsIURI> uri;
|
2001-05-11 21:04:09 +00:00
|
|
|
rv = NewURI(aSpec, aBaseURI, getter_AddRefs(uri));
|
1999-06-08 18:28:10 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-11-17 08:14:52 +00:00
|
|
|
|
2001-05-11 21:04:09 +00:00
|
|
|
return NewChannelFromURI(uri, result);
|
1999-06-07 21:33:30 +00:00
|
|
|
}
|
|
|
|
|
2000-01-05 02:44:23 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsIOService::GetOffline(PRBool *offline)
|
|
|
|
{
|
|
|
|
*offline = mOffline;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsIOService::SetOffline(PRBool offline)
|
|
|
|
{
|
2001-01-17 19:51:28 +00:00
|
|
|
nsCOMPtr<nsIObserverService>
|
|
|
|
observerService(do_GetService(NS_OBSERVERSERVICE_CONTRACTID));
|
|
|
|
|
2000-03-27 22:17:48 +00:00
|
|
|
nsresult rv1 = NS_OK;
|
|
|
|
nsresult rv2 = NS_OK;
|
2000-01-05 03:44:42 +00:00
|
|
|
if (offline) {
|
2001-03-27 15:17:52 +00:00
|
|
|
// don't care if notification fails
|
|
|
|
if (observerService)
|
|
|
|
(void)observerService->Notify(this,
|
|
|
|
NS_LITERAL_STRING("network:offline-status-changed").get(),
|
|
|
|
NS_LITERAL_STRING("offline").get());
|
2000-05-12 23:41:40 +00:00
|
|
|
mOffline = PR_TRUE; // indicate we're trying to shutdown
|
2000-01-05 03:44:42 +00:00
|
|
|
// be sure to try and shutdown both (even if the first fails)
|
2000-02-17 03:34:16 +00:00
|
|
|
if (mDNSService)
|
2000-05-12 23:41:40 +00:00
|
|
|
rv1 = mDNSService->Shutdown(); // shutdown dns service first, because it has callbacks for socket transport
|
|
|
|
if (mSocketTransportService)
|
|
|
|
rv2 = mSocketTransportService->Shutdown();
|
2000-01-05 03:44:42 +00:00
|
|
|
if (NS_FAILED(rv1)) return rv1;
|
|
|
|
if (NS_FAILED(rv2)) return rv2;
|
2001-01-17 19:51:28 +00:00
|
|
|
|
2000-01-05 03:44:42 +00:00
|
|
|
}
|
2000-03-27 22:17:48 +00:00
|
|
|
else if (!offline && mOffline) {
|
|
|
|
// go online
|
|
|
|
if (mDNSService)
|
2000-05-12 23:41:40 +00:00
|
|
|
rv1 = mDNSService->Init();
|
|
|
|
if (NS_FAILED(rv2)) return rv1;
|
|
|
|
|
|
|
|
if (mSocketTransportService)
|
|
|
|
rv2 = mSocketTransportService->Init(); //XXX should we shutdown the dns service?
|
|
|
|
if (NS_FAILED(rv2)) return rv1;
|
2001-01-17 19:51:28 +00:00
|
|
|
mOffline = PR_FALSE; // indicate success only AFTER we've
|
|
|
|
// brought up the services
|
|
|
|
// don't care if notification fails
|
2001-01-17 23:42:42 +00:00
|
|
|
if (observerService)
|
|
|
|
(void)observerService->Notify(this,
|
2001-03-08 08:05:05 +00:00
|
|
|
NS_LITERAL_STRING("network:offline-status-changed").get(),
|
|
|
|
NS_LITERAL_STRING("online").get());
|
2000-03-27 22:17:48 +00:00
|
|
|
}
|
2000-01-05 02:44:23 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-08-22 07:03:33 +00:00
|
|
|
|
2001-06-06 00:10:09 +00:00
|
|
|
NS_IMETHODIMP
|
2001-08-16 04:53:16 +00:00
|
|
|
nsIOService::AllowPort(PRInt32 inPort, const char *scheme, PRBool *_retval)
|
2001-06-06 00:10:09 +00:00
|
|
|
{
|
2001-08-16 04:53:16 +00:00
|
|
|
PRInt16 port = inPort;
|
2001-06-06 00:10:09 +00:00
|
|
|
if (port == -1) {
|
|
|
|
*_retval = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// first check to see if the port is in our blacklist:
|
|
|
|
PRInt32 badPortListCnt = mRestrictedPortList.Count();
|
|
|
|
for (int i=0; i<badPortListCnt; i++)
|
|
|
|
{
|
2001-08-14 07:59:59 +00:00
|
|
|
if (port == (PRInt32) NS_PTR_TO_INT32(mRestrictedPortList[i]))
|
2001-06-06 00:10:09 +00:00
|
|
|
{
|
|
|
|
*_retval = PR_FALSE;
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*_retval = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-07-10 11:26:43 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2000-01-27 08:57:14 +00:00
|
|
|
// URL parsing utilities
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsIOService::ExtractPort(const char *str, PRInt32 *result)
|
|
|
|
{
|
2000-02-03 03:44:22 +00:00
|
|
|
PRInt32 returnValue = -1;
|
|
|
|
*result = (0 < PR_sscanf(str, "%d", &returnValue)) ? returnValue : -1;
|
|
|
|
return NS_OK;
|
2000-01-27 08:57:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsIOService::ResolveRelativePath(const char *relativePath, const char* basePath,
|
|
|
|
char **result)
|
|
|
|
{
|
|
|
|
nsCAutoString name;
|
|
|
|
nsCAutoString path(basePath);
|
2000-07-12 07:39:34 +00:00
|
|
|
PRBool needsDelim = PR_FALSE;
|
|
|
|
|
|
|
|
if ( !path.IsEmpty() ) {
|
|
|
|
PRUnichar last = path.Last();
|
|
|
|
needsDelim = !(last == '/' || last == '\\' );
|
|
|
|
}
|
2000-01-27 08:57:14 +00:00
|
|
|
|
|
|
|
PRBool end = PR_FALSE;
|
|
|
|
char c;
|
|
|
|
while (!end) {
|
|
|
|
c = *relativePath++;
|
|
|
|
switch (c) {
|
|
|
|
case '\0':
|
|
|
|
case '#':
|
|
|
|
case ';':
|
|
|
|
case '?':
|
|
|
|
end = PR_TRUE;
|
|
|
|
// fall through...
|
|
|
|
case '/':
|
|
|
|
case '\\':
|
|
|
|
// delimiter found
|
|
|
|
if (name.Equals("..")) {
|
|
|
|
// pop path
|
|
|
|
PRInt32 pos = path.RFind("/");
|
|
|
|
if (pos > 0) {
|
|
|
|
path.Truncate(pos + 1);
|
|
|
|
path += name;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return NS_ERROR_MALFORMED_URI;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (name.Equals(".") || name.Equals("")) {
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// append name to path
|
|
|
|
if (needsDelim)
|
|
|
|
path += "/";
|
|
|
|
path += name;
|
|
|
|
needsDelim = PR_TRUE;
|
|
|
|
}
|
|
|
|
name = "";
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
// append char to name
|
|
|
|
name += c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// append anything left on relativePath (e.g. #..., ;..., ?...)
|
|
|
|
if (c != '\0')
|
|
|
|
path += --relativePath;
|
|
|
|
|
|
|
|
*result = path.ToNewCString();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|