зеркало из 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 nsINntpUrl;
|
||||||
interface nsISupportsArray;
|
interface nsISupportsArray;
|
||||||
interface nsIMsgFolder;
|
interface nsIMsgFolder;
|
||||||
|
interface nsIMsgWindow;
|
||||||
|
|
||||||
[scriptable, uuid(30106238-0991-11d4-a565-0060b0fc04b7)]
|
[scriptable, uuid(30106238-0991-11d4-a565-0060b0fc04b7)]
|
||||||
interface nsINNTPProtocol : nsISupports {
|
interface nsINNTPProtocol : nsISupports {
|
||||||
|
@ -37,15 +38,11 @@ interface nsINNTPProtocol : nsISupports {
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
void IsBusy(out boolean aIsConnectionBusy);
|
void IsBusy(out boolean aIsConnectionBusy);
|
||||||
|
|
||||||
// Protocol instance examines the url, looking at the host name,
|
void LoadNewsUrl(in nsIURI aUri, in nsISupports aConsumer);
|
||||||
// user name and folder the action would be on in order to figure out
|
void Initialize(in nsIURI aURL, in nsIMsgWindow aMsgWindow);
|
||||||
// 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);
|
|
||||||
// Get last active time stamp
|
// Get last active time stamp
|
||||||
void GetLastActiveTimeStamp(out PRTime aTimeStamp);
|
void GetLastActiveTimeStamp(out PRTime aTimeStamp);
|
||||||
|
|
||||||
|
void CloseConnection();
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
#include "nsIFileSpec.idl"
|
#include "nsIFileSpec.idl"
|
||||||
|
|
||||||
interface nsIMsgNewsFolder;
|
interface nsIMsgNewsFolder;
|
||||||
|
interface nsINNTPProtocol;
|
||||||
|
interface nsIURI;
|
||||||
|
interface nsIMsgWindow;
|
||||||
|
|
||||||
[scriptable, uuid(21ea0654-f773-11d2-8aec-004005263078)]
|
[scriptable, uuid(21ea0654-f773-11d2-8aec-004005263078)]
|
||||||
interface nsINntpIncomingServer : nsISupports {
|
interface nsINntpIncomingServer : nsISupports {
|
||||||
|
@ -49,6 +52,7 @@ interface nsINntpIncomingServer : nsISupports {
|
||||||
|
|
||||||
attribute boolean newsrcHasChanged;
|
attribute boolean newsrcHasChanged;
|
||||||
|
|
||||||
|
attribute long maximumConnectionsNumber;
|
||||||
/* used when populating the subscribe dialog */
|
/* used when populating the subscribe dialog */
|
||||||
void addNewNewsgroup(in string name, in string state, in string count);
|
void addNewNewsgroup(in string name, in string state, in string count);
|
||||||
void addSubscribedNewsgroups();
|
void addSubscribedNewsgroups();
|
||||||
|
@ -57,4 +61,10 @@ interface nsINntpIncomingServer : nsISupports {
|
||||||
readonly attribute nsISupports firstGroupNeedingCounts;
|
readonly attribute nsISupports firstGroupNeedingCounts;
|
||||||
|
|
||||||
void displaySubscribedGroup(in nsIMsgNewsFolder msgFolder, in long firstMessage, in long lastMessage, in long totalMessages);
|
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;
|
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)
|
nsNNTPProtocol::nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow)
|
||||||
: nsMsgProtocol(aURL)
|
: nsMsgProtocol(aURL)
|
||||||
{
|
{
|
||||||
|
@ -463,18 +470,20 @@ nsNNTPProtocol::nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow)
|
||||||
m_commandSpecificData = nsnull;
|
m_commandSpecificData = nsnull;
|
||||||
m_searchData = nsnull;
|
m_searchData = nsnull;
|
||||||
|
|
||||||
if (aMsgWindow) {
|
if (aMsgWindow)
|
||||||
m_msgWindow = aMsgWindow;
|
m_msgWindow = aMsgWindow;
|
||||||
}
|
|
||||||
|
|
||||||
m_runningURL = null_nsCOMPtr();
|
m_runningURL = null_nsCOMPtr();
|
||||||
|
m_connectionBusy = PR_FALSE;
|
||||||
|
m_fromCache = PR_FALSE;
|
||||||
|
LL_I2L(m_lastActiveTimeStamp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsNNTPProtocol::~nsNNTPProtocol()
|
nsNNTPProtocol::~nsNNTPProtocol()
|
||||||
{
|
{
|
||||||
if (m_nntpServer) {
|
if (m_nntpServer) {
|
||||||
m_nntpServer->WriteNewsrcFile();
|
m_nntpServer->WriteNewsrcFile();
|
||||||
|
m_nntpServer->RemoveConnection(this);
|
||||||
}
|
}
|
||||||
PR_FREEIF(m_currentGroup);
|
PR_FREEIF(m_currentGroup);
|
||||||
if (m_lineStreamBuffer) {
|
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;
|
nsresult rv = NS_OK;
|
||||||
net_NewsChunkSize = DEFAULT_NEWS_CHUNK_SIZE;
|
net_NewsChunkSize = DEFAULT_NEWS_CHUNK_SIZE;
|
||||||
PRBool isSecure = PR_FALSE;
|
PRBool isSecure = PR_FALSE;
|
||||||
|
|
||||||
|
if (aMsgWindow)
|
||||||
|
m_msgWindow = aMsgWindow;
|
||||||
|
nsMsgProtocol::InitFromURI(aURL);
|
||||||
|
|
||||||
rv = m_url->GetHost(getter_Copies(m_hostName));
|
rv = m_url->GetHost(getter_Copies(m_hostName));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
rv = m_url->GetPreHost(getter_Copies(m_userName));
|
rv = m_url->GetPreHost(getter_Copies(m_userName));
|
||||||
|
@ -541,6 +554,7 @@ nsresult nsNNTPProtocol::Initialize(void)
|
||||||
// query the URL for a nsINNTPUrl
|
// query the URL for a nsINNTPUrl
|
||||||
|
|
||||||
m_runningURL = do_QueryInterface(m_url);
|
m_runningURL = do_QueryInterface(m_url);
|
||||||
|
m_connectionBusy = PR_TRUE;
|
||||||
if (NS_SUCCEEDED(rv) && m_runningURL)
|
if (NS_SUCCEEDED(rv) && m_runningURL)
|
||||||
{
|
{
|
||||||
// okay, now fill in our event sinks...Note that each getter ref counts before
|
// okay, now fill in our event sinks...Note that each getter ref counts before
|
||||||
|
@ -551,25 +565,27 @@ nsresult nsNNTPProtocol::Initialize(void)
|
||||||
m_runningURL->GetNewsgroup(getter_AddRefs(m_newsgroup));
|
m_runningURL->GetNewsgroup(getter_AddRefs(m_newsgroup));
|
||||||
m_runningURL->GetOfflineNewsState(getter_AddRefs(m_offlineNewsState));
|
m_runningURL->GetOfflineNewsState(getter_AddRefs(m_offlineNewsState));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// call base class to set up the transport
|
if (!m_socketIsOpen)
|
||||||
|
{
|
||||||
|
// call base class to set up the transport
|
||||||
if (isSecure) {
|
if (isSecure) {
|
||||||
rv = OpenNetworkSocket(m_url, "ssl");
|
rv = OpenNetworkSocket(m_url, "ssl");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rv = OpenNetworkSocket(m_url, nsnull);
|
rv = OpenNetworkSocket(m_url, nsnull);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
m_dataBuf = (char *) PR_Malloc(sizeof(char) * OUTPUT_BUFFER_SIZE);
|
m_dataBuf = (char *) PR_Malloc(sizeof(char) * OUTPUT_BUFFER_SIZE);
|
||||||
m_dataBufSize = OUTPUT_BUFFER_SIZE;
|
m_dataBufSize = OUTPUT_BUFFER_SIZE;
|
||||||
|
|
||||||
m_lineStreamBuffer = new nsMsgLineStreamBuffer(OUTPUT_BUFFER_SIZE, CRLF, PR_TRUE /* create new lines */);
|
m_lineStreamBuffer = new nsMsgLineStreamBuffer(OUTPUT_BUFFER_SIZE, CRLF, PR_TRUE /* create new lines */);
|
||||||
|
|
||||||
m_nextState = SEND_FIRST_NNTP_COMMAND;
|
m_nextState = SEND_FIRST_NNTP_COMMAND;
|
||||||
m_nextStateAfterResponse = NNTP_CONNECT;
|
m_nextStateAfterResponse = NNTP_CONNECT;
|
||||||
m_typeWanted = 0;
|
m_typeWanted = 0;
|
||||||
m_responseCode = 0;
|
m_responseCode = 0;
|
||||||
m_previousResponseCode = 0;
|
m_previousResponseCode = 0;
|
||||||
|
@ -625,6 +641,27 @@ nsNNTPProtocol::InitializeNewsFolderFromUri(const char *uri)
|
||||||
return NS_OK;
|
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)
|
nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer)
|
||||||
{
|
{
|
||||||
|
@ -637,6 +674,14 @@ nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer)
|
||||||
nsCOMPtr <nsINNTPNewsgroupPost> message;
|
nsCOMPtr <nsINNTPNewsgroupPost> message;
|
||||||
nsresult rv = NS_OK;
|
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;
|
m_articleNumber = -1;
|
||||||
rv = aURL->GetHost(getter_Copies(m_hostName));
|
rv = aURL->GetHost(getter_Copies(m_hostName));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
@ -645,6 +690,7 @@ nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer)
|
||||||
|
|
||||||
m_runningURL = do_QueryInterface(aURL, &rv);
|
m_runningURL = do_QueryInterface(aURL, &rv);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
m_connectionBusy = PR_TRUE;
|
||||||
m_runningURL->GetNewsAction(&m_newsAction);
|
m_runningURL->GetNewsAction(&m_newsAction);
|
||||||
|
|
||||||
// okay, now fill in our event sinks...Note that each getter ref counts before
|
// 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...
|
// cache so we aren't creating new connections to process each request...
|
||||||
// but until that time, we always want to properly shutdown the connection
|
// 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()
|
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
|
m_nextState = NEWS_FINISHED; // so we don't spin in the free state
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
break;
|
#endif
|
||||||
case NEWS_FINISHED:
|
case NEWS_FINISHED:
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
break;
|
break;
|
||||||
|
@ -4954,7 +5010,13 @@ nsresult nsNNTPProtocol::ProcessProtocolState(nsIURI * url, nsIInputStream * inp
|
||||||
return NS_OK; /* keep going */
|
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? */
|
/* 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??? */
|
/* yes, I think we do! Why did I think we should??? */
|
||||||
|
@ -4962,7 +5024,15 @@ nsresult nsNNTPProtocol::CloseSocket()
|
||||||
data, there was an error or we were interrupted or
|
data, there was an error or we were interrupted or
|
||||||
something. So, tell libmsg there was an abnormal
|
something. So, tell libmsg there was an abnormal
|
||||||
exit so that it can free its data. */
|
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)
|
if (m_newsgroupList)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
@ -4977,10 +5047,6 @@ nsresult nsNNTPProtocol::CloseSocket()
|
||||||
we be releasing it here? */
|
we be releasing it here? */
|
||||||
/* NS_RELEASE(m_newsgroup->GetNewsgroupList()); */
|
/* 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_path);
|
||||||
PR_FREEIF(m_responseText);
|
PR_FREEIF(m_responseText);
|
||||||
|
@ -4996,7 +5062,13 @@ nsresult nsNNTPProtocol::CloseSocket()
|
||||||
m_cancelID = nsnull;
|
m_cancelID = nsnull;
|
||||||
|
|
||||||
m_runningURL = null_nsCOMPtr();
|
m_runningURL = null_nsCOMPtr();
|
||||||
|
m_connectionBusy = PR_FALSE;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsNNTPProtocol::CloseSocket()
|
||||||
|
{
|
||||||
|
CleanupAfterRunningUrl(); // is this needed?
|
||||||
return nsMsgProtocol::CloseSocket();
|
return nsMsgProtocol::CloseSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
*
|
*
|
||||||
* The Initial Developer of the Original Code is Netscape
|
* The Initial Developer of the Original Code is Netscape
|
||||||
* Communications Corporation. Portions created by Netscape are
|
* Communications Corporation. Portions created by Netscape are
|
||||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
* Copyright (C) 1998-2000 Netscape Communications Corporation. All
|
||||||
* Rights Reserved.
|
* Rights Reserved.
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
#include "nsIBufferOutputStream.h"
|
#include "nsIBufferOutputStream.h"
|
||||||
#include "nsINntpUrl.h"
|
#include "nsINntpUrl.h"
|
||||||
#include "nsINntpIncomingServer.h"
|
#include "nsINntpIncomingServer.h"
|
||||||
|
#include "nsINNTPProtocol.h"
|
||||||
|
|
||||||
#include "nsIWebShell.h" // mscott - this dependency should only be temporary!
|
#include "nsIWebShell.h" // mscott - this dependency should only be temporary!
|
||||||
|
|
||||||
|
@ -144,20 +145,16 @@ NEWS_FREE,
|
||||||
NEWS_FINISHED
|
NEWS_FINISHED
|
||||||
} StatesEnum;
|
} StatesEnum;
|
||||||
|
|
||||||
class nsNNTPProtocol : public nsMsgProtocol
|
class nsNNTPProtocol : public nsINNTPProtocol, public nsMsgProtocol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_NSINNTPPROTOCOL
|
||||||
// Creating a protocol instance requires the URL
|
// Creating a protocol instance requires the URL
|
||||||
// need to call Initialize after we do a new of nsNNTPProtocol
|
// need to call Initialize after we do a new of nsNNTPProtocol
|
||||||
nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow);
|
nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow);
|
||||||
virtual ~nsNNTPProtocol();
|
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.
|
// 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);
|
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
|
NS_IMETHOD Cancel(nsresult status); // handle stop button
|
||||||
|
|
||||||
|
nsresult LoadUrl(nsIURI * aURL, nsISupports * aConsumer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// over-rides from nsMsgProtocol
|
// over-rides from nsMsgProtocol
|
||||||
virtual nsresult ProcessProtocolState(nsIURI * url, nsIInputStream * inputStream,
|
virtual nsresult ProcessProtocolState(nsIURI * url, nsIInputStream * inputStream,
|
||||||
|
@ -175,7 +174,9 @@ private:
|
||||||
// and then calls the base class to transmit the data
|
// and then calls the base class to transmit the data
|
||||||
PRInt32 SendData(nsIURI * aURL, const char * dataBuffer);
|
PRInt32 SendData(nsIURI * aURL, const char * dataBuffer);
|
||||||
|
|
||||||
void ParseHeaderForCancel(char *buf);
|
nsresult CleanupAfterRunningUrl();
|
||||||
|
|
||||||
|
void ParseHeaderForCancel(char *buf);
|
||||||
|
|
||||||
static PRBool CheckIfAuthor(nsISupports *aElement, void *data);
|
static PRBool CheckIfAuthor(nsISupports *aElement, void *data);
|
||||||
|
|
||||||
|
@ -198,6 +199,9 @@ private:
|
||||||
|
|
||||||
// the nsINntpURL that is currently running
|
// the nsINntpURL that is currently running
|
||||||
nsCOMPtr<nsINntpUrl> m_runningURL;
|
nsCOMPtr<nsINntpUrl> m_runningURL;
|
||||||
|
PRBool m_connectionBusy;
|
||||||
|
PRBool m_fromCache; // is this connection from the cache?
|
||||||
|
PRTime m_lastActiveTimeStamp;
|
||||||
nsNewsAction m_newsAction;
|
nsNewsAction m_newsAction;
|
||||||
|
|
||||||
// Generic state information -- What state are we in? What state do we want to go to
|
// Generic state information -- What state are we in? What state do we want to go to
|
||||||
|
|
|
@ -31,10 +31,11 @@
|
||||||
#include "nsFileStream.h"
|
#include "nsFileStream.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsINntpService.h"
|
#include "nsINntpService.h"
|
||||||
|
#include "nsINNTPProtocol.h"
|
||||||
#include "nsIRDFService.h"
|
#include "nsIRDFService.h"
|
||||||
#include "nsRDFCID.h"
|
#include "nsRDFCID.h"
|
||||||
#include "nsMsgNewsCID.h"
|
#include "nsMsgNewsCID.h"
|
||||||
|
#include "nsNNTPProtocol.h"
|
||||||
|
|
||||||
#define NEW_NEWS_DIR_NAME "News"
|
#define NEW_NEWS_DIR_NAME "News"
|
||||||
#define PREF_MAIL_NEWSRC_ROOT "mail.newsrc_root"
|
#define PREF_MAIL_NEWSRC_ROOT "mail.newsrc_root"
|
||||||
|
@ -61,10 +62,11 @@ NS_IMPL_ISUPPORTS_INHERITED(nsNntpIncomingServer,
|
||||||
|
|
||||||
nsNntpIncomingServer::nsNntpIncomingServer()
|
nsNntpIncomingServer::nsNntpIncomingServer()
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
|
|
||||||
mNewsrcHasChanged = PR_FALSE;
|
mNewsrcHasChanged = PR_FALSE;
|
||||||
mGroupsEnumerator = nsnull;
|
mGroupsEnumerator = nsnull;
|
||||||
|
NS_NewISupportsArray(getter_AddRefs(m_connectionCache));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -308,9 +310,163 @@ nsNntpIncomingServer::GetNewsrcHasChanged(PRBool *aNewsrcHasChanged)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsNntpIncomingServer::CloseCachedConnections()
|
nsNntpIncomingServer::CloseCachedConnections()
|
||||||
{
|
{
|
||||||
return WriteNewsrcFile();
|
// 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
|
NS_IMETHODIMP
|
||||||
nsNntpIncomingServer::AddSubscribedNewsgroups()
|
nsNntpIncomingServer::AddSubscribedNewsgroups()
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
|
|
||||||
#include "nsEnumeratorUtils.h"
|
#include "nsEnumeratorUtils.h"
|
||||||
|
|
||||||
|
class nsINntpUrl;
|
||||||
|
class nsIMsgMailNewsUrl;
|
||||||
|
|
||||||
/* get some implementation from nsMsgIncomingServer */
|
/* get some implementation from nsMsgIncomingServer */
|
||||||
class nsNntpIncomingServer : public nsMsgIncomingServer,
|
class nsNntpIncomingServer : public nsMsgIncomingServer,
|
||||||
public nsINntpIncomingServer
|
public nsINntpIncomingServer
|
||||||
|
@ -51,6 +54,11 @@ public:
|
||||||
NS_IMETHOD GetLocalStoreType(char * *type);
|
NS_IMETHOD GetLocalStoreType(char * *type);
|
||||||
NS_IMETHOD CloseCachedConnections();
|
NS_IMETHOD CloseCachedConnections();
|
||||||
NS_IMETHOD PerformExpand();
|
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 PerformBiff();
|
||||||
NS_IMETHOD GetServerRequiresPasswordForBiff(PRBool *_retval);
|
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...
|
// almost there...now create a nntp protocol instance to run the url in...
|
||||||
nsNNTPProtocol *nntpProtocol = nsnull;
|
nsNNTPProtocol *nntpProtocol = nsnull;
|
||||||
|
|
||||||
|
// ### try to access cache - but can't find server yet...
|
||||||
nntpProtocol = new nsNNTPProtocol(mailnewsurl, aMsgWindow);
|
nntpProtocol = new nsNNTPProtocol(mailnewsurl, aMsgWindow);
|
||||||
if (!nntpProtocol) return NS_ERROR_OUT_OF_MEMORY;;
|
if (!nntpProtocol) return NS_ERROR_OUT_OF_MEMORY;;
|
||||||
|
|
||||||
rv = nntpProtocol->Initialize();
|
rv = nntpProtocol->Initialize(mailnewsurl, aMsgWindow);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
nsCOMPtr <nsINNTPNewsgroupPost> post;
|
nsCOMPtr <nsINNTPNewsgroupPost> post;
|
||||||
|
@ -790,7 +791,7 @@ nsresult nsNntpService::PostMessage(nsIFileSpec *fileToPost, const char *newsgro
|
||||||
rv = nntpUrl->SetMessageToPost(post);
|
rv = nntpUrl->SetMessageToPost(post);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
rv = nntpProtocol->LoadUrl(mailnewsurl, /* aConsumer */ nsnull);
|
rv = nntpProtocol->LoadNewsUrl(mailnewsurl, /* aConsumer */ nsnull);
|
||||||
|
|
||||||
if (_retval)
|
if (_retval)
|
||||||
nntpUrl->QueryInterface(NS_GET_IID(nsIURI), (void **) _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
|
nsresult
|
||||||
nsNntpService::RunNewsUrl(nsIURI * aUri, nsIMsgWindow *aMsgWindow, nsISupports * aConsumer)
|
nsNntpService::RunNewsUrl(nsIURI * aUri, nsIMsgWindow *aMsgWindow, nsISupports * aConsumer)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
// almost there...now create a nntp protocol instance to run the url in...
|
// 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 (NS_SUCCEEDED(rv))
|
||||||
if (!nntpProtocol) return NS_ERROR_OUT_OF_MEMORY;
|
rv = nntpProtocol->Initialize(aUri, aMsgWindow);
|
||||||
|
|
||||||
rv = nntpProtocol->Initialize();
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
rv = nntpProtocol->LoadUrl(aUri, aConsumer);
|
rv = nntpProtocol->LoadNewsUrl(aUri, aConsumer);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1061,13 +1094,13 @@ NS_IMETHODIMP nsNntpService::NewURI(const char *aSpec, nsIURI *aBaseURI, nsIURI
|
||||||
NS_IMETHODIMP nsNntpService::NewChannel(nsIURI *aURI, nsIChannel **_retval)
|
NS_IMETHODIMP nsNntpService::NewChannel(nsIURI *aURI, nsIChannel **_retval)
|
||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
nsNNTPProtocol *nntpProtocol = new nsNNTPProtocol(aURI, nsnull);
|
nsCOMPtr <nsINNTPProtocol> nntpProtocol;
|
||||||
if (!nntpProtocol) return NS_ERROR_OUT_OF_MEMORY;
|
rv = GetProtocolForUri(aURI, nsnull, getter_AddRefs(nntpProtocol));
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
rv = nntpProtocol->Initialize();
|
rv = nntpProtocol->Initialize(aURI, nsnull);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
return nntpProtocol->QueryInterface(NS_GET_IID(nsIChannel), (void **) _retval);
|
return nntpProtocol->QueryInterface(NS_GET_IID(nsIChannel), (void **) _retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
|
@ -71,6 +71,7 @@ protected:
|
||||||
|
|
||||||
// a convience routine used to put together news urls.
|
// a convience routine used to put together news urls.
|
||||||
nsresult ConstructNntpUrl(const char * urlString, const char * newsgroupName, nsMsgKey key, nsIUrlListener *aUrlListener, nsIURI ** aUrl);
|
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
|
// a convience routine to run news urls
|
||||||
nsresult RunNewsUrl (nsIURI * aUrl, nsIMsgWindow *aMsgWindow, nsISupports * aConsumer);
|
nsresult RunNewsUrl (nsIURI * aUrl, nsIMsgWindow *aMsgWindow, nsISupports * aConsumer);
|
||||||
static PRBool findNewsServerWithGroup(nsISupports *aElement, void *data);
|
static PRBool findNewsServerWithGroup(nsISupports *aElement, void *data);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче