mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
7763512029
--HG-- rename : netwerk/cache/src/nsCache.cpp => netwerk/cache/nsCache.cpp rename : netwerk/cache/src/nsCache.h => netwerk/cache/nsCache.h rename : netwerk/cache/src/nsCacheDevice.h => netwerk/cache/nsCacheDevice.h rename : netwerk/cache/src/nsCacheEntry.cpp => netwerk/cache/nsCacheEntry.cpp rename : netwerk/cache/src/nsCacheEntry.h => netwerk/cache/nsCacheEntry.h rename : netwerk/cache/src/nsCacheEntryDescriptor.cpp => netwerk/cache/nsCacheEntryDescriptor.cpp rename : netwerk/cache/src/nsCacheEntryDescriptor.h => netwerk/cache/nsCacheEntryDescriptor.h rename : netwerk/cache/src/nsCacheMetaData.cpp => netwerk/cache/nsCacheMetaData.cpp rename : netwerk/cache/src/nsCacheMetaData.h => netwerk/cache/nsCacheMetaData.h rename : netwerk/cache/src/nsCacheRequest.h => netwerk/cache/nsCacheRequest.h rename : netwerk/cache/src/nsCacheService.cpp => netwerk/cache/nsCacheService.cpp rename : netwerk/cache/src/nsCacheService.h => netwerk/cache/nsCacheService.h rename : netwerk/cache/src/nsCacheSession.cpp => netwerk/cache/nsCacheSession.cpp rename : netwerk/cache/src/nsCacheSession.h => netwerk/cache/nsCacheSession.h rename : netwerk/cache/src/nsDeleteDir.cpp => netwerk/cache/nsDeleteDir.cpp rename : netwerk/cache/src/nsDeleteDir.h => netwerk/cache/nsDeleteDir.h rename : netwerk/cache/src/nsDiskCache.h => netwerk/cache/nsDiskCache.h rename : netwerk/cache/src/nsDiskCacheBinding.cpp => netwerk/cache/nsDiskCacheBinding.cpp rename : netwerk/cache/src/nsDiskCacheBinding.h => netwerk/cache/nsDiskCacheBinding.h rename : netwerk/cache/src/nsDiskCacheBlockFile.cpp => netwerk/cache/nsDiskCacheBlockFile.cpp rename : netwerk/cache/src/nsDiskCacheBlockFile.h => netwerk/cache/nsDiskCacheBlockFile.h rename : netwerk/cache/src/nsDiskCacheDevice.cpp => netwerk/cache/nsDiskCacheDevice.cpp rename : netwerk/cache/src/nsDiskCacheDevice.h => netwerk/cache/nsDiskCacheDevice.h rename : netwerk/cache/src/nsDiskCacheDeviceSQL.cpp => netwerk/cache/nsDiskCacheDeviceSQL.cpp rename : netwerk/cache/src/nsDiskCacheDeviceSQL.h => netwerk/cache/nsDiskCacheDeviceSQL.h rename : netwerk/cache/src/nsDiskCacheEntry.cpp => netwerk/cache/nsDiskCacheEntry.cpp rename : netwerk/cache/src/nsDiskCacheEntry.h => netwerk/cache/nsDiskCacheEntry.h rename : netwerk/cache/src/nsDiskCacheMap.cpp => netwerk/cache/nsDiskCacheMap.cpp rename : netwerk/cache/src/nsDiskCacheMap.h => netwerk/cache/nsDiskCacheMap.h rename : netwerk/cache/src/nsDiskCacheStreams.cpp => netwerk/cache/nsDiskCacheStreams.cpp rename : netwerk/cache/src/nsDiskCacheStreams.h => netwerk/cache/nsDiskCacheStreams.h rename : netwerk/cache/public/nsICache.idl => netwerk/cache/nsICache.idl rename : netwerk/cache/public/nsICacheEntryDescriptor.idl => netwerk/cache/nsICacheEntryDescriptor.idl rename : netwerk/cache/public/nsICacheListener.idl => netwerk/cache/nsICacheListener.idl rename : netwerk/cache/public/nsICacheService.idl => netwerk/cache/nsICacheService.idl rename : netwerk/cache/public/nsICacheSession.idl => netwerk/cache/nsICacheSession.idl rename : netwerk/cache/public/nsICacheVisitor.idl => netwerk/cache/nsICacheVisitor.idl rename : netwerk/cache/src/nsMemoryCacheDevice.cpp => netwerk/cache/nsMemoryCacheDevice.cpp rename : netwerk/cache/src/nsMemoryCacheDevice.h => netwerk/cache/nsMemoryCacheDevice.h rename : netwerk/cookie/src/nsCookie.cpp => netwerk/cookie/nsCookie.cpp rename : netwerk/cookie/src/nsCookie.h => netwerk/cookie/nsCookie.h rename : netwerk/cookie/src/nsCookieService.cpp => netwerk/cookie/nsCookieService.cpp rename : netwerk/cookie/src/nsCookieService.h => netwerk/cookie/nsCookieService.h rename : netwerk/cookie/public/nsICookie.idl => netwerk/cookie/nsICookie.idl rename : netwerk/cookie/public/nsICookie2.idl => netwerk/cookie/nsICookie2.idl rename : netwerk/cookie/public/nsICookieManager.idl => netwerk/cookie/nsICookieManager.idl rename : netwerk/cookie/public/nsICookieManager2.idl => netwerk/cookie/nsICookieManager2.idl rename : netwerk/cookie/public/nsICookiePermission.idl => netwerk/cookie/nsICookiePermission.idl rename : netwerk/cookie/public/nsICookieService.idl => netwerk/cookie/nsICookieService.idl rename : netwerk/dns/src/effective_tld_names.dat => netwerk/dns/effective_tld_names.dat rename : netwerk/dns/src/nameprep.c => netwerk/dns/nameprep.c rename : netwerk/dns/src/nameprep_template.c => netwerk/dns/nameprep_template.c rename : netwerk/dns/src/nameprepdata.c => netwerk/dns/nameprepdata.c rename : netwerk/dns/src/nsDNSService2.cpp => netwerk/dns/nsDNSService2.cpp rename : netwerk/dns/src/nsDNSService2.h => netwerk/dns/nsDNSService2.h rename : netwerk/dns/src/nsEffectiveTLDService.cpp => netwerk/dns/nsEffectiveTLDService.cpp rename : netwerk/dns/src/nsEffectiveTLDService.h => netwerk/dns/nsEffectiveTLDService.h rename : netwerk/dns/src/nsHostResolver.cpp => netwerk/dns/nsHostResolver.cpp rename : netwerk/dns/src/nsHostResolver.h => netwerk/dns/nsHostResolver.h rename : netwerk/dns/src/nsIDNKitInterface.h => netwerk/dns/nsIDNKitInterface.h rename : netwerk/dns/public/nsIDNSListener.idl => netwerk/dns/nsIDNSListener.idl rename : netwerk/dns/public/nsIDNSRecord.idl => netwerk/dns/nsIDNSRecord.idl rename : netwerk/dns/public/nsIDNSRequest.idl => netwerk/dns/nsIDNSRequest.idl rename : netwerk/dns/public/nsIDNSService.idl => netwerk/dns/nsIDNSService.idl rename : netwerk/dns/src/nsIDNService.cpp => netwerk/dns/nsIDNService.cpp rename : netwerk/dns/src/nsIDNService.h => netwerk/dns/nsIDNService.h rename : netwerk/dns/public/nsIEffectiveTLDService.idl => netwerk/dns/nsIEffectiveTLDService.idl rename : netwerk/dns/public/nsIIDNService.idl => netwerk/dns/nsIIDNService.idl rename : netwerk/dns/public/nsPIDNSService.idl => netwerk/dns/nsPIDNSService.idl rename : netwerk/dns/src/prepare_tlds.py => netwerk/dns/prepare_tlds.py rename : netwerk/dns/src/punycode.c => netwerk/dns/punycode.c rename : netwerk/dns/src/punycode.h => netwerk/dns/punycode.h rename : netwerk/dns/src/race.c => netwerk/dns/race.c rename : netwerk/mime/public/nsIMIMEHeaderParam.idl => netwerk/mime/nsIMIMEHeaderParam.idl rename : netwerk/mime/public/nsIMIMEInfo.idl => netwerk/mime/nsIMIMEInfo.idl rename : netwerk/mime/public/nsIMIMEService.idl => netwerk/mime/nsIMIMEService.idl rename : netwerk/mime/src/nsMIMEHeaderParamImpl.cpp => netwerk/mime/nsMIMEHeaderParamImpl.cpp rename : netwerk/mime/src/nsMIMEHeaderParamImpl.h => netwerk/mime/nsMIMEHeaderParamImpl.h rename : netwerk/mime/public/nsMimeTypes.h => netwerk/mime/nsMimeTypes.h rename : netwerk/protocol/about/src/nsAboutBlank.cpp => netwerk/protocol/about/nsAboutBlank.cpp rename : netwerk/protocol/about/src/nsAboutBlank.h => netwerk/protocol/about/nsAboutBlank.h rename : netwerk/protocol/about/src/nsAboutBloat.cpp => netwerk/protocol/about/nsAboutBloat.cpp rename : netwerk/protocol/about/src/nsAboutBloat.h => netwerk/protocol/about/nsAboutBloat.h rename : netwerk/protocol/about/src/nsAboutCache.cpp => netwerk/protocol/about/nsAboutCache.cpp rename : netwerk/protocol/about/src/nsAboutCache.h => netwerk/protocol/about/nsAboutCache.h rename : netwerk/protocol/about/src/nsAboutCacheEntry.cpp => netwerk/protocol/about/nsAboutCacheEntry.cpp rename : netwerk/protocol/about/src/nsAboutCacheEntry.h => netwerk/protocol/about/nsAboutCacheEntry.h rename : netwerk/protocol/about/src/nsAboutProtocolHandler.cpp => netwerk/protocol/about/nsAboutProtocolHandler.cpp rename : netwerk/protocol/about/src/nsAboutProtocolHandler.h => netwerk/protocol/about/nsAboutProtocolHandler.h rename : netwerk/protocol/about/public/nsAboutProtocolUtils.h => netwerk/protocol/about/nsAboutProtocolUtils.h rename : netwerk/protocol/about/public/nsIAboutModule.idl => netwerk/protocol/about/nsIAboutModule.idl rename : netwerk/protocol/data/src/nsDataChannel.cpp => netwerk/protocol/data/nsDataChannel.cpp rename : netwerk/protocol/data/src/nsDataChannel.h => netwerk/protocol/data/nsDataChannel.h rename : netwerk/protocol/data/src/nsDataHandler.cpp => netwerk/protocol/data/nsDataHandler.cpp rename : netwerk/protocol/data/src/nsDataHandler.h => netwerk/protocol/data/nsDataHandler.h rename : netwerk/protocol/data/src/nsDataModule.cpp => netwerk/protocol/data/nsDataModule.cpp rename : netwerk/protocol/file/src/nsFileChannel.cpp => netwerk/protocol/file/nsFileChannel.cpp rename : netwerk/protocol/file/src/nsFileChannel.h => netwerk/protocol/file/nsFileChannel.h rename : netwerk/protocol/file/src/nsFileProtocolHandler.cpp => netwerk/protocol/file/nsFileProtocolHandler.cpp rename : netwerk/protocol/file/src/nsFileProtocolHandler.h => netwerk/protocol/file/nsFileProtocolHandler.h rename : netwerk/protocol/file/public/nsIFileChannel.idl => netwerk/protocol/file/nsIFileChannel.idl rename : netwerk/protocol/file/public/nsIFileProtocolHandler.idl => netwerk/protocol/file/nsIFileProtocolHandler.idl rename : netwerk/protocol/ftp/public/ftpCore.h => netwerk/protocol/ftp/ftpCore.h rename : netwerk/protocol/ftp/src/nsFTPChannel.cpp => netwerk/protocol/ftp/nsFTPChannel.cpp rename : netwerk/protocol/ftp/src/nsFTPChannel.h => netwerk/protocol/ftp/nsFTPChannel.h rename : netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp => netwerk/protocol/ftp/nsFtpConnectionThread.cpp rename : netwerk/protocol/ftp/src/nsFtpConnectionThread.h => netwerk/protocol/ftp/nsFtpConnectionThread.h rename : netwerk/protocol/ftp/src/nsFtpControlConnection.cpp => netwerk/protocol/ftp/nsFtpControlConnection.cpp rename : netwerk/protocol/ftp/src/nsFtpControlConnection.h => netwerk/protocol/ftp/nsFtpControlConnection.h rename : netwerk/protocol/ftp/src/nsFtpProtocolHandler.cpp => netwerk/protocol/ftp/nsFtpProtocolHandler.cpp rename : netwerk/protocol/ftp/src/nsFtpProtocolHandler.h => netwerk/protocol/ftp/nsFtpProtocolHandler.h rename : netwerk/protocol/ftp/public/nsIFTPChannel.idl => netwerk/protocol/ftp/nsIFTPChannel.idl rename : netwerk/protocol/gopher/src/nsGopherChannel.cpp => netwerk/protocol/gopher/nsGopherChannel.cpp rename : netwerk/protocol/gopher/src/nsGopherChannel.h => netwerk/protocol/gopher/nsGopherChannel.h rename : netwerk/protocol/gopher/src/nsGopherHandler.cpp => netwerk/protocol/gopher/nsGopherHandler.cpp rename : netwerk/protocol/gopher/src/nsGopherHandler.h => netwerk/protocol/gopher/nsGopherHandler.h rename : netwerk/protocol/http/src/README => netwerk/protocol/http/README rename : netwerk/protocol/http/src/nsAHttpConnection.h => netwerk/protocol/http/nsAHttpConnection.h rename : netwerk/protocol/http/src/nsAHttpTransaction.h => netwerk/protocol/http/nsAHttpTransaction.h rename : netwerk/protocol/http/src/nsHttp.cpp => netwerk/protocol/http/nsHttp.cpp rename : netwerk/protocol/http/src/nsHttp.h => netwerk/protocol/http/nsHttp.h rename : netwerk/protocol/http/src/nsHttpActivityDistributor.cpp => netwerk/protocol/http/nsHttpActivityDistributor.cpp rename : netwerk/protocol/http/src/nsHttpActivityDistributor.h => netwerk/protocol/http/nsHttpActivityDistributor.h rename : netwerk/protocol/http/src/nsHttpAtomList.h => netwerk/protocol/http/nsHttpAtomList.h rename : netwerk/protocol/http/src/nsHttpAuthCache.cpp => netwerk/protocol/http/nsHttpAuthCache.cpp rename : netwerk/protocol/http/src/nsHttpAuthCache.h => netwerk/protocol/http/nsHttpAuthCache.h rename : netwerk/protocol/http/src/nsHttpAuthManager.cpp => netwerk/protocol/http/nsHttpAuthManager.cpp rename : netwerk/protocol/http/src/nsHttpAuthManager.h => netwerk/protocol/http/nsHttpAuthManager.h rename : netwerk/protocol/http/src/nsHttpBasicAuth.cpp => netwerk/protocol/http/nsHttpBasicAuth.cpp rename : netwerk/protocol/http/src/nsHttpBasicAuth.h => netwerk/protocol/http/nsHttpBasicAuth.h rename : netwerk/protocol/http/src/nsHttpChannel.cpp => netwerk/protocol/http/nsHttpChannel.cpp rename : netwerk/protocol/http/src/nsHttpChannel.h => netwerk/protocol/http/nsHttpChannel.h rename : netwerk/protocol/http/src/nsHttpChunkedDecoder.cpp => netwerk/protocol/http/nsHttpChunkedDecoder.cpp rename : netwerk/protocol/http/src/nsHttpChunkedDecoder.h => netwerk/protocol/http/nsHttpChunkedDecoder.h rename : netwerk/protocol/http/src/nsHttpConnection.cpp => netwerk/protocol/http/nsHttpConnection.cpp rename : netwerk/protocol/http/src/nsHttpConnection.h => netwerk/protocol/http/nsHttpConnection.h rename : netwerk/protocol/http/src/nsHttpConnectionInfo.cpp => netwerk/protocol/http/nsHttpConnectionInfo.cpp rename : netwerk/protocol/http/src/nsHttpConnectionInfo.h => netwerk/protocol/http/nsHttpConnectionInfo.h rename : netwerk/protocol/http/src/nsHttpConnectionMgr.cpp => netwerk/protocol/http/nsHttpConnectionMgr.cpp rename : netwerk/protocol/http/src/nsHttpConnectionMgr.h => netwerk/protocol/http/nsHttpConnectionMgr.h rename : netwerk/protocol/http/src/nsHttpDigestAuth.cpp => netwerk/protocol/http/nsHttpDigestAuth.cpp rename : netwerk/protocol/http/src/nsHttpDigestAuth.h => netwerk/protocol/http/nsHttpDigestAuth.h rename : netwerk/protocol/http/src/nsHttpHandler.cpp => netwerk/protocol/http/nsHttpHandler.cpp rename : netwerk/protocol/http/src/nsHttpHandler.h => netwerk/protocol/http/nsHttpHandler.h rename : netwerk/protocol/http/src/nsHttpHeaderArray.cpp => netwerk/protocol/http/nsHttpHeaderArray.cpp rename : netwerk/protocol/http/src/nsHttpHeaderArray.h => netwerk/protocol/http/nsHttpHeaderArray.h rename : netwerk/protocol/http/src/nsHttpNTLMAuth.cpp => netwerk/protocol/http/nsHttpNTLMAuth.cpp rename : netwerk/protocol/http/src/nsHttpNTLMAuth.h => netwerk/protocol/http/nsHttpNTLMAuth.h rename : netwerk/protocol/http/src/nsHttpPipeline.cpp => netwerk/protocol/http/nsHttpPipeline.cpp rename : netwerk/protocol/http/src/nsHttpPipeline.h => netwerk/protocol/http/nsHttpPipeline.h rename : netwerk/protocol/http/src/nsHttpRequestHead.cpp => netwerk/protocol/http/nsHttpRequestHead.cpp rename : netwerk/protocol/http/src/nsHttpRequestHead.h => netwerk/protocol/http/nsHttpRequestHead.h rename : netwerk/protocol/http/src/nsHttpResponseHead.cpp => netwerk/protocol/http/nsHttpResponseHead.cpp rename : netwerk/protocol/http/src/nsHttpResponseHead.h => netwerk/protocol/http/nsHttpResponseHead.h rename : netwerk/protocol/http/src/nsHttpTransaction.cpp => netwerk/protocol/http/nsHttpTransaction.cpp rename : netwerk/protocol/http/src/nsHttpTransaction.h => netwerk/protocol/http/nsHttpTransaction.h rename : netwerk/protocol/http/public/nsIHttpActivityObserver.idl => netwerk/protocol/http/nsIHttpActivityObserver.idl rename : netwerk/protocol/http/public/nsIHttpAuthManager.idl => netwerk/protocol/http/nsIHttpAuthManager.idl rename : netwerk/protocol/http/public/nsIHttpAuthenticator.idl => netwerk/protocol/http/nsIHttpAuthenticator.idl rename : netwerk/protocol/http/public/nsIHttpChannel.idl => netwerk/protocol/http/nsIHttpChannel.idl rename : netwerk/protocol/http/public/nsIHttpChannelInternal.idl => netwerk/protocol/http/nsIHttpChannelInternal.idl rename : netwerk/protocol/http/public/nsIHttpEventSink.idl => netwerk/protocol/http/nsIHttpEventSink.idl rename : netwerk/protocol/http/public/nsIHttpHeaderVisitor.idl => netwerk/protocol/http/nsIHttpHeaderVisitor.idl rename : netwerk/protocol/http/public/nsIHttpProtocolHandler.idl => netwerk/protocol/http/nsIHttpProtocolHandler.idl rename : netwerk/protocol/res/public/nsIResProtocolHandler.idl => netwerk/protocol/res/nsIResProtocolHandler.idl rename : netwerk/protocol/res/src/nsResProtocolHandler.cpp => netwerk/protocol/res/nsResProtocolHandler.cpp rename : netwerk/protocol/res/src/nsResProtocolHandler.h => netwerk/protocol/res/nsResProtocolHandler.h rename : netwerk/protocol/viewsource/public/nsIViewSourceChannel.idl => netwerk/protocol/viewsource/nsIViewSourceChannel.idl rename : netwerk/protocol/viewsource/src/nsViewSourceChannel.cpp => netwerk/protocol/viewsource/nsViewSourceChannel.cpp rename : netwerk/protocol/viewsource/src/nsViewSourceChannel.h => netwerk/protocol/viewsource/nsViewSourceChannel.h rename : netwerk/protocol/viewsource/src/nsViewSourceHandler.cpp => netwerk/protocol/viewsource/nsViewSourceHandler.cpp rename : netwerk/protocol/viewsource/src/nsViewSourceHandler.h => netwerk/protocol/viewsource/nsViewSourceHandler.h rename : netwerk/socket/base/nsISOCKSSocketInfo.idl => netwerk/socket/nsISOCKSSocketInfo.idl rename : netwerk/socket/base/nsISSLSocketControl.idl => netwerk/socket/nsISSLSocketControl.idl rename : netwerk/socket/base/nsISocketProvider.idl => netwerk/socket/nsISocketProvider.idl rename : netwerk/socket/base/nsISocketProviderService.idl => netwerk/socket/nsISocketProviderService.idl rename : netwerk/socket/base/nsITransportSecurityInfo.idl => netwerk/socket/nsITransportSecurityInfo.idl rename : netwerk/socket/base/nsSOCKS4SocketProvider.h => netwerk/socket/nsSOCKS4SocketProvider.h rename : netwerk/socket/base/nsSOCKSIOLayer.cpp => netwerk/socket/nsSOCKSIOLayer.cpp rename : netwerk/socket/base/nsSOCKSIOLayer.h => netwerk/socket/nsSOCKSIOLayer.h rename : netwerk/socket/base/nsSOCKSSocketProvider.cpp => netwerk/socket/nsSOCKSSocketProvider.cpp rename : netwerk/socket/base/nsSOCKSSocketProvider.h => netwerk/socket/nsSOCKSSocketProvider.h rename : netwerk/socket/base/nsSocketProviderService.cpp => netwerk/socket/nsSocketProviderService.cpp rename : netwerk/socket/base/nsSocketProviderService.h => netwerk/socket/nsSocketProviderService.h rename : netwerk/socket/base/nsUDPSocketProvider.cpp => netwerk/socket/nsUDPSocketProvider.cpp rename : netwerk/socket/base/nsUDPSocketProvider.h => netwerk/socket/nsUDPSocketProvider.h rename : netwerk/wifi/public/nsIWifiAccessPoint.idl => netwerk/wifi/nsIWifiAccessPoint.idl rename : netwerk/wifi/public/nsIWifiListener.idl => netwerk/wifi/nsIWifiListener.idl rename : netwerk/wifi/public/nsIWifiMonitor.idl => netwerk/wifi/nsIWifiMonitor.idl rename : netwerk/wifi/src/nsWifiAccessPoint.cpp => netwerk/wifi/nsWifiAccessPoint.cpp rename : netwerk/wifi/src/nsWifiAccessPoint.h => netwerk/wifi/nsWifiAccessPoint.h rename : netwerk/wifi/src/nsWifiMonitor.cpp => netwerk/wifi/nsWifiMonitor.cpp rename : netwerk/wifi/src/nsWifiMonitor.h => netwerk/wifi/nsWifiMonitor.h rename : netwerk/wifi/src/nsWifiScannerMac.cpp => netwerk/wifi/nsWifiScannerMac.cpp rename : netwerk/wifi/src/nsWifiScannerSolaris.cpp => netwerk/wifi/nsWifiScannerSolaris.cpp rename : netwerk/wifi/src/nsWifiScannerUnix.cpp => netwerk/wifi/nsWifiScannerUnix.cpp rename : netwerk/wifi/src/nsWifiScannerWin.cpp => netwerk/wifi/nsWifiScannerWin.cpp rename : netwerk/wifi/src/osx_corewlan.mm => netwerk/wifi/osx_corewlan.mm rename : netwerk/wifi/src/osx_wifi.h => netwerk/wifi/osx_wifi.h rename : netwerk/wifi/src/wlanapi.h => netwerk/wifi/wlanapi.h
993 lines
30 KiB
C++
993 lines
30 KiB
C++
/* vim:set ts=4 sw=4 sts=4 et cin: */
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla 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/MPL/
|
|
*
|
|
* 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.
|
|
*
|
|
* The Original Code is Mozilla.
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* Netscape Communications Corporation.
|
|
* Portions created by the Initial Developer are Copyright (C) 2002
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Darin Fisher <darin@netscape.com>
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#include "nsHttpConnectionMgr.h"
|
|
#include "nsHttpConnection.h"
|
|
#include "nsHttpPipeline.h"
|
|
#include "nsHttpHandler.h"
|
|
#include "nsAutoLock.h"
|
|
#include "nsNetCID.h"
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
// defined by the socket transport service while active
|
|
extern PRThread *gSocketThread;
|
|
|
|
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
static void
|
|
InsertTransactionSorted(nsTArray<nsHttpTransaction*> &pendingQ, nsHttpTransaction *trans)
|
|
{
|
|
// insert into queue with smallest valued number first. search in reverse
|
|
// order under the assumption that many of the existing transactions will
|
|
// have the same priority (usually 0).
|
|
|
|
for (PRInt32 i=pendingQ.Length()-1; i>=0; --i) {
|
|
nsHttpTransaction *t = pendingQ[i];
|
|
if (trans->Priority() >= t->Priority()) {
|
|
pendingQ.InsertElementAt(i+1, trans);
|
|
return;
|
|
}
|
|
}
|
|
pendingQ.InsertElementAt(0, trans);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
nsHttpConnectionMgr::nsHttpConnectionMgr()
|
|
: mRef(0)
|
|
, mMonitor(nsAutoMonitor::NewMonitor("nsHttpConnectionMgr"))
|
|
, mMaxConns(0)
|
|
, mMaxConnsPerHost(0)
|
|
, mMaxConnsPerProxy(0)
|
|
, mMaxPersistConnsPerHost(0)
|
|
, mMaxPersistConnsPerProxy(0)
|
|
, mNumActiveConns(0)
|
|
, mNumIdleConns(0)
|
|
{
|
|
LOG(("Creating nsHttpConnectionMgr @%x\n", this));
|
|
}
|
|
|
|
nsHttpConnectionMgr::~nsHttpConnectionMgr()
|
|
{
|
|
LOG(("Destroying nsHttpConnectionMgr @%x\n", this));
|
|
|
|
if (mMonitor)
|
|
nsAutoMonitor::DestroyMonitor(mMonitor);
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::Init(PRUint16 maxConns,
|
|
PRUint16 maxConnsPerHost,
|
|
PRUint16 maxConnsPerProxy,
|
|
PRUint16 maxPersistConnsPerHost,
|
|
PRUint16 maxPersistConnsPerProxy,
|
|
PRUint16 maxRequestDelay,
|
|
PRUint16 maxPipelinedRequests)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::Init\n"));
|
|
|
|
nsresult rv;
|
|
nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
nsAutoMonitor mon(mMonitor);
|
|
|
|
// do nothing if already initialized
|
|
if (mSocketThreadTarget)
|
|
return NS_OK;
|
|
|
|
// no need to do any special synchronization here since there cannot be
|
|
// any activity on the socket thread (because Shutdown is synchronous).
|
|
mMaxConns = maxConns;
|
|
mMaxConnsPerHost = maxConnsPerHost;
|
|
mMaxConnsPerProxy = maxConnsPerProxy;
|
|
mMaxPersistConnsPerHost = maxPersistConnsPerHost;
|
|
mMaxPersistConnsPerProxy = maxPersistConnsPerProxy;
|
|
mMaxRequestDelay = maxRequestDelay;
|
|
mMaxPipelinedRequests = maxPipelinedRequests;
|
|
|
|
mSocketThreadTarget = sts;
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::Shutdown()
|
|
{
|
|
LOG(("nsHttpConnectionMgr::Shutdown\n"));
|
|
|
|
nsAutoMonitor mon(mMonitor);
|
|
|
|
// do nothing if already shutdown
|
|
if (!mSocketThreadTarget)
|
|
return NS_OK;
|
|
|
|
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgShutdown);
|
|
|
|
// release our reference to the STS to prevent further events
|
|
// from being posted. this is how we indicate that we are
|
|
// shutting down.
|
|
mSocketThreadTarget = 0;
|
|
|
|
if (NS_FAILED(rv)) {
|
|
NS_WARNING("unable to post SHUTDOWN message");
|
|
return rv;
|
|
}
|
|
|
|
// wait for shutdown event to complete
|
|
mon.Wait();
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::PostEvent(nsConnEventHandler handler, PRInt32 iparam, void *vparam)
|
|
{
|
|
nsAutoMonitor mon(mMonitor);
|
|
|
|
nsresult rv;
|
|
if (!mSocketThreadTarget) {
|
|
NS_WARNING("cannot post event if not initialized");
|
|
rv = NS_ERROR_NOT_INITIALIZED;
|
|
}
|
|
else {
|
|
nsRefPtr<nsIRunnable> event = new nsConnEvent(this, handler, iparam, vparam);
|
|
if (!event)
|
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
|
else
|
|
rv = mSocketThreadTarget->Dispatch(event, NS_DISPATCH_NORMAL);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::AddTransaction(nsHttpTransaction *trans, PRInt32 priority)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::AddTransaction [trans=%x %d]\n", trans, priority));
|
|
|
|
NS_ADDREF(trans);
|
|
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgNewTransaction, priority, trans);
|
|
if (NS_FAILED(rv))
|
|
NS_RELEASE(trans);
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::RescheduleTransaction(nsHttpTransaction *trans, PRInt32 priority)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::RescheduleTransaction [trans=%x %d]\n", trans, priority));
|
|
|
|
NS_ADDREF(trans);
|
|
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgReschedTransaction, priority, trans);
|
|
if (NS_FAILED(rv))
|
|
NS_RELEASE(trans);
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::CancelTransaction(nsHttpTransaction *trans, nsresult reason)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::CancelTransaction [trans=%x reason=%x]\n", trans, reason));
|
|
|
|
NS_ADDREF(trans);
|
|
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgCancelTransaction, reason, trans);
|
|
if (NS_FAILED(rv))
|
|
NS_RELEASE(trans);
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::PruneDeadConnections()
|
|
{
|
|
return PostEvent(&nsHttpConnectionMgr::OnMsgPruneDeadConnections);
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::GetSocketThreadTarget(nsIEventTarget **target)
|
|
{
|
|
nsAutoMonitor mon(mMonitor);
|
|
NS_IF_ADDREF(*target = mSocketThreadTarget);
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
nsHttpConnectionMgr::AddTransactionToPipeline(nsHttpPipeline *pipeline)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::AddTransactionToPipeline [pipeline=%x]\n", pipeline));
|
|
|
|
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
|
|
|
|
nsRefPtr<nsHttpConnectionInfo> ci;
|
|
pipeline->GetConnectionInfo(getter_AddRefs(ci));
|
|
if (ci) {
|
|
nsCStringKey key(ci->HashKey());
|
|
nsConnectionEntry *ent = (nsConnectionEntry *) mCT.Get(&key);
|
|
if (ent) {
|
|
// search for another request to pipeline...
|
|
PRInt32 i, count = ent->mPendingQ.Length();
|
|
for (i=0; i<count; ++i) {
|
|
nsHttpTransaction *trans = ent->mPendingQ[i];
|
|
if (trans->Caps() & NS_HTTP_ALLOW_PIPELINING) {
|
|
pipeline->AddTransaction(trans);
|
|
|
|
// remove transaction from pending queue
|
|
ent->mPendingQ.RemoveElementAt(i);
|
|
NS_RELEASE(trans);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::ReclaimConnection(nsHttpConnection *conn)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::ReclaimConnection [conn=%x]\n", conn));
|
|
|
|
NS_ADDREF(conn);
|
|
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgReclaimConnection, 0, conn);
|
|
if (NS_FAILED(rv))
|
|
NS_RELEASE(conn);
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::UpdateParam(nsParamName name, PRUint16 value)
|
|
{
|
|
PRUint32 param = (PRUint32(name) << 16) | PRUint32(value);
|
|
return PostEvent(&nsHttpConnectionMgr::OnMsgUpdateParam, 0, (void *) param);
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::ProcessPendingQ(nsHttpConnectionInfo *ci)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", ci->HashKey().get()));
|
|
|
|
NS_ADDREF(ci);
|
|
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgProcessPendingQ, 0, ci);
|
|
if (NS_FAILED(rv))
|
|
NS_RELEASE(ci);
|
|
return rv;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// enumeration callbacks
|
|
|
|
PRIntn
|
|
nsHttpConnectionMgr::ProcessOneTransactionCB(nsHashKey *key, void *data, void *closure)
|
|
{
|
|
nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
|
|
nsConnectionEntry *ent = (nsConnectionEntry *) data;
|
|
|
|
if (self->ProcessPendingQForEntry(ent))
|
|
return kHashEnumerateStop;
|
|
|
|
return kHashEnumerateNext;
|
|
}
|
|
|
|
PRIntn
|
|
nsHttpConnectionMgr::PurgeOneIdleConnectionCB(nsHashKey *key, void *data, void *closure)
|
|
{
|
|
nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
|
|
nsConnectionEntry *ent = (nsConnectionEntry *) data;
|
|
|
|
if (ent->mIdleConns.Length() > 0) {
|
|
nsHttpConnection *conn = ent->mIdleConns[0];
|
|
ent->mIdleConns.RemoveElementAt(0);
|
|
conn->Close(NS_ERROR_ABORT);
|
|
NS_RELEASE(conn);
|
|
self->mNumIdleConns--;
|
|
return kHashEnumerateStop;
|
|
}
|
|
|
|
return kHashEnumerateNext;
|
|
}
|
|
|
|
PRIntn
|
|
nsHttpConnectionMgr::PruneDeadConnectionsCB(nsHashKey *key, void *data, void *closure)
|
|
{
|
|
nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
|
|
nsConnectionEntry *ent = (nsConnectionEntry *) data;
|
|
|
|
LOG((" pruning [ci=%s]\n", ent->mConnInfo->HashKey().get()));
|
|
|
|
PRInt32 count = ent->mIdleConns.Length();
|
|
if (count > 0) {
|
|
for (PRInt32 i=count-1; i>=0; --i) {
|
|
nsHttpConnection *conn = ent->mIdleConns[i];
|
|
if (!conn->CanReuse()) {
|
|
ent->mIdleConns.RemoveElementAt(i);
|
|
conn->Close(NS_ERROR_ABORT);
|
|
NS_RELEASE(conn);
|
|
self->mNumIdleConns--;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
count = ent->mActiveConns.Length();
|
|
if (count > 0) {
|
|
for (PRInt32 i=count-1; i>=0; --i) {
|
|
nsHttpConnection *conn = ent->mActiveConns[i];
|
|
LOG((" active conn [%x] with trans [%x]\n", conn, conn->Transaction()));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// if this entry is empty, then we can remove it.
|
|
if (ent->mIdleConns.Length() == 0 &&
|
|
ent->mActiveConns.Length() == 0 &&
|
|
ent->mPendingQ.Length() == 0) {
|
|
LOG((" removing empty connection entry\n"));
|
|
delete ent;
|
|
return kHashEnumerateRemove;
|
|
}
|
|
|
|
// else, use this opportunity to compact our arrays...
|
|
ent->mIdleConns.Compact();
|
|
ent->mActiveConns.Compact();
|
|
ent->mPendingQ.Compact();
|
|
|
|
return kHashEnumerateNext;
|
|
}
|
|
|
|
PRIntn
|
|
nsHttpConnectionMgr::ShutdownPassCB(nsHashKey *key, void *data, void *closure)
|
|
{
|
|
nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
|
|
nsConnectionEntry *ent = (nsConnectionEntry *) data;
|
|
|
|
nsHttpTransaction *trans;
|
|
nsHttpConnection *conn;
|
|
|
|
// close all active connections
|
|
while (ent->mActiveConns.Length()) {
|
|
conn = ent->mActiveConns[0];
|
|
|
|
ent->mActiveConns.RemoveElementAt(0);
|
|
self->mNumActiveConns--;
|
|
|
|
conn->Close(NS_ERROR_ABORT);
|
|
NS_RELEASE(conn);
|
|
}
|
|
|
|
// close all idle connections
|
|
while (ent->mIdleConns.Length()) {
|
|
conn = ent->mIdleConns[0];
|
|
|
|
ent->mIdleConns.RemoveElementAt(0);
|
|
self->mNumIdleConns--;
|
|
|
|
conn->Close(NS_ERROR_ABORT);
|
|
NS_RELEASE(conn);
|
|
}
|
|
|
|
// close all pending transactions
|
|
while (ent->mPendingQ.Length()) {
|
|
trans = ent->mPendingQ[0];
|
|
|
|
ent->mPendingQ.RemoveElementAt(0);
|
|
|
|
trans->Close(NS_ERROR_ABORT);
|
|
NS_RELEASE(trans);
|
|
}
|
|
|
|
delete ent;
|
|
return kHashEnumerateRemove;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
PRBool
|
|
nsHttpConnectionMgr::ProcessPendingQForEntry(nsConnectionEntry *ent)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::ProcessPendingQForEntry [ci=%s]\n",
|
|
ent->mConnInfo->HashKey().get()));
|
|
|
|
PRInt32 i, count = ent->mPendingQ.Length();
|
|
if (count > 0) {
|
|
LOG((" pending-count=%u\n", count));
|
|
nsHttpTransaction *trans = nsnull;
|
|
nsHttpConnection *conn = nsnull;
|
|
for (i=0; i<count; ++i) {
|
|
trans = ent->mPendingQ[i];
|
|
GetConnection(ent, trans->Caps(), &conn);
|
|
if (conn)
|
|
break;
|
|
}
|
|
if (conn) {
|
|
LOG((" dispatching pending transaction...\n"));
|
|
|
|
// remove pending transaction
|
|
ent->mPendingQ.RemoveElementAt(i);
|
|
|
|
nsresult rv = DispatchTransaction(ent, trans, trans->Caps(), conn);
|
|
if (NS_SUCCEEDED(rv))
|
|
NS_RELEASE(trans);
|
|
else {
|
|
LOG((" DispatchTransaction failed [rv=%x]\n", rv));
|
|
// on failure, just put the transaction back
|
|
ent->mPendingQ.InsertElementAt(i, trans);
|
|
// might be something wrong with the connection... close it.
|
|
conn->Close(rv);
|
|
}
|
|
|
|
NS_RELEASE(conn);
|
|
return PR_TRUE;
|
|
}
|
|
}
|
|
return PR_FALSE;
|
|
}
|
|
|
|
// we're at the active connection limit if any one of the following conditions is true:
|
|
// (1) at max-connections
|
|
// (2) keep-alive enabled and at max-persistent-connections-per-server/proxy
|
|
// (3) keep-alive disabled and at max-connections-per-server
|
|
PRBool
|
|
nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, PRUint8 caps)
|
|
{
|
|
nsHttpConnectionInfo *ci = ent->mConnInfo;
|
|
|
|
LOG(("nsHttpConnectionMgr::AtActiveConnectionLimit [ci=%s caps=%x]\n",
|
|
ci->HashKey().get(), caps));
|
|
|
|
// use >= just to be safe
|
|
if (mNumActiveConns >= mMaxConns) {
|
|
LOG((" num active conns == max conns\n"));
|
|
return PR_TRUE;
|
|
}
|
|
|
|
nsHttpConnection *conn;
|
|
PRInt32 i, totalCount, persistCount = 0;
|
|
|
|
totalCount = ent->mActiveConns.Length();
|
|
|
|
// count the number of persistent connections
|
|
for (i=0; i<totalCount; ++i) {
|
|
conn = ent->mActiveConns[i];
|
|
if (conn->IsKeepAlive()) // XXX make sure this is thread-safe
|
|
persistCount++;
|
|
}
|
|
|
|
LOG((" total=%d, persist=%d\n", totalCount, persistCount));
|
|
|
|
PRUint16 maxConns;
|
|
PRUint16 maxPersistConns;
|
|
|
|
if (ci->UsingHttpProxy() && !ci->UsingSSL()) {
|
|
maxConns = mMaxConnsPerProxy;
|
|
maxPersistConns = mMaxPersistConnsPerProxy;
|
|
}
|
|
else {
|
|
maxConns = mMaxConnsPerHost;
|
|
maxPersistConns = mMaxPersistConnsPerHost;
|
|
}
|
|
|
|
// use >= just to be safe
|
|
return (totalCount >= maxConns) || ( (caps & NS_HTTP_ALLOW_KEEPALIVE) &&
|
|
(persistCount >= maxPersistConns) );
|
|
}
|
|
|
|
void
|
|
nsHttpConnectionMgr::GetConnection(nsConnectionEntry *ent, PRUint8 caps,
|
|
nsHttpConnection **result)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::GetConnection [ci=%s caps=%x]\n",
|
|
ent->mConnInfo->HashKey().get(), PRUint32(caps)));
|
|
|
|
*result = nsnull;
|
|
|
|
if (AtActiveConnectionLimit(ent, caps)) {
|
|
LOG((" at active connection limit!\n"));
|
|
return;
|
|
}
|
|
|
|
nsHttpConnection *conn = nsnull;
|
|
|
|
if (caps & NS_HTTP_ALLOW_KEEPALIVE) {
|
|
// search the idle connection list
|
|
while (!conn && (ent->mIdleConns.Length() > 0)) {
|
|
conn = ent->mIdleConns[0];
|
|
// we check if the connection can be reused before even checking if
|
|
// it is a "matching" connection.
|
|
if (!conn->CanReuse()) {
|
|
LOG((" dropping stale connection: [conn=%x]\n", conn));
|
|
conn->Close(NS_ERROR_ABORT);
|
|
NS_RELEASE(conn);
|
|
}
|
|
else
|
|
LOG((" reusing connection [conn=%x]\n", conn));
|
|
ent->mIdleConns.RemoveElementAt(0);
|
|
mNumIdleConns--;
|
|
}
|
|
}
|
|
|
|
if (!conn) {
|
|
conn = new nsHttpConnection();
|
|
if (!conn)
|
|
return;
|
|
NS_ADDREF(conn);
|
|
|
|
nsresult rv = conn->Init(ent->mConnInfo, mMaxRequestDelay);
|
|
if (NS_FAILED(rv)) {
|
|
NS_RELEASE(conn);
|
|
return;
|
|
}
|
|
|
|
// We created a new connection that will become active, purge the
|
|
// oldest idle connection if we've reached the upper limit.
|
|
if (mNumIdleConns + mNumActiveConns + 1 > mMaxConns)
|
|
mCT.Enumerate(PurgeOneIdleConnectionCB, this);
|
|
|
|
// XXX this just purges a random idle connection. we should instead
|
|
// enumerate the entire hash table to find the eldest idle connection.
|
|
}
|
|
|
|
*result = conn;
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::DispatchTransaction(nsConnectionEntry *ent,
|
|
nsAHttpTransaction *trans,
|
|
PRUint8 caps,
|
|
nsHttpConnection *conn)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::DispatchTransaction [ci=%s trans=%x caps=%x conn=%x]\n",
|
|
ent->mConnInfo->HashKey().get(), trans, caps, conn));
|
|
|
|
nsConnectionHandle *handle = new nsConnectionHandle(conn);
|
|
if (!handle)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
NS_ADDREF(handle);
|
|
|
|
nsHttpPipeline *pipeline = nsnull;
|
|
if (conn->SupportsPipelining() && (caps & NS_HTTP_ALLOW_PIPELINING)) {
|
|
LOG((" looking to build pipeline...\n"));
|
|
if (BuildPipeline(ent, trans, &pipeline))
|
|
trans = pipeline;
|
|
}
|
|
|
|
// hold an owning ref to this connection
|
|
ent->mActiveConns.AppendElement(conn);
|
|
mNumActiveConns++;
|
|
NS_ADDREF(conn);
|
|
|
|
// give the transaction the indirect reference to the connection.
|
|
trans->SetConnection(handle);
|
|
|
|
nsresult rv = conn->Activate(trans, caps);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
LOG((" conn->Activate failed [rv=%x]\n", rv));
|
|
ent->mActiveConns.RemoveElement(conn);
|
|
mNumActiveConns--;
|
|
// sever back references to connection, and do so without triggering
|
|
// a call to ReclaimConnection ;-)
|
|
trans->SetConnection(nsnull);
|
|
NS_RELEASE(handle->mConn);
|
|
// destroy the connection
|
|
NS_RELEASE(conn);
|
|
}
|
|
|
|
// if we were unable to activate the pipeline, then this will destroy
|
|
// the pipeline, which will cause each the transactions owned by the
|
|
// pipeline to be restarted.
|
|
NS_IF_RELEASE(pipeline);
|
|
|
|
NS_RELEASE(handle);
|
|
return rv;
|
|
}
|
|
|
|
PRBool
|
|
nsHttpConnectionMgr::BuildPipeline(nsConnectionEntry *ent,
|
|
nsAHttpTransaction *firstTrans,
|
|
nsHttpPipeline **result)
|
|
{
|
|
if (mMaxPipelinedRequests < 2)
|
|
return PR_FALSE;
|
|
|
|
nsHttpPipeline *pipeline = nsnull;
|
|
nsHttpTransaction *trans;
|
|
|
|
PRUint32 i = 0, numAdded = 0;
|
|
while (i < ent->mPendingQ.Length()) {
|
|
trans = ent->mPendingQ[i];
|
|
if (trans->Caps() & NS_HTTP_ALLOW_PIPELINING) {
|
|
if (numAdded == 0) {
|
|
pipeline = new nsHttpPipeline;
|
|
if (!pipeline)
|
|
return PR_FALSE;
|
|
pipeline->AddTransaction(firstTrans);
|
|
numAdded = 1;
|
|
}
|
|
pipeline->AddTransaction(trans);
|
|
|
|
// remove transaction from pending queue
|
|
ent->mPendingQ.RemoveElementAt(i);
|
|
NS_RELEASE(trans);
|
|
|
|
if (++numAdded == mMaxPipelinedRequests)
|
|
break;
|
|
}
|
|
else
|
|
++i; // skip to next pending transaction
|
|
}
|
|
|
|
if (numAdded == 0)
|
|
return PR_FALSE;
|
|
|
|
LOG((" pipelined %u transactions\n", numAdded));
|
|
NS_ADDREF(*result = pipeline);
|
|
return PR_TRUE;
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
|
|
{
|
|
// since "adds" and "cancels" are processed asynchronously and because
|
|
// various events might trigger an "add" directly on the socket thread,
|
|
// we must take care to avoid dispatching a transaction that has already
|
|
// been canceled (see bug 190001).
|
|
if (NS_FAILED(trans->Status())) {
|
|
LOG((" transaction was canceled... dropping event!\n"));
|
|
return NS_OK;
|
|
}
|
|
|
|
PRUint8 caps = trans->Caps();
|
|
nsHttpConnectionInfo *ci = trans->ConnectionInfo();
|
|
NS_ASSERTION(ci, "no connection info");
|
|
|
|
nsCStringKey key(ci->HashKey());
|
|
nsConnectionEntry *ent = (nsConnectionEntry *) mCT.Get(&key);
|
|
if (!ent) {
|
|
nsHttpConnectionInfo *clone = ci->Clone();
|
|
if (!clone)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
ent = new nsConnectionEntry(clone);
|
|
if (!ent)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
mCT.Put(&key, ent);
|
|
}
|
|
|
|
nsHttpConnection *conn;
|
|
|
|
// check if the transaction already has a sticky reference to a connection.
|
|
// if so, then we can just use it directly. XXX check if alive??
|
|
// XXX add a TakeConnection method or something to make this clearer!
|
|
nsConnectionHandle *handle = (nsConnectionHandle *) trans->Connection();
|
|
if (handle) {
|
|
NS_ASSERTION(caps & NS_HTTP_STICKY_CONNECTION, "unexpected caps");
|
|
NS_ASSERTION(handle->mConn, "no connection");
|
|
|
|
// steal reference from connection handle.
|
|
// XXX prevent SetConnection(nsnull) from calling ReclaimConnection
|
|
conn = handle->mConn;
|
|
handle->mConn = nsnull;
|
|
|
|
// destroy connection handle.
|
|
trans->SetConnection(nsnull);
|
|
|
|
// remove sticky connection from active connection list; we'll add it
|
|
// right back in DispatchTransaction.
|
|
if (ent->mActiveConns.RemoveElement(conn))
|
|
mNumActiveConns--;
|
|
else {
|
|
NS_ERROR("sticky connection not found in active list");
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
}
|
|
else
|
|
GetConnection(ent, caps, &conn);
|
|
|
|
nsresult rv;
|
|
if (!conn) {
|
|
LOG((" adding transaction to pending queue [trans=%x pending-count=%u]\n",
|
|
trans, ent->mPendingQ.Length()+1));
|
|
// put this transaction on the pending queue...
|
|
InsertTransactionSorted(ent->mPendingQ, trans);
|
|
NS_ADDREF(trans);
|
|
rv = NS_OK;
|
|
}
|
|
else {
|
|
rv = DispatchTransaction(ent, trans, caps, conn);
|
|
NS_RELEASE(conn);
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void
|
|
nsHttpConnectionMgr::OnMsgShutdown(PRInt32, void *)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::OnMsgShutdown\n"));
|
|
|
|
mCT.Reset(ShutdownPassCB, this);
|
|
|
|
// signal shutdown complete
|
|
nsAutoMonitor mon(mMonitor);
|
|
mon.Notify();
|
|
}
|
|
|
|
void
|
|
nsHttpConnectionMgr::OnMsgNewTransaction(PRInt32 priority, void *param)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::OnMsgNewTransaction [trans=%p]\n", param));
|
|
|
|
nsHttpTransaction *trans = (nsHttpTransaction *) param;
|
|
trans->SetPriority(priority);
|
|
nsresult rv = ProcessNewTransaction(trans);
|
|
if (NS_FAILED(rv))
|
|
trans->Close(rv); // for whatever its worth
|
|
NS_RELEASE(trans);
|
|
}
|
|
|
|
void
|
|
nsHttpConnectionMgr::OnMsgReschedTransaction(PRInt32 priority, void *param)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::OnMsgNewTransaction [trans=%p]\n", param));
|
|
|
|
nsHttpTransaction *trans = (nsHttpTransaction *) param;
|
|
trans->SetPriority(priority);
|
|
|
|
nsHttpConnectionInfo *ci = trans->ConnectionInfo();
|
|
nsCStringKey key(ci->HashKey());
|
|
nsConnectionEntry *ent = (nsConnectionEntry *) mCT.Get(&key);
|
|
if (ent) {
|
|
PRInt32 index = ent->mPendingQ.IndexOf(trans);
|
|
if (index >= 0) {
|
|
ent->mPendingQ.RemoveElementAt(index);
|
|
InsertTransactionSorted(ent->mPendingQ, trans);
|
|
}
|
|
}
|
|
|
|
NS_RELEASE(trans);
|
|
}
|
|
|
|
void
|
|
nsHttpConnectionMgr::OnMsgCancelTransaction(PRInt32 reason, void *param)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p]\n", param));
|
|
|
|
nsHttpTransaction *trans = (nsHttpTransaction *) param;
|
|
//
|
|
// if the transaction owns a connection and the transaction is not done,
|
|
// then ask the connection to close the transaction. otherwise, close the
|
|
// transaction directly (removing it from the pending queue first).
|
|
//
|
|
nsAHttpConnection *conn = trans->Connection();
|
|
if (conn && !trans->IsDone())
|
|
conn->CloseTransaction(trans, reason);
|
|
else {
|
|
nsHttpConnectionInfo *ci = trans->ConnectionInfo();
|
|
nsCStringKey key(ci->HashKey());
|
|
nsConnectionEntry *ent = (nsConnectionEntry *) mCT.Get(&key);
|
|
if (ent) {
|
|
PRInt32 index = ent->mPendingQ.IndexOf(trans);
|
|
if (index >= 0) {
|
|
ent->mPendingQ.RemoveElementAt(index);
|
|
nsHttpTransaction *temp = trans;
|
|
NS_RELEASE(temp); // b/c NS_RELEASE nulls its argument!
|
|
}
|
|
}
|
|
trans->Close(reason);
|
|
}
|
|
NS_RELEASE(trans);
|
|
}
|
|
|
|
void
|
|
nsHttpConnectionMgr::OnMsgProcessPendingQ(PRInt32, void *param)
|
|
{
|
|
nsHttpConnectionInfo *ci = (nsHttpConnectionInfo *) param;
|
|
|
|
LOG(("nsHttpConnectionMgr::OnMsgProcessPendingQ [ci=%s]\n", ci->HashKey().get()));
|
|
|
|
// start by processing the queue identified by the given connection info.
|
|
nsCStringKey key(ci->HashKey());
|
|
nsConnectionEntry *ent = (nsConnectionEntry *) mCT.Get(&key);
|
|
if (!(ent && ProcessPendingQForEntry(ent))) {
|
|
// if we reach here, it means that we couldn't dispatch a transaction
|
|
// for the specified connection info. walk the connection table...
|
|
mCT.Enumerate(ProcessOneTransactionCB, this);
|
|
}
|
|
|
|
NS_RELEASE(ci);
|
|
}
|
|
|
|
void
|
|
nsHttpConnectionMgr::OnMsgPruneDeadConnections(PRInt32, void *)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::OnMsgPruneDeadConnections\n"));
|
|
|
|
if (mNumIdleConns > 0)
|
|
mCT.Enumerate(PruneDeadConnectionsCB, this);
|
|
}
|
|
|
|
void
|
|
nsHttpConnectionMgr::OnMsgReclaimConnection(PRInt32, void *param)
|
|
{
|
|
LOG(("nsHttpConnectionMgr::OnMsgReclaimConnection [conn=%p]\n", param));
|
|
|
|
nsHttpConnection *conn = (nsHttpConnection *) param;
|
|
|
|
//
|
|
// 1) remove the connection from the active list
|
|
// 2) if keep-alive, add connection to idle list
|
|
// 3) post event to process the pending transaction queue
|
|
//
|
|
|
|
nsHttpConnectionInfo *ci = conn->ConnectionInfo();
|
|
NS_ADDREF(ci);
|
|
|
|
nsCStringKey key(ci->HashKey());
|
|
nsConnectionEntry *ent = (nsConnectionEntry *) mCT.Get(&key);
|
|
|
|
NS_ASSERTION(ent, "no connection entry");
|
|
if (ent) {
|
|
ent->mActiveConns.RemoveElement(conn);
|
|
mNumActiveConns--;
|
|
if (conn->CanReuse()) {
|
|
LOG((" adding connection to idle list\n"));
|
|
// hold onto this connection in the idle list. we push it to
|
|
// the end of the list so as to ensure that we'll visit older
|
|
// connections first before getting to this one.
|
|
ent->mIdleConns.AppendElement(conn);
|
|
mNumIdleConns++;
|
|
}
|
|
else {
|
|
LOG((" connection cannot be reused; closing connection\n"));
|
|
// make sure the connection is closed and release our reference.
|
|
conn->Close(NS_ERROR_ABORT);
|
|
nsHttpConnection *temp = conn;
|
|
NS_RELEASE(temp);
|
|
}
|
|
}
|
|
|
|
OnMsgProcessPendingQ(NS_OK, ci); // releases |ci|
|
|
NS_RELEASE(conn);
|
|
}
|
|
|
|
void
|
|
nsHttpConnectionMgr::OnMsgUpdateParam(PRInt32, void *param)
|
|
{
|
|
PRUint16 name = (NS_PTR_TO_INT32(param) & 0xFFFF0000) >> 16;
|
|
PRUint16 value = NS_PTR_TO_INT32(param) & 0x0000FFFF;
|
|
|
|
switch (name) {
|
|
case MAX_CONNECTIONS:
|
|
mMaxConns = value;
|
|
break;
|
|
case MAX_CONNECTIONS_PER_HOST:
|
|
mMaxConnsPerHost = value;
|
|
break;
|
|
case MAX_CONNECTIONS_PER_PROXY:
|
|
mMaxConnsPerProxy = value;
|
|
break;
|
|
case MAX_PERSISTENT_CONNECTIONS_PER_HOST:
|
|
mMaxPersistConnsPerHost = value;
|
|
break;
|
|
case MAX_PERSISTENT_CONNECTIONS_PER_PROXY:
|
|
mMaxPersistConnsPerProxy = value;
|
|
break;
|
|
case MAX_REQUEST_DELAY:
|
|
mMaxRequestDelay = value;
|
|
break;
|
|
case MAX_PIPELINED_REQUESTS:
|
|
mMaxPipelinedRequests = value;
|
|
break;
|
|
default:
|
|
NS_NOTREACHED("unexpected parameter name");
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// nsHttpConnectionMgr::nsConnectionHandle
|
|
|
|
nsHttpConnectionMgr::nsConnectionHandle::~nsConnectionHandle()
|
|
{
|
|
if (mConn) {
|
|
gHttpHandler->ReclaimConnection(mConn);
|
|
NS_RELEASE(mConn);
|
|
}
|
|
}
|
|
|
|
NS_IMPL_THREADSAFE_ISUPPORTS0(nsHttpConnectionMgr::nsConnectionHandle)
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::nsConnectionHandle::OnHeadersAvailable(nsAHttpTransaction *trans,
|
|
nsHttpRequestHead *req,
|
|
nsHttpResponseHead *resp,
|
|
PRBool *reset)
|
|
{
|
|
return mConn->OnHeadersAvailable(trans, req, resp, reset);
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::nsConnectionHandle::ResumeSend()
|
|
{
|
|
return mConn->ResumeSend();
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::nsConnectionHandle::ResumeRecv()
|
|
{
|
|
return mConn->ResumeRecv();
|
|
}
|
|
|
|
void
|
|
nsHttpConnectionMgr::nsConnectionHandle::CloseTransaction(nsAHttpTransaction *trans, nsresult reason)
|
|
{
|
|
mConn->CloseTransaction(trans, reason);
|
|
}
|
|
|
|
void
|
|
nsHttpConnectionMgr::nsConnectionHandle::GetConnectionInfo(nsHttpConnectionInfo **result)
|
|
{
|
|
mConn->GetConnectionInfo(result);
|
|
}
|
|
|
|
void
|
|
nsHttpConnectionMgr::nsConnectionHandle::GetSecurityInfo(nsISupports **result)
|
|
{
|
|
mConn->GetSecurityInfo(result);
|
|
}
|
|
|
|
PRBool
|
|
nsHttpConnectionMgr::nsConnectionHandle::IsPersistent()
|
|
{
|
|
return mConn->IsPersistent();
|
|
}
|
|
|
|
PRBool
|
|
nsHttpConnectionMgr::nsConnectionHandle::IsReused()
|
|
{
|
|
return mConn->IsReused();
|
|
}
|
|
|
|
nsresult
|
|
nsHttpConnectionMgr::nsConnectionHandle::PushBack(const char *buf, PRUint32 bufLen)
|
|
{
|
|
return mConn->PushBack(buf, bufLen);
|
|
}
|