зеркало из https://github.com/mozilla/pjs.git
work on nntp connection cache,not turned on yet r=sspitzer 13506
This commit is contained in:
Родитель
9e5e574372
Коммит
a3ebd05505
|
@ -27,6 +27,7 @@ interface nsIURI;
|
|||
interface nsINntpUrl;
|
||||
interface nsISupportsArray;
|
||||
interface nsIMsgFolder;
|
||||
interface nsIMsgWindow;
|
||||
|
||||
[scriptable, uuid(30106238-0991-11d4-a565-0060b0fc04b7)]
|
||||
interface nsINNTPProtocol : nsISupports {
|
||||
|
@ -37,15 +38,11 @@ interface nsINNTPProtocol : nsISupports {
|
|||
/////////////////////////////////////////////////////////////////////////
|
||||
void IsBusy(out boolean aIsConnectionBusy);
|
||||
|
||||
// Protocol instance examines the url, looking at the host name,
|
||||
// user name and folder the action would be on in order to figure out
|
||||
// if it can process this url. I decided to push the semantics about
|
||||
// whether a connection can handle a url down into the connection level
|
||||
// instead of in the connection cache.
|
||||
void CanHandleUrl(in nsINntpUrl aNntpUrl, out boolean aCanRunUrl,
|
||||
out boolean hasToWait);
|
||||
void LoadNewsUrl(in nsIURI aUri, in nsISupports aConsumer);
|
||||
void Initialize(in nsIURI aURL, in nsIMsgWindow aMsgWindow);
|
||||
|
||||
// Get last active time stamp
|
||||
void GetLastActiveTimeStamp(out PRTime aTimeStamp);
|
||||
|
||||
|
||||
void CloseConnection();
|
||||
};
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
#include "nsIFileSpec.idl"
|
||||
|
||||
interface nsIMsgNewsFolder;
|
||||
interface nsINNTPProtocol;
|
||||
interface nsIURI;
|
||||
interface nsIMsgWindow;
|
||||
|
||||
[scriptable, uuid(21ea0654-f773-11d2-8aec-004005263078)]
|
||||
interface nsINntpIncomingServer : nsISupports {
|
||||
|
@ -49,6 +52,7 @@ interface nsINntpIncomingServer : nsISupports {
|
|||
|
||||
attribute boolean newsrcHasChanged;
|
||||
|
||||
attribute long maximumConnectionsNumber;
|
||||
/* used when populating the subscribe dialog */
|
||||
void addNewNewsgroup(in string name, in string state, in string count);
|
||||
void addSubscribedNewsgroups();
|
||||
|
@ -57,4 +61,10 @@ interface nsINntpIncomingServer : nsISupports {
|
|||
readonly attribute nsISupports firstGroupNeedingCounts;
|
||||
|
||||
void displaySubscribedGroup(in nsIMsgNewsFolder msgFolder, in long firstMessage, in long lastMessage, in long totalMessages);
|
||||
|
||||
|
||||
void GetNntpConnection(in nsIURI url, in nsIMsgWindow window,
|
||||
out nsINNTPProtocol aNntpConnection);
|
||||
void RemoveConnection(in nsINNTPProtocol aNntpConnection);
|
||||
|
||||
};
|
||||
|
|
|
@ -443,6 +443,13 @@ nsDummyBufferStream::QueryInterface(REFNSIID aIID, void** result)
|
|||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsNNTPProtocol, nsMsgProtocol)
|
||||
NS_IMPL_RELEASE_INHERITED(nsNNTPProtocol, nsMsgProtocol)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsNNTPProtocol)
|
||||
NS_INTERFACE_MAP_ENTRY(nsINNTPProtocol)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsMsgProtocol)
|
||||
|
||||
nsNNTPProtocol::nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow)
|
||||
: nsMsgProtocol(aURL)
|
||||
{
|
||||
|
@ -463,18 +470,20 @@ nsNNTPProtocol::nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow)
|
|||
m_commandSpecificData = nsnull;
|
||||
m_searchData = nsnull;
|
||||
|
||||
if (aMsgWindow) {
|
||||
if (aMsgWindow)
|
||||
m_msgWindow = aMsgWindow;
|
||||
}
|
||||
|
||||
m_runningURL = null_nsCOMPtr();
|
||||
|
||||
m_connectionBusy = PR_FALSE;
|
||||
m_fromCache = PR_FALSE;
|
||||
LL_I2L(m_lastActiveTimeStamp, 0);
|
||||
}
|
||||
|
||||
nsNNTPProtocol::~nsNNTPProtocol()
|
||||
{
|
||||
if (m_nntpServer) {
|
||||
m_nntpServer->WriteNewsrcFile();
|
||||
m_nntpServer->RemoveConnection(this);
|
||||
}
|
||||
PR_FREEIF(m_currentGroup);
|
||||
if (m_lineStreamBuffer) {
|
||||
|
@ -482,12 +491,16 @@ nsNNTPProtocol::~nsNNTPProtocol()
|
|||
}
|
||||
}
|
||||
|
||||
nsresult nsNNTPProtocol::Initialize(void)
|
||||
NS_IMETHODIMP nsNNTPProtocol::Initialize(nsIURI * aURL, nsIMsgWindow *aMsgWindow)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
net_NewsChunkSize = DEFAULT_NEWS_CHUNK_SIZE;
|
||||
PRBool isSecure = PR_FALSE;
|
||||
|
||||
if (aMsgWindow)
|
||||
m_msgWindow = aMsgWindow;
|
||||
nsMsgProtocol::InitFromURI(aURL);
|
||||
|
||||
rv = m_url->GetHost(getter_Copies(m_hostName));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = m_url->GetPreHost(getter_Copies(m_userName));
|
||||
|
@ -541,6 +554,7 @@ nsresult nsNNTPProtocol::Initialize(void)
|
|||
// query the URL for a nsINNTPUrl
|
||||
|
||||
m_runningURL = do_QueryInterface(m_url);
|
||||
m_connectionBusy = PR_TRUE;
|
||||
if (NS_SUCCEEDED(rv) && m_runningURL)
|
||||
{
|
||||
// okay, now fill in our event sinks...Note that each getter ref counts before
|
||||
|
@ -555,6 +569,8 @@ nsresult nsNNTPProtocol::Initialize(void)
|
|||
return rv;
|
||||
}
|
||||
|
||||
if (!m_socketIsOpen)
|
||||
{
|
||||
// call base class to set up the transport
|
||||
if (isSecure) {
|
||||
rv = OpenNetworkSocket(m_url, "ssl");
|
||||
|
@ -562,7 +578,7 @@ nsresult nsNNTPProtocol::Initialize(void)
|
|||
else {
|
||||
rv = OpenNetworkSocket(m_url, nsnull);
|
||||
}
|
||||
|
||||
}
|
||||
m_dataBuf = (char *) PR_Malloc(sizeof(char) * OUTPUT_BUFFER_SIZE);
|
||||
m_dataBufSize = OUTPUT_BUFFER_SIZE;
|
||||
|
||||
|
@ -625,6 +641,27 @@ nsNNTPProtocol::InitializeNewsFolderFromUri(const char *uri)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void IsBusy (out boolean aIsConnectionBusy); */
|
||||
NS_IMETHODIMP nsNNTPProtocol::IsBusy(PRBool *aIsConnectionBusy)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aIsConnectionBusy);
|
||||
*aIsConnectionBusy = m_connectionBusy;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void GetLastActiveTimeStamp (out PRTime aTimeStamp); */
|
||||
NS_IMETHODIMP nsNNTPProtocol::GetLastActiveTimeStamp(PRTime *aTimeStamp)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTimeStamp);
|
||||
*aTimeStamp = m_lastActiveTimeStamp;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNNTPProtocol::LoadNewsUrl(nsIURI * aURL, nsISupports * aConsumer)
|
||||
{
|
||||
return LoadUrl(aURL, aConsumer);
|
||||
}
|
||||
|
||||
|
||||
nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer)
|
||||
{
|
||||
|
@ -637,6 +674,14 @@ nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer)
|
|||
nsCOMPtr <nsINNTPNewsgroupPost> message;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// if this connection comes from the cache, we need to initialize the
|
||||
// load group here, by generating the start request notification.
|
||||
if (m_fromCache)
|
||||
{
|
||||
if (m_channelListener)
|
||||
rv = m_channelListener->OnStartRequest(this, m_channelContext);
|
||||
}
|
||||
|
||||
m_articleNumber = -1;
|
||||
rv = aURL->GetHost(getter_Copies(m_hostName));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -645,6 +690,7 @@ nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer)
|
|||
|
||||
m_runningURL = do_QueryInterface(aURL, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
m_connectionBusy = PR_TRUE;
|
||||
m_runningURL->GetNewsAction(&m_newsAction);
|
||||
|
||||
// okay, now fill in our event sinks...Note that each getter ref counts before
|
||||
|
@ -4929,10 +4975,20 @@ nsresult nsNNTPProtocol::ProcessProtocolState(nsIURI * url, nsIInputStream * inp
|
|||
// cache so we aren't creating new connections to process each request...
|
||||
// but until that time, we always want to properly shutdown the connection
|
||||
|
||||
|
||||
m_connectionBusy = PR_FALSE;
|
||||
#ifdef DEBUG_bienvenu
|
||||
#define USE_CONN_CACHE
|
||||
#endif
|
||||
#ifdef USE_CONN_CACHE
|
||||
mailnewsurl->SetUrlState(PR_FALSE, NS_OK);
|
||||
m_lastActiveTimeStamp = PR_Now(); // remmeber when we last used this connection.
|
||||
return CleanupAfterRunningUrl();
|
||||
#else
|
||||
SendData(mailnewsurl, NNTP_CMD_QUIT); // this will cause OnStopRequest get called, which will call CloseSocket()
|
||||
m_nextState = NEWS_FINISHED; // so we don't spin in the free state
|
||||
return NS_OK;
|
||||
break;
|
||||
#endif
|
||||
case NEWS_FINISHED:
|
||||
return NS_OK;
|
||||
break;
|
||||
|
@ -4954,7 +5010,13 @@ nsresult nsNNTPProtocol::ProcessProtocolState(nsIURI * url, nsIInputStream * inp
|
|||
return NS_OK; /* keep going */
|
||||
}
|
||||
|
||||
nsresult nsNNTPProtocol::CloseSocket()
|
||||
NS_IMETHODIMP nsNNTPProtocol::CloseConnection()
|
||||
{
|
||||
SendData(nsnull, NNTP_CMD_QUIT); // this will cause OnStopRequest get called, which will call CloseSocket()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNNTPProtocol::CleanupAfterRunningUrl()
|
||||
{
|
||||
/* do we need to know if we're parsing xover to call finish xover? */
|
||||
/* yes, I think we do! Why did I think we should??? */
|
||||
|
@ -4963,6 +5025,14 @@ nsresult nsNNTPProtocol::CloseSocket()
|
|||
something. So, tell libmsg there was an abnormal
|
||||
exit so that it can free its data. */
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (m_channelListener)
|
||||
rv = m_channelListener->OnStopRequest(this, m_channelContext, NS_OK, nsnull);
|
||||
|
||||
if (m_loadGroup)
|
||||
m_loadGroup->RemoveChannel(NS_STATIC_CAST(nsIChannel *, this), nsnull, NS_OK, nsnull);
|
||||
|
||||
if (m_newsgroupList)
|
||||
{
|
||||
int status;
|
||||
|
@ -4977,10 +5047,6 @@ nsresult nsNNTPProtocol::CloseSocket()
|
|||
we be releasing it here? */
|
||||
/* NS_RELEASE(m_newsgroup->GetNewsgroupList()); */
|
||||
}
|
||||
#ifdef UNREADY_CODE
|
||||
if (cd->control_con)
|
||||
cd->control_con->last_used_time = PR_Now();
|
||||
#endif
|
||||
|
||||
PR_FREEIF(m_path);
|
||||
PR_FREEIF(m_responseText);
|
||||
|
@ -4996,7 +5062,13 @@ nsresult nsNNTPProtocol::CloseSocket()
|
|||
m_cancelID = nsnull;
|
||||
|
||||
m_runningURL = null_nsCOMPtr();
|
||||
m_connectionBusy = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNNTPProtocol::CloseSocket()
|
||||
{
|
||||
CleanupAfterRunningUrl(); // is this needed?
|
||||
return nsMsgProtocol::CloseSocket();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1998-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
|
@ -30,6 +30,7 @@
|
|||
#include "nsIBufferOutputStream.h"
|
||||
#include "nsINntpUrl.h"
|
||||
#include "nsINntpIncomingServer.h"
|
||||
#include "nsINNTPProtocol.h"
|
||||
|
||||
#include "nsIWebShell.h" // mscott - this dependency should only be temporary!
|
||||
|
||||
|
@ -144,20 +145,16 @@ NEWS_FREE,
|
|||
NEWS_FINISHED
|
||||
} StatesEnum;
|
||||
|
||||
class nsNNTPProtocol : public nsMsgProtocol
|
||||
class nsNNTPProtocol : public nsINNTPProtocol, public nsMsgProtocol
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSINNTPPROTOCOL
|
||||
// Creating a protocol instance requires the URL
|
||||
// need to call Initialize after we do a new of nsNNTPProtocol
|
||||
nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow);
|
||||
virtual ~nsNNTPProtocol();
|
||||
|
||||
// initialization function given a news url
|
||||
NS_IMETHOD Initialize(void);
|
||||
|
||||
// aConsumer is typically a display stream you may want the results to be displayed into...
|
||||
virtual nsresult LoadUrl(nsIURI * aURL, nsISupports * aConsumer = nsnull);
|
||||
|
||||
// stop binding is a "notification" informing us that the stream associated with aURL is going away.
|
||||
NS_IMETHOD OnStopRequest(nsIChannel * aChannel, nsISupports * aCtxt, nsresult aStatus, const PRUnichar* aMsg);
|
||||
|
||||
|
@ -165,6 +162,8 @@ public:
|
|||
|
||||
NS_IMETHOD Cancel(nsresult status); // handle stop button
|
||||
|
||||
nsresult LoadUrl(nsIURI * aURL, nsISupports * aConsumer);
|
||||
|
||||
private:
|
||||
// over-rides from nsMsgProtocol
|
||||
virtual nsresult ProcessProtocolState(nsIURI * url, nsIInputStream * inputStream,
|
||||
|
@ -175,6 +174,8 @@ private:
|
|||
// and then calls the base class to transmit the data
|
||||
PRInt32 SendData(nsIURI * aURL, const char * dataBuffer);
|
||||
|
||||
nsresult CleanupAfterRunningUrl();
|
||||
|
||||
void ParseHeaderForCancel(char *buf);
|
||||
|
||||
static PRBool CheckIfAuthor(nsISupports *aElement, void *data);
|
||||
|
@ -198,6 +199,9 @@ private:
|
|||
|
||||
// the nsINntpURL that is currently running
|
||||
nsCOMPtr<nsINntpUrl> m_runningURL;
|
||||
PRBool m_connectionBusy;
|
||||
PRBool m_fromCache; // is this connection from the cache?
|
||||
PRTime m_lastActiveTimeStamp;
|
||||
nsNewsAction m_newsAction;
|
||||
|
||||
// Generic state information -- What state are we in? What state do we want to go to
|
||||
|
|
|
@ -31,10 +31,11 @@
|
|||
#include "nsFileStream.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsINntpService.h"
|
||||
|
||||
#include "nsINNTPProtocol.h"
|
||||
#include "nsIRDFService.h"
|
||||
#include "nsRDFCID.h"
|
||||
#include "nsMsgNewsCID.h"
|
||||
#include "nsNNTPProtocol.h"
|
||||
|
||||
#define NEW_NEWS_DIR_NAME "News"
|
||||
#define PREF_MAIL_NEWSRC_ROOT "mail.newsrc_root"
|
||||
|
@ -65,6 +66,7 @@ nsNntpIncomingServer::nsNntpIncomingServer()
|
|||
|
||||
mNewsrcHasChanged = PR_FALSE;
|
||||
mGroupsEnumerator = nsnull;
|
||||
NS_NewISupportsArray(getter_AddRefs(m_connectionCache));
|
||||
}
|
||||
|
||||
|
||||
|
@ -308,9 +310,163 @@ nsNntpIncomingServer::GetNewsrcHasChanged(PRBool *aNewsrcHasChanged)
|
|||
NS_IMETHODIMP
|
||||
nsNntpIncomingServer::CloseCachedConnections()
|
||||
{
|
||||
// iterate through the connection cache for a connection that can handle this url.
|
||||
PRUint32 cnt;
|
||||
nsCOMPtr<nsISupports> aSupport;
|
||||
nsCOMPtr<nsINNTPProtocol> connection;
|
||||
|
||||
if (m_connectionCache)
|
||||
{
|
||||
nsresult rv = m_connectionCache->Count(&cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
for (PRUint32 i = 0; i < cnt; i++)
|
||||
{
|
||||
aSupport = getter_AddRefs(m_connectionCache->ElementAt(i));
|
||||
connection = do_QueryInterface(aSupport);
|
||||
if (connection)
|
||||
rv = connection->CloseConnection();
|
||||
}
|
||||
}
|
||||
return WriteNewsrcFile();
|
||||
}
|
||||
|
||||
NS_IMPL_SERVERPREF_INT(nsNntpIncomingServer, MaximumConnectionsNumber,
|
||||
"max_cached_connections");
|
||||
|
||||
PRBool
|
||||
nsNntpIncomingServer::ConnectionTimeOut(nsINNTPProtocol* aConnection)
|
||||
{
|
||||
PRBool retVal = PR_FALSE;
|
||||
if (!aConnection) return retVal;
|
||||
nsresult rv;
|
||||
|
||||
PR_CEnterMonitor(this);
|
||||
|
||||
PRTime cacheTimeoutLimits;
|
||||
|
||||
LL_I2L(cacheTimeoutLimits, 170 * 1000000); // 170 seconds in microseconds
|
||||
PRTime lastActiveTimeStamp;
|
||||
rv = aConnection->GetLastActiveTimeStamp(&lastActiveTimeStamp);
|
||||
|
||||
PRTime elapsedTime;
|
||||
LL_SUB(elapsedTime, PR_Now(), lastActiveTimeStamp);
|
||||
PRTime t;
|
||||
LL_SUB(t, elapsedTime, cacheTimeoutLimits);
|
||||
if (LL_GE_ZERO(t))
|
||||
{
|
||||
nsCOMPtr<nsINNTPProtocol> aProtocol(do_QueryInterface(aConnection,
|
||||
&rv));
|
||||
if (NS_SUCCEEDED(rv) && aProtocol)
|
||||
{
|
||||
m_connectionCache->RemoveElement(aConnection);
|
||||
retVal = PR_TRUE;
|
||||
}
|
||||
}
|
||||
PR_CExitMonitor(this);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsNntpIncomingServer::CreateProtocolInstance(nsINNTPProtocol ** aNntpConnection, nsIURI *url,
|
||||
nsIMsgWindow *aMsgWindow)
|
||||
{
|
||||
// create a new connection and add it to the connection cache
|
||||
// we may need to flag the protocol connection as busy so we don't get
|
||||
// a race
|
||||
// condition where someone else goes through this code
|
||||
nsNNTPProtocol * protocolInstance = new nsNNTPProtocol(url, aMsgWindow);
|
||||
if (!protocolInstance)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
// nsresult rv = nsComponentManager::CreateInstance(kImapProtocolCID, nsnull,
|
||||
// NS_GET_IID(nsINntpProtocol),
|
||||
// (void **) &protocolInstance);
|
||||
nsresult rv = protocolInstance->QueryInterface(NS_GET_IID(nsINNTPProtocol), (void **) aNntpConnection);
|
||||
// take the protocol instance and add it to the connectionCache
|
||||
if (NS_SUCCEEDED(rv) && *aNntpConnection)
|
||||
m_connectionCache->AppendElement(*aNntpConnection);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNntpIncomingServer::GetNntpConnection(nsIURI * aUri, nsIMsgWindow *aMsgWindow,
|
||||
nsINNTPProtocol ** aNntpConnection)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsINNTPProtocol> connection;
|
||||
nsCOMPtr<nsINNTPProtocol> freeConnection;
|
||||
PRBool isBusy = PR_FALSE;
|
||||
|
||||
PR_CEnterMonitor(this);
|
||||
|
||||
PRInt32 maxConnections = 2; // default to be 2
|
||||
rv = GetMaximumConnectionsNumber(&maxConnections);
|
||||
if (NS_FAILED(rv) || maxConnections == 0)
|
||||
{
|
||||
maxConnections = 2;
|
||||
rv = SetMaximumConnectionsNumber(maxConnections);
|
||||
}
|
||||
else if (maxConnections < 1)
|
||||
{ // forced to use at least 1
|
||||
maxConnections = 1;
|
||||
rv = SetMaximumConnectionsNumber(maxConnections);
|
||||
}
|
||||
|
||||
*aNntpConnection = nsnull;
|
||||
// iterate through the connection cache for a connection that can handle this url.
|
||||
PRUint32 cnt;
|
||||
nsCOMPtr<nsISupports> aSupport;
|
||||
|
||||
rv = m_connectionCache->Count(&cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
for (PRUint32 i = 0; i < cnt && !isBusy; i++)
|
||||
{
|
||||
aSupport = getter_AddRefs(m_connectionCache->ElementAt(i));
|
||||
connection = do_QueryInterface(aSupport);
|
||||
if (connection)
|
||||
rv = connection->IsBusy(&isBusy);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
connection = null_nsCOMPtr();
|
||||
continue;
|
||||
}
|
||||
if (!freeConnection && !isBusy && connection)
|
||||
{
|
||||
freeConnection = connection;
|
||||
}
|
||||
}
|
||||
|
||||
if (ConnectionTimeOut(connection))
|
||||
connection = null_nsCOMPtr();
|
||||
if (ConnectionTimeOut(freeConnection))
|
||||
freeConnection = null_nsCOMPtr();
|
||||
|
||||
// if we got here and we have a connection, then we should return it!
|
||||
if (!isBusy && connection)
|
||||
{
|
||||
*aNntpConnection = freeConnection;
|
||||
freeConnection->Initialize(aUri, aMsgWindow);
|
||||
NS_IF_ADDREF(*aNntpConnection);
|
||||
}
|
||||
else // have no queueing mechanism - just create the protocol instance.
|
||||
{
|
||||
rv = CreateProtocolInstance(aNntpConnection, aUri, aMsgWindow);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/* void RemoveConnection (in nsINNTPProtocol aNntpConnection); */
|
||||
NS_IMETHODIMP nsNntpIncomingServer::RemoveConnection(nsINNTPProtocol *aNntpConnection)
|
||||
{
|
||||
if (aNntpConnection)
|
||||
m_connectionCache->RemoveElement(aNntpConnection);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNntpIncomingServer::AddSubscribedNewsgroups()
|
||||
{
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
|
||||
#include "nsEnumeratorUtils.h"
|
||||
|
||||
class nsINntpUrl;
|
||||
class nsIMsgMailNewsUrl;
|
||||
|
||||
/* get some implementation from nsMsgIncomingServer */
|
||||
class nsNntpIncomingServer : public nsMsgIncomingServer,
|
||||
public nsINntpIncomingServer
|
||||
|
@ -51,6 +54,11 @@ public:
|
|||
NS_IMETHOD GetLocalStoreType(char * *type);
|
||||
NS_IMETHOD CloseCachedConnections();
|
||||
NS_IMETHOD PerformExpand();
|
||||
protected:
|
||||
nsresult CreateProtocolInstance(nsINNTPProtocol ** aNntpConnection, nsIURI *url,
|
||||
nsIMsgWindow *window);
|
||||
PRBool ConnectionTimeOut(nsINNTPProtocol* aNntpConnection);
|
||||
nsCOMPtr<nsISupportsArray> m_connectionCache;
|
||||
NS_IMETHOD PerformBiff();
|
||||
NS_IMETHOD GetServerRequiresPasswordForBiff(PRBool *_retval);
|
||||
|
||||
|
|
|
@ -774,10 +774,11 @@ nsresult nsNntpService::PostMessage(nsIFileSpec *fileToPost, const char *newsgro
|
|||
// almost there...now create a nntp protocol instance to run the url in...
|
||||
nsNNTPProtocol *nntpProtocol = nsnull;
|
||||
|
||||
// ### try to access cache - but can't find server yet...
|
||||
nntpProtocol = new nsNNTPProtocol(mailnewsurl, aMsgWindow);
|
||||
if (!nntpProtocol) return NS_ERROR_OUT_OF_MEMORY;;
|
||||
|
||||
rv = nntpProtocol->Initialize();
|
||||
rv = nntpProtocol->Initialize(mailnewsurl, aMsgWindow);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr <nsINNTPNewsgroupPost> post;
|
||||
|
@ -790,7 +791,7 @@ nsresult nsNntpService::PostMessage(nsIFileSpec *fileToPost, const char *newsgro
|
|||
rv = nntpUrl->SetMessageToPost(post);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = nntpProtocol->LoadUrl(mailnewsurl, /* aConsumer */ nsnull);
|
||||
rv = nntpProtocol->LoadNewsUrl(mailnewsurl, /* aConsumer */ nsnull);
|
||||
|
||||
if (_retval)
|
||||
nntpUrl->QueryInterface(NS_GET_IID(nsIURI), (void **) _retval);
|
||||
|
@ -842,21 +843,53 @@ nsresult nsNntpService::ConstructNntpUrl(const char * urlString, const char * ne
|
|||
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNntpService::GetProtocolForUri(nsIURI *aUri, nsIMsgWindow *aMsgWindow, nsINNTPProtocol **aProtocol)
|
||||
{
|
||||
nsXPIDLCString hostName;
|
||||
nsXPIDLCString userName;
|
||||
|
||||
nsresult rv = aUri->GetHost(getter_Copies(hostName));
|
||||
rv = aUri->GetPreHost(getter_Copies(userName));
|
||||
|
||||
NS_WITH_SERVICE(nsIMsgAccountManager, accountManager, NS_MSGACCOUNTMANAGER_PROGID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// find the incoming server
|
||||
nsCOMPtr<nsIMsgIncomingServer> server;
|
||||
nsCOMPtr<nsINntpIncomingServer> nntpServer;
|
||||
rv = accountManager->FindServer(userName,
|
||||
hostName,
|
||||
"nntp",
|
||||
getter_AddRefs(server));
|
||||
|
||||
if (NS_FAILED(rv) || !server)
|
||||
return rv;
|
||||
|
||||
nntpServer = do_QueryInterface(server, &rv);
|
||||
|
||||
if (!nntpServer || NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = nntpServer->GetNntpConnection(aUri, aMsgWindow, aProtocol);
|
||||
if (NS_FAILED(rv) || !*aProtocol)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return rv;
|
||||
}
|
||||
nsresult
|
||||
nsNntpService::RunNewsUrl(nsIURI * aUri, nsIMsgWindow *aMsgWindow, nsISupports * aConsumer)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// almost there...now create a nntp protocol instance to run the url in...
|
||||
nsNNTPProtocol *nntpProtocol = nsnull;
|
||||
nsCOMPtr <nsINNTPProtocol> nntpProtocol;
|
||||
rv = GetProtocolForUri(aUri, aMsgWindow, getter_AddRefs(nntpProtocol));
|
||||
|
||||
nntpProtocol = new nsNNTPProtocol(aUri, aMsgWindow);
|
||||
if (!nntpProtocol) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = nntpProtocol->Initialize();
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = nntpProtocol->Initialize(aUri, aMsgWindow);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = nntpProtocol->LoadUrl(aUri, aConsumer);
|
||||
rv = nntpProtocol->LoadNewsUrl(aUri, aConsumer);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1061,10 +1094,10 @@ NS_IMETHODIMP nsNntpService::NewURI(const char *aSpec, nsIURI *aBaseURI, nsIURI
|
|||
NS_IMETHODIMP nsNntpService::NewChannel(nsIURI *aURI, nsIChannel **_retval)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsNNTPProtocol *nntpProtocol = new nsNNTPProtocol(aURI, nsnull);
|
||||
if (!nntpProtocol) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = nntpProtocol->Initialize();
|
||||
nsCOMPtr <nsINNTPProtocol> nntpProtocol;
|
||||
rv = GetProtocolForUri(aURI, nsnull, getter_AddRefs(nntpProtocol));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = nntpProtocol->Initialize(aURI, nsnull);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return nntpProtocol->QueryInterface(NS_GET_IID(nsIChannel), (void **) _retval);
|
||||
|
|
|
@ -71,6 +71,7 @@ protected:
|
|||
|
||||
// a convience routine used to put together news urls.
|
||||
nsresult ConstructNntpUrl(const char * urlString, const char * newsgroupName, nsMsgKey key, nsIUrlListener *aUrlListener, nsIURI ** aUrl);
|
||||
nsresult GetProtocolForUri(nsIURI *aUri, nsIMsgWindow *aMsgWindow, nsINNTPProtocol **aProtocol);
|
||||
// a convience routine to run news urls
|
||||
nsresult RunNewsUrl (nsIURI * aUrl, nsIMsgWindow *aMsgWindow, nsISupports * aConsumer);
|
||||
static PRBool findNewsServerWithGroup(nsISupports *aElement, void *data);
|
||||
|
|
Загрузка…
Ссылка в новой задаче