зеркало из https://github.com/mozilla/pjs.git
Bug #73819 --> hook imap and news up to the new memory cache.
r/sr=sspitzer,bienvenu
This commit is contained in:
Родитель
f77df37354
Коммит
c6ef67e961
|
@ -30,7 +30,7 @@ interface nsIMsgIncomingServer;
|
|||
interface nsIMsgWindow;
|
||||
interface nsILoadGroup;
|
||||
interface nsIMsgSearchSession;
|
||||
interface nsICachedNetData;
|
||||
interface nsICacheEntryDescriptor;
|
||||
|
||||
[scriptable, uuid(6CFFCEB0-CB8C-11d2-8065-006008128C4E)]
|
||||
interface nsIMsgMailNewsUrl : nsIURL {
|
||||
|
@ -72,7 +72,7 @@ interface nsIMsgMailNewsUrl : nsIURL {
|
|||
attribute boolean msgIsInLocalCache;
|
||||
attribute boolean suppressErrorMsgs; // used to avoid displaying biff error messages
|
||||
|
||||
attribute nsICachedNetData memCacheEntry;
|
||||
attribute nsICacheEntryDescriptor memCacheEntry;
|
||||
|
||||
const unsigned long eCopy = 0;
|
||||
const unsigned long eMove = 1;
|
||||
|
@ -98,8 +98,8 @@ interface nsIMsgMessageUrl : nsISupports {
|
|||
// used by imap, pop and nntp in order to implement save message to disk
|
||||
attribute nsIFileSpec messageFile;
|
||||
attribute boolean AddDummyEnvelope;
|
||||
attribute boolean canonicalLineEnding;
|
||||
attribute string originalSpec;
|
||||
attribute boolean canonicalLineEnding;
|
||||
attribute string originalSpec;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsINetDataCacheManager.h"
|
||||
#include "nsNetCID.h"
|
||||
|
||||
static NS_DEFINE_CID(kUrlListenerManagerCID, NS_URLLISTENERMANAGER_CID);
|
||||
|
@ -605,36 +604,17 @@ NS_IMETHODIMP nsMsgMailNewsUrl::SetFilePath(const char *i_DirFile)
|
|||
return m_baseURL->SetFilePath(i_DirFile);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgMailNewsUrl::SetMemCacheEntry(nsICachedNetData *memCacheEntry)
|
||||
NS_IMETHODIMP nsMsgMailNewsUrl::SetMemCacheEntry(nsICacheEntryDescriptor *memCacheEntry)
|
||||
{
|
||||
m_memCacheEntry = memCacheEntry;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgMailNewsUrl:: GetMemCacheEntry(nsICachedNetData **memCacheEntry)
|
||||
NS_IMETHODIMP nsMsgMailNewsUrl:: GetMemCacheEntry(nsICacheEntryDescriptor **memCacheEntry)
|
||||
{
|
||||
NS_ENSURE_ARG(memCacheEntry);
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!m_memCacheEntry)
|
||||
{
|
||||
nsCOMPtr<nsINetDataCacheManager> cacheManager = do_GetService(NS_NETWORK_CACHE_MANAGER_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && cacheManager)
|
||||
{
|
||||
// Retrieve an existing cache entry or create a new one if none exists for the
|
||||
// given URL.
|
||||
nsXPIDLCString urlCString;
|
||||
// eventually we are going to want to use the url spec - the query/ref part 'cause that doesn't
|
||||
// distinguish urls.......
|
||||
GetSpec(getter_Copies(urlCString));
|
||||
// for now, truncate of the query part so we don't duplicate urls in the cache...
|
||||
char * anchor = PL_strrchr(urlCString, '?');
|
||||
if (anchor)
|
||||
*anchor = '\0';
|
||||
rv = cacheManager->GetCachedNetData(urlCString, 0, 0, nsINetDataCacheManager::BYPASS_PERSISTENT_CACHE,
|
||||
getter_AddRefs(m_memCacheEntry));
|
||||
}
|
||||
}
|
||||
if (m_memCacheEntry)
|
||||
{
|
||||
*memCacheEntry = m_memCacheEntry;
|
||||
|
@ -645,6 +625,6 @@ NS_IMETHODIMP nsMsgMailNewsUrl:: GetMemCacheEntry(nsICachedNetData **memCacheEnt
|
|||
*memCacheEntry = nsnull;
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott MacGregor <mscott@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef nsMsgMailNewsUrl_h___
|
||||
|
@ -34,7 +35,8 @@
|
|||
#include "nsIURL.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIMsgSearchSession.h"
|
||||
#include "nsICachedNetData.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Okay, I found that all of the mail and news url interfaces needed to support
|
||||
// several common interfaces (in addition to those provided through nsIURI).
|
||||
|
@ -64,7 +66,7 @@ protected:
|
|||
nsCOMPtr<nsIMsgWindow> m_msgWindow;
|
||||
nsCOMPtr<nsILoadGroup> m_loadGroup;
|
||||
nsCOMPtr<nsIMsgSearchSession> m_searchSession;
|
||||
nsCOMPtr<nsICachedNetData> m_memCacheEntry;
|
||||
nsCOMPtr<nsICacheEntryDescriptor> m_memCacheEntry;
|
||||
char *m_errorMessage;
|
||||
PRBool m_runningUrl;
|
||||
PRBool m_updatingFolder;
|
||||
|
|
|
@ -27,13 +27,13 @@
|
|||
#include "nsIMailboxSpec.idl"
|
||||
|
||||
interface nsIMsgMailNewsUrl;
|
||||
interface nsIImapMockChannel;
|
||||
|
||||
typedef long ImapOnlineCopyState;
|
||||
|
||||
[scriptable, uuid(5f7484b0-68b4-11d3-a53e-0060b0fc04b7)]
|
||||
|
||||
interface ImapOnlineCopyStateType
|
||||
{
|
||||
interface ImapOnlineCopyStateType
|
||||
{
|
||||
const long kInProgress = 0;
|
||||
const long kSuccessfulCopy = 1;
|
||||
const long kSuccessfulMove = 2;
|
||||
|
@ -44,34 +44,32 @@ typedef long ImapOnlineCopyState;
|
|||
const long kInterruptedState = 7;
|
||||
const long kFailedCopy = 8;
|
||||
const long kFailedMove = 9;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
[scriptable, uuid(3b2dd7e0-e72c-11d2-ab7b-00805f8ac968)]
|
||||
|
||||
interface nsIImapMailFolderSink : nsISupports {
|
||||
attribute boolean folderNeedsACLListed;
|
||||
attribute boolean folderNeedsSubscribing;
|
||||
attribute boolean folderNeedsAdded;
|
||||
attribute boolean folderNeedsACLListed;
|
||||
attribute boolean folderNeedsSubscribing;
|
||||
attribute boolean folderNeedsAdded;
|
||||
attribute boolean folderVerifiedOnline;
|
||||
string GetOnlineDelimiter();
|
||||
// Tell mail master about the newly selected mailbox
|
||||
void UpdateImapMailboxInfo(in nsIImapProtocol aProtocol,
|
||||
string GetOnlineDelimiter();
|
||||
// Tell mail master about the newly selected mailbox
|
||||
void UpdateImapMailboxInfo(in nsIImapProtocol aProtocol,
|
||||
in nsIMailboxSpec aSpec);
|
||||
void UpdateImapMailboxStatus(in nsIImapProtocol aProtocol,
|
||||
in nsIMailboxSpec aSpec);
|
||||
void UpdateImapMailboxStatus(in nsIImapProtocol aProtocol,
|
||||
in nsIMailboxSpec aSpec);
|
||||
void ChildDiscoverySucceeded(in nsIImapProtocol aProtocol) ;
|
||||
void PromptUserForSubscribeUpdatePath(in nsIImapProtocol aProtocol,
|
||||
out boolean aBool) ;
|
||||
void SetupHeaderParseStream(in nsIImapProtocol aProtocol, in unsigned long size, in string content_type, in nsIMailboxSpec boxSpec);
|
||||
void ChildDiscoverySucceeded(in nsIImapProtocol aProtocol) ;
|
||||
void PromptUserForSubscribeUpdatePath(in nsIImapProtocol aProtocol,
|
||||
out boolean aBool) ;
|
||||
void SetupHeaderParseStream(in nsIImapProtocol aProtocol, in unsigned long size, in string content_type, in nsIMailboxSpec boxSpec);
|
||||
|
||||
void ParseAdoptedHeaderLine(in nsIImapProtocol aProtocol, in string messageLine, in unsigned long msgKey) ;
|
||||
|
||||
void NormalEndHeaderParseStream(in nsIImapProtocol aProtocol);
|
||||
|
||||
void AbortHeaderParseStream(in nsIImapProtocol aProtocol) ;
|
||||
|
||||
void OnlineCopyCompleted(in nsIImapProtocol aProtocol, in ImapOnlineCopyState aCopyState);
|
||||
void ParseAdoptedHeaderLine(in nsIImapProtocol aProtocol, in string messageLine, in unsigned long msgKey) ;
|
||||
|
||||
void NormalEndHeaderParseStream(in nsIImapProtocol aProtocol);
|
||||
|
||||
void AbortHeaderParseStream(in nsIImapProtocol aProtocol) ;
|
||||
|
||||
void OnlineCopyCompleted(in nsIImapProtocol aProtocol, in ImapOnlineCopyState aCopyState);
|
||||
void StartMessage(in nsIMsgMailNewsUrl aUrl);
|
||||
void EndMessage(in nsIMsgMailNewsUrl aUrl, in nsMsgKey uidOfMessage);
|
||||
|
||||
|
@ -82,4 +80,5 @@ interface nsIImapMailFolderSink : nsISupports {
|
|||
// are only released / destroyed from the UI thread.
|
||||
void PrepareToReleaseUrl(in nsIMsgMailNewsUrl aUrl);
|
||||
void ReleaseUrl();
|
||||
void CloseMockChannel(in nsIImapMockChannel aChannel);
|
||||
};
|
||||
|
|
|
@ -40,6 +40,7 @@ interface nsIEventQueue;
|
|||
interface nsIMsgFolder;
|
||||
interface nsIMsgWindow;
|
||||
interface nsIImapIncomingServer;
|
||||
interface nsICacheSession;
|
||||
|
||||
|
||||
[scriptable, uuid(18236127-FA1D-11d3-98BA-001083010E9B)]
|
||||
|
@ -224,4 +225,6 @@ interface nsIImapService : nsISupports
|
|||
|
||||
void playbackAllOfflineOperations(in nsIMsgWindow aMsgWindow, in nsIUrlListener aListener);
|
||||
void downloadAllOffineImapFolders(in nsIMsgWindow aMsgWindow, in nsIUrlListener aListener);
|
||||
|
||||
readonly attribute nsICacheSession cacheSession;
|
||||
};
|
||||
|
|
|
@ -65,9 +65,7 @@
|
|||
#include "nsIPrompt.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
// for the memory cache...
|
||||
#include "nsINetDataCacheManager.h"
|
||||
#include "nsINetDataCache.h"
|
||||
#include "nsICachedNetData.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
#include "nsImapUrl.h"
|
||||
#include "nsFileStream.h"
|
||||
|
||||
|
@ -475,10 +473,8 @@ nsImapIncomingServer::LoadNextQueuedUrl(PRBool *aResult)
|
|||
|
||||
while (cnt > 0 && !urlRun && keepGoing)
|
||||
{
|
||||
nsCOMPtr<nsISupports>
|
||||
aSupport(getter_AddRefs(m_urlQueue->ElementAt(0)));
|
||||
nsCOMPtr<nsIImapUrl>
|
||||
aImapUrl(do_QueryInterface(aSupport, &rv));
|
||||
nsCOMPtr<nsISupports> aSupport(getter_AddRefs(m_urlQueue->ElementAt(0)));
|
||||
nsCOMPtr<nsIImapUrl> aImapUrl(do_QueryInterface(aSupport, &rv));
|
||||
nsCOMPtr<nsIMsgMailNewsUrl> aMailNewsUrl(do_QueryInterface(aSupport, &rv));
|
||||
|
||||
if (aImapUrl)
|
||||
|
@ -487,9 +483,9 @@ nsImapIncomingServer::LoadNextQueuedUrl(PRBool *aResult)
|
|||
|
||||
if (NS_SUCCEEDED(aImapUrl->GetMockChannel(getter_AddRefs(mockChannel))) && mockChannel)
|
||||
{
|
||||
nsCOMPtr<nsIRequest> request = do_QueryInterface(mockChannel);
|
||||
nsCOMPtr<nsIRequest> request = do_QueryInterface(mockChannel);
|
||||
if (!request)
|
||||
return NS_ERROR_FAILURE;
|
||||
return NS_ERROR_FAILURE;
|
||||
request->GetStatus(&rv);
|
||||
if (!NS_SUCCEEDED(rv))
|
||||
{
|
||||
|
@ -500,10 +496,10 @@ nsImapIncomingServer::LoadNextQueuedUrl(PRBool *aResult)
|
|||
|
||||
if (aMailNewsUrl)
|
||||
{
|
||||
nsCOMPtr<nsICachedNetData> cacheEntry;
|
||||
nsCOMPtr<nsICacheEntryDescriptor> cacheEntry;
|
||||
res = aMailNewsUrl->GetMemCacheEntry(getter_AddRefs(cacheEntry));
|
||||
if (NS_SUCCEEDED(res) && cacheEntry)
|
||||
cacheEntry->Delete();
|
||||
cacheEntry->Doom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -511,14 +507,11 @@ nsImapIncomingServer::LoadNextQueuedUrl(PRBool *aResult)
|
|||
// between the place we set it and here.
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsISupports *aConsumer =
|
||||
(nsISupports*)m_urlConsumers.ElementAt(0);
|
||||
|
||||
nsISupports *aConsumer = (nsISupports*)m_urlConsumers.ElementAt(0);
|
||||
NS_IF_ADDREF(aConsumer);
|
||||
|
||||
nsCOMPtr <nsIImapProtocol> protocolInstance ;
|
||||
rv = CreateImapConnection(nsnull, aImapUrl,
|
||||
getter_AddRefs(protocolInstance));
|
||||
rv = CreateImapConnection(nsnull, aImapUrl, getter_AddRefs(protocolInstance));
|
||||
if (NS_SUCCEEDED(rv) && protocolInstance)
|
||||
{
|
||||
nsCOMPtr<nsIURI> url = do_QueryInterface(aImapUrl, &rv);
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#include "nsImapOfflineSync.h"
|
||||
#include "nsIMsgAccountManager.h"
|
||||
#include "nsQuickSort.h"
|
||||
#include "nsIImapMockChannel.h"
|
||||
|
||||
static NS_DEFINE_CID(kMsgAccountManagerCID, NS_MSGACCOUNTMANAGER_CID);
|
||||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
|
@ -3416,6 +3417,13 @@ nsImapMailFolder::ReleaseUrl()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImapMailFolder::CloseMockChannel(nsIImapMockChannel * aChannel)
|
||||
{
|
||||
aChannel->Close();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImapMailFolder::BeginMessageUpload()
|
||||
{
|
||||
|
|
|
@ -59,7 +59,8 @@
|
|||
#include "nsIDNSService.h"
|
||||
#include "nsIMsgHdr.h"
|
||||
// for the memory cache...
|
||||
#include "nsICachedNetData.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
#include "nsICacheSession.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
PRLogModuleInfo *IMAP;
|
||||
|
@ -90,6 +91,7 @@ static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CI
|
|||
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
|
||||
static NS_DEFINE_CID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);
|
||||
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
|
||||
static NS_DEFINE_CID(kStreamListenerTeeCID, NS_STREAMLISTENERTEE_CID);
|
||||
|
||||
#define OUTPUT_BUFFER_SIZE (4096*2) // mscott - i should be able to remove this if I can use nsMsgLineBuffer???
|
||||
|
||||
|
@ -637,7 +639,7 @@ nsresult nsImapProtocol::SetupWithUrl(nsIURI * aURL, nsISupports* aConsumer)
|
|||
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningUrl);
|
||||
if (mailnewsUrl)
|
||||
{
|
||||
nsCOMPtr<nsICachedNetData> cacheEntry;
|
||||
nsCOMPtr<nsICacheEntryDescriptor> cacheEntry;
|
||||
mailnewsUrl->GetMemCacheEntry(getter_AddRefs(cacheEntry));
|
||||
if (cacheEntry)
|
||||
cacheEntry->SetSecurityInfo(securityInfo);
|
||||
|
@ -654,7 +656,10 @@ void nsImapProtocol::ReleaseUrlState()
|
|||
{
|
||||
if (m_mockChannel)
|
||||
{
|
||||
m_mockChannel->Close();
|
||||
if (m_imapMailFolderSink)
|
||||
m_imapMailFolderSink->CloseMockChannel(m_mockChannel);
|
||||
else
|
||||
m_mockChannel->Close();
|
||||
m_mockChannel = null_nsCOMPtr();
|
||||
}
|
||||
if (m_runningUrl)
|
||||
|
@ -6790,6 +6795,7 @@ NS_INTERFACE_MAP_BEGIN(nsImapMockChannel)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIImapMockChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRequest)
|
||||
NS_INTERFACE_MAP_ENTRY(nsICacheListener)
|
||||
NS_INTERFACE_MAP_END_THREADSAFE
|
||||
|
||||
|
||||
|
@ -6807,8 +6813,10 @@ nsImapMockChannel::~nsImapMockChannel()
|
|||
|
||||
NS_IMETHODIMP nsImapMockChannel::Close()
|
||||
{
|
||||
m_channelListener = null_nsCOMPtr();
|
||||
return NS_OK;
|
||||
m_channelListener = null_nsCOMPtr();
|
||||
mCacheRequest = null_nsCOMPtr();
|
||||
m_url = null_nsCOMPtr();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMockChannel::GetProgressEventSink(nsIProgressEventSink ** aProgressEventSink)
|
||||
|
@ -6885,18 +6893,18 @@ NS_IMETHODIMP nsImapMockChannel::SetURI(nsIURI* aURI)
|
|||
if (!aURI)
|
||||
printf("Clearing URI\n");
|
||||
#endif
|
||||
if (m_url)
|
||||
if (m_url)
|
||||
{
|
||||
// if we don't have a progress event sink yet, get it from the url for now...
|
||||
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url);
|
||||
if (mailnewsUrl && !mProgressEventSink)
|
||||
{
|
||||
// if we don't have a progress event sink yet, get it from the url for now...
|
||||
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url);
|
||||
if (mailnewsUrl && !mProgressEventSink)
|
||||
{
|
||||
nsCOMPtr<nsIMsgStatusFeedback> statusFeedback;
|
||||
mailnewsUrl->GetStatusFeedback(getter_AddRefs(statusFeedback));
|
||||
mProgressEventSink = do_QueryInterface(statusFeedback);
|
||||
}
|
||||
nsCOMPtr<nsIMsgStatusFeedback> statusFeedback;
|
||||
mailnewsUrl->GetStatusFeedback(getter_AddRefs(statusFeedback));
|
||||
mProgressEventSink = do_QueryInterface(statusFeedback);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMockChannel::Open(nsIInputStream **_retval)
|
||||
|
@ -6905,70 +6913,100 @@ NS_IMETHODIMP nsImapMockChannel::Open(nsIInputStream **_retval)
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMockChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
|
||||
NS_IMETHODIMP
|
||||
nsImapMockChannel::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry, nsCacheAccessMode access, nsresult status)
|
||||
{
|
||||
nsCOMPtr<nsICachedNetData> cacheEntry;
|
||||
PRUint32 contentLength = 0;
|
||||
PRBool partialFlag = PR_FALSE;
|
||||
|
||||
// set the stream listener and then load the url
|
||||
m_channelContext = ctxt;
|
||||
m_channelListener = listener;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(m_url);
|
||||
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// look to see if this url should be added to the memory cache..
|
||||
PRBool useMemoryCache = PR_FALSE;
|
||||
mailnewsUrl->GetAddToMemoryCache(&useMemoryCache);
|
||||
rv = mailnewsUrl->GetMemCacheEntry(getter_AddRefs(cacheEntry));
|
||||
if (NS_SUCCEEDED(rv) && cacheEntry)
|
||||
if (NS_SUCCEEDED(status))
|
||||
{
|
||||
PRBool updateInProgress;
|
||||
cacheEntry->GetPartialFlag(&partialFlag);
|
||||
cacheEntry->GetUpdateInProgress(&updateInProgress);
|
||||
cacheEntry->GetStoredContentLength(&contentLength);
|
||||
// only try to update the cache entry if it isn't being used.
|
||||
// We always want to try to write to the cache entry if we can
|
||||
if (!updateInProgress)
|
||||
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url, &rv);
|
||||
mailnewsUrl->SetMemCacheEntry(entry);
|
||||
|
||||
// if we have write access then insert a "stream T" into the flow so data
|
||||
// gets written to both
|
||||
if (access & nsICache::ACCESS_WRITE && !(access & nsICache::ACCESS_READ))
|
||||
{
|
||||
// now we need to figure out if the entry is new / or partially unfinished...
|
||||
// this determines if we are going to USE the cache entry for reading the data
|
||||
// vs. if we need to write data into the cache entry...
|
||||
if (!contentLength || partialFlag)
|
||||
// we're going to fill up this cache entry,
|
||||
rv = cacheEntry->InterceptAsyncRead(listener, 0, getter_AddRefs(m_channelListener));
|
||||
entry->MarkValid();
|
||||
// use a stream listener Tee to force data into the cache and to our current channel listener...
|
||||
nsCOMPtr<nsIStreamListener> newListener;
|
||||
nsCOMPtr<nsIStreamListenerTee> tee = do_CreateInstance(kStreamListenerTeeCID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsITransport> transport;
|
||||
rv = entry->GetTransport(getter_AddRefs(transport));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIOutputStream> out;
|
||||
rv = transport->OpenOutputStream(0, PRUint32(-1), 0, getter_AddRefs(out));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = tee->Init(m_channelListener, out);
|
||||
m_channelListener = do_QueryInterface(tee);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
// now, determine if we should be loading from the cache or if we have
|
||||
// to really load the msg with a protocol connection...
|
||||
if (cacheEntry && contentLength > 0 && !partialFlag)
|
||||
{
|
||||
PRUint32 annotationLength = 0;
|
||||
char *annotation = nsnull;
|
||||
|
||||
rv = cacheEntry->GetAnnotation("ContentModified", &annotationLength, &annotation);
|
||||
if (NS_SUCCEEDED(rv) && annotationLength == nsCRT::strlen("Not Modified")
|
||||
&& annotation && !nsCRT::strncmp(annotation, "Not Modified", annotationLength))
|
||||
else
|
||||
{
|
||||
nsCOMPtr<nsIChannel> cacheChannel;
|
||||
rv = cacheEntry->NewChannel(m_loadGroup, getter_AddRefs(cacheChannel));
|
||||
rv = ReadFromMemCache(entry);
|
||||
if (access & nsICache::ACCESS_WRITE)
|
||||
entry->MarkValid();
|
||||
if (NS_SUCCEEDED(rv)) return NS_OK; // kick out if reading from the cache succeeded...
|
||||
}
|
||||
} // if we got a valid entry back from the cache...
|
||||
|
||||
// if reading from the cache failed or if we are writing into the cache, default to ReadFromImapConnection.
|
||||
return ReadFromImapConnection();
|
||||
}
|
||||
|
||||
nsresult nsImapMockChannel::OpenCacheEntry()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
// get the cache session from our imap service...
|
||||
nsCOMPtr<nsIImapService> imapService = do_GetService(kCImapService, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsICacheSession> cacheSession;
|
||||
rv = imapService->GetCacheSession(getter_AddRefs(cacheSession));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Open a cache entry with key = url
|
||||
nsXPIDLCString urlSpec;
|
||||
m_url->GetSpec(getter_Copies(urlSpec));
|
||||
// for now, truncate of the query part so we don't duplicate urls in the cache...
|
||||
char * anchor = PL_strrchr(urlSpec, '?');
|
||||
if (anchor)
|
||||
*anchor = '\0';
|
||||
return cacheSession->AsyncOpenCacheEntry(urlSpec, nsICache::ACCESS_READ_WRITE, this);
|
||||
}
|
||||
|
||||
nsresult nsImapMockChannel::ReadFromMemCache(nsICacheEntryDescriptor *entry)
|
||||
{
|
||||
NS_ENSURE_ARG(entry);
|
||||
|
||||
PRUint32 annotationLength = 0;
|
||||
nsXPIDLCString annotation;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
rv = entry->GetMetaDataElement("ContentModified", getter_Copies(annotation));
|
||||
if (NS_SUCCEEDED(rv) && (annotation.get()))
|
||||
{
|
||||
annotationLength = nsCRT::strlen(annotation.get());
|
||||
if (annotationLength == nsCRT::strlen("Not Modified") && !nsCRT::strncmp(annotation, "Not Modified", annotationLength))
|
||||
{
|
||||
nsCOMPtr<nsITransport> cacheTransport;
|
||||
rv = entry->GetTransport(getter_AddRefs(cacheTransport));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
// if we are going to read from the cache, then create a mock stream listener class and use it
|
||||
nsImapCacheStreamListener * cacheListener = new nsImapCacheStreamListener();
|
||||
NS_ADDREF(cacheListener);
|
||||
SetupPartExtractor(imapUrl, m_channelListener);
|
||||
cacheListener->Init(m_channelListener, NS_STATIC_CAST(nsIChannel *, this));
|
||||
rv = cacheChannel->AsyncOpen(cacheListener, m_channelContext);
|
||||
rv = cacheTransport->AsyncRead(cacheListener, m_channelContext, 0, PRUint32(-1), 0, getter_AddRefs(mCacheRequest));
|
||||
NS_RELEASE(cacheListener);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) // ONLY if we succeeded in actually starting the read should we return
|
||||
{
|
||||
nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(m_url);
|
||||
|
||||
// if the msg is unread, we should mark it read on the server. This lets
|
||||
// the code running this url we're loading from the cache, if it cares.
|
||||
imapUrl->SetMsgLoadingFromCache(PR_TRUE);
|
||||
|
@ -6979,15 +7017,58 @@ NS_IMETHODIMP nsImapMockChannel::AsyncOpen(nsIStreamListener *listener, nsISuppo
|
|||
|
||||
// be sure to set the cache entry's security info status as our security info status...
|
||||
nsCOMPtr<nsISupports> securityInfo;
|
||||
cacheEntry->GetSecurityInfo(getter_AddRefs(securityInfo));
|
||||
entry->GetSecurityInfo(getter_AddRefs(securityInfo));
|
||||
SetSecurityInfo(securityInfo);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
} // if AsyncRead succeeded.
|
||||
} // if get transport succeeded
|
||||
} // if contnet is not modified
|
||||
else
|
||||
rv = NS_ERROR_FAILURE; // content is modified so return an error so we try to open it the old fashioned way
|
||||
} // if we got an annotation
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// the requested url isn't in any of our caches so create an imap connection
|
||||
// to process it.
|
||||
nsresult nsImapMockChannel::ReadFromImapConnection()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(m_url);
|
||||
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url);
|
||||
|
||||
// okay, add the mock channel to the load group..
|
||||
imapUrl->AddChannelToLoadGroup();
|
||||
// loading the url consists of asking the server to add the url to it's imap event queue....
|
||||
nsCOMPtr<nsIMsgIncomingServer> server;
|
||||
rv = mailnewsUrl->GetServer(getter_AddRefs(server));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIImapIncomingServer> imapServer (do_QueryInterface(server, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Assume AsyncRead is always called from the UI thread.....
|
||||
nsCOMPtr<nsIEventQueue> queue;
|
||||
// get the Event Queue for this thread...
|
||||
nsCOMPtr<nsIEventQueueService> pEventQService (do_GetService(kEventQueueServiceCID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = imapServer->GetImapConnectionAndLoadUrl(queue, imapUrl, nsnull);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// for messages stored in our offline cache, we have special code to handle that...
|
||||
// If it's in the local cache, we return true and we can abort the download because
|
||||
// this method does the rest of the work.
|
||||
PRBool nsImapMockChannel::ReadFromLocalCache()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(m_url);
|
||||
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url, &rv);
|
||||
|
||||
// check if msg is in local cache.
|
||||
PRBool useLocalCache = PR_FALSE;
|
||||
mailnewsUrl->GetMsgIsInLocalCache(&useLocalCache);
|
||||
if (useLocalCache)
|
||||
|
@ -6998,7 +7079,7 @@ NS_IMETHODIMP nsImapMockChannel::AsyncOpen(nsIStreamListener *listener, nsISuppo
|
|||
rv = imapUrl->GetImapFolder(getter_AddRefs(folder));
|
||||
if (folder && NS_SUCCEEDED(rv))
|
||||
{
|
||||
// we want to create a file channel and read the msg from there.
|
||||
// we want to create a file channel and read the msg from there.
|
||||
nsCOMPtr<nsITransport> fileChannel;
|
||||
nsMsgKey msgKey = atoi(messageIdString);
|
||||
PRUint32 size, offset;
|
||||
|
@ -7007,17 +7088,15 @@ NS_IMETHODIMP nsImapMockChannel::AsyncOpen(nsIStreamListener *listener, nsISuppo
|
|||
// folder sink?) We also need to set the transfer offset to the message offset
|
||||
if (fileChannel && NS_SUCCEEDED(rv))
|
||||
{
|
||||
// dougt - This may break the ablity to "cancel" a read from offline mail reading.
|
||||
// fileChannel->SetLoadGroup(m_loadGroup);
|
||||
// dougt - This may break the ablity to "cancel" a read from offline mail reading.
|
||||
// fileChannel->SetLoadGroup(m_loadGroup);
|
||||
|
||||
// force the url to remove its reference on the mock channel...this is to solve
|
||||
// a nasty reference counting problem...
|
||||
imapUrl->SetMockChannel(nsnull);
|
||||
|
||||
// if we are going to read from the cache, then create a mock stream listener class and use it
|
||||
nsImapCacheStreamListener * cacheListener = new nsImapCacheStreamListener();
|
||||
NS_ADDREF(cacheListener);
|
||||
SetupPartExtractor(imapUrl, m_channelListener);
|
||||
cacheListener->Init(m_channelListener, NS_STATIC_CAST(nsIChannel *, this));
|
||||
nsCOMPtr<nsIRequest> request;
|
||||
rv = fileChannel->AsyncRead(cacheListener, m_channelContext, offset, size, 0, getter_AddRefs(request));
|
||||
|
@ -7028,37 +7107,40 @@ NS_IMETHODIMP nsImapMockChannel::AsyncOpen(nsIStreamListener *listener, nsISuppo
|
|||
// if the msg is unread, we should mark it read on the server. This lets
|
||||
// the code running this url we're loading from the cache, if it cares.
|
||||
imapUrl->SetMsgLoadingFromCache(PR_TRUE);
|
||||
return rv;
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // if we got an offline file transport
|
||||
} // if we got the folder for this url
|
||||
} // if use local cache
|
||||
|
||||
SetupPartExtractor(imapUrl, m_channelListener);
|
||||
|
||||
// okay, add the mock channel to the load group..
|
||||
imapUrl->AddChannelToLoadGroup();
|
||||
// loading the url consists of asking the server to add the url to it's imap event queue....
|
||||
nsCOMPtr<nsIMsgIncomingServer> server;
|
||||
rv = mailnewsUrl->GetServer(getter_AddRefs(server));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIImapIncomingServer> imapServer;
|
||||
imapServer = do_QueryInterface(server, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Assume AsyncRead is always called from the UI thread.....
|
||||
nsCOMPtr<nsIEventQueue> queue;
|
||||
// get the Event Queue for this thread...
|
||||
NS_WITH_SERVICE(nsIEventQueueService, pEventQService,kEventQueueServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = imapServer->GetImapConnectionAndLoadUrl(queue, imapUrl, nsnull);
|
||||
return rv;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult nsImapMockChannel::SetupPartExtractor(nsIImapUrl * aUrl, nsIStreamListener * aConsumer)
|
||||
NS_IMETHODIMP nsImapMockChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
// set the stream listener and then load the url
|
||||
m_channelContext = ctxt;
|
||||
m_channelListener = listener;
|
||||
nsCOMPtr<nsIImapUrl> imapUrl (do_QueryInterface(m_url));
|
||||
|
||||
SetupPartExtractorListener(imapUrl, m_channelListener);
|
||||
|
||||
if (ReadFromLocalCache())
|
||||
return NS_OK;
|
||||
|
||||
// okay, it's not in the local cache, now check the memory cache...
|
||||
|
||||
rv = OpenCacheEntry();
|
||||
|
||||
// if for some reason open cache entry failed then just default to opening an imap connection for the url
|
||||
if (NS_FAILED(rv))
|
||||
return ReadFromImapConnection();
|
||||
else
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsImapMockChannel::SetupPartExtractorListener(nsIImapUrl * aUrl, nsIStreamListener * aConsumer)
|
||||
{
|
||||
// if the url we are loading refers to a specific part then we need
|
||||
// libmime to extract that part from the message for us.
|
||||
|
@ -7071,7 +7153,7 @@ nsresult nsImapMockChannel::SetupPartExtractor(nsIImapUrl * aUrl, nsIStreamListe
|
|||
{
|
||||
nsCOMPtr<nsIStreamListener> newConsumer;
|
||||
converter->AsyncConvertData(NS_LITERAL_STRING("message/rfc822").get(), NS_LITERAL_STRING("*/*").get(),
|
||||
aConsumer, this, getter_AddRefs(newConsumer));
|
||||
aConsumer, NS_STATIC_CAST(nsIChannel *, this), getter_AddRefs(newConsumer));
|
||||
if (newConsumer)
|
||||
m_channelListener = newConsumer;
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "nsXPIDLString.h"
|
||||
#include "nsIMsgWindow.h"
|
||||
#include "nsIMsgLogonRedirector.h"
|
||||
#include "nsICacheListener.h"
|
||||
|
||||
class nsIMAPMessagePartIDArray;
|
||||
class nsIMsgIncomingServer;
|
||||
|
@ -578,7 +579,9 @@ private:
|
|||
//
|
||||
// Threading concern: This class lives entirely in the UI thread.
|
||||
|
||||
class nsImapMockChannel : public nsIImapMockChannel
|
||||
class nsICacheEntryDescriptor;
|
||||
|
||||
class nsImapMockChannel : public nsIImapMockChannel, public nsICacheListener
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -586,6 +589,7 @@ public:
|
|||
NS_DECL_NSIIMAPMOCKCHANNEL
|
||||
NS_DECL_NSICHANNEL
|
||||
NS_DECL_NSIREQUEST
|
||||
NS_DECL_NSICACHELISTENER
|
||||
|
||||
nsImapMockChannel();
|
||||
virtual ~nsImapMockChannel();
|
||||
|
@ -610,9 +614,17 @@ protected:
|
|||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsCOMPtr<nsISupports> mSecurityInfo;
|
||||
nsCOMPtr<nsIRequest> mCacheRequest; // the request associated with a read from the cache
|
||||
nsCString m_ContentType;
|
||||
|
||||
nsresult SetupPartExtractor(nsIImapUrl * aUrl, nsIStreamListener * aConsumer);
|
||||
// cache related helper methods
|
||||
nsresult OpenCacheEntry(); // makes a request to the cache service for a cache entry for a url
|
||||
PRBool ReadFromLocalCache(); // attempts to read the url out of our local (offline) cache....
|
||||
nsresult ReadFromImapConnection(); // creates a new imap connection to read the url
|
||||
nsresult ReadFromMemCache(nsICacheEntryDescriptor *entry); // attempts to read the url out of our memory cache
|
||||
|
||||
// we end up daisy chaining multiple nsIStreamListeners into the load process.
|
||||
nsresult SetupPartExtractorListener(nsIImapUrl * aUrl, nsIStreamListener * aConsumer);
|
||||
};
|
||||
|
||||
#endif // nsImapProtocol_h___
|
||||
|
|
|
@ -59,12 +59,16 @@
|
|||
#include "nsImapOfflineSync.h"
|
||||
#include "nsIMsgHdr.h"
|
||||
#include "nsMsgUtils.h"
|
||||
#include "nsICacheService.h"
|
||||
#include "nsNetCID.h"
|
||||
|
||||
#define PREF_MAIL_ROOT_IMAP "mail.root.imap"
|
||||
|
||||
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
|
||||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
static NS_DEFINE_CID(kImapUrlCID, NS_IMAPURL_CID);
|
||||
static NS_DEFINE_CID(kCacheServiceCID, NS_CACHESERVICE_CID);
|
||||
|
||||
|
||||
static const char *sequenceString = "SEQUENCE";
|
||||
|
@ -410,7 +414,7 @@ NS_IMETHODIMP nsImapService::FetchMimePart(nsIURI *aURI, const char *aMessageURI
|
|||
rv = nsParseImapMessageURI(aMessageURI, folderURI, &key, getter_Copies(mimePart));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCOMPtr<nsIImapMessageSink> imapMessageSink(do_QueryInterface(folder, &rv));
|
||||
nsCOMPtr<nsIImapMessageSink> imapMessageSink(do_QueryInterface(folder, &rv));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(aURI);
|
||||
|
@ -3321,3 +3325,21 @@ nsImapService::DownloadAllOffineImapFolders(nsIMsgWindow *aMsgWindow, nsIUrlList
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImapService::GetCacheSession(nsICacheSession **result)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!mCacheSession)
|
||||
{
|
||||
nsCOMPtr<nsICacheService> serv = do_GetService(kCacheServiceCID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = serv->CreateSession("IMAP-memory-only", nsICache::STORE_IN_MEMORY, nsICache::STREAM_BASED, getter_AddRefs(mCacheSession));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mCacheSession->SetDoomEntriesIfExpired(PR_FALSE);
|
||||
}
|
||||
|
||||
*result = mCacheSession;
|
||||
NS_IF_ADDREF(*result);
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "nsIProtocolHandler.h"
|
||||
#include "nsIMsgProtocolInfo.h"
|
||||
|
||||
#include "nsICacheSession.h"
|
||||
|
||||
class nsIImapHostSessionList;
|
||||
class nsCString;
|
||||
class nsIImapUrl;
|
||||
|
@ -110,6 +112,8 @@ protected:
|
|||
|
||||
PRBool mPrintingOperation; // Flag for printing operations
|
||||
|
||||
// handle to the cache session for imap.....
|
||||
nsCOMPtr<nsICacheSession> mCacheSession;
|
||||
};
|
||||
|
||||
#endif /* nsImapService_h___ */
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "nsXPIDLString.h"
|
||||
#include "nsAutoLock.h"
|
||||
#include "nsIMAPNamespace.h"
|
||||
#include "nsICachedNetData.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
// rdf stuff is needed to get the charset from the imap folder associated with the url.
|
||||
#include "nsIRDFService.h"
|
||||
#include "rdf.h"
|
||||
|
@ -1001,7 +1001,7 @@ NS_IMETHODIMP nsImapUrl::SetAllowContentChange(PRBool allowContentChange)
|
|||
NS_IMETHODIMP nsImapUrl::SetContentModified(nsImapContentModifiedType contentModified)
|
||||
{
|
||||
m_contentModified = contentModified;
|
||||
nsCOMPtr<nsICachedNetData> cacheEntry;
|
||||
nsCOMPtr<nsICacheEntryDescriptor> cacheEntry;
|
||||
nsresult res = GetMemCacheEntry(getter_AddRefs(cacheEntry));
|
||||
if (NS_SUCCEEDED(res) && cacheEntry)
|
||||
{
|
||||
|
@ -1021,7 +1021,7 @@ NS_IMETHODIMP nsImapUrl::SetContentModified(nsImapContentModifiedType contentMod
|
|||
contentModifiedAnnotation = "Force Content Not Modified";
|
||||
break;
|
||||
}
|
||||
cacheEntry->SetAnnotation("ContentModified", nsCRT::strlen(contentModifiedAnnotation), contentModifiedAnnotation);
|
||||
cacheEntry->SetMetaDataElement("ContentModified", contentModifiedAnnotation);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ interface nsISupportsArray;
|
|||
interface nsIFileSpec;
|
||||
interface nsIMsgWindow;
|
||||
interface nsIMsgFolder;
|
||||
interface nsICacheSession;
|
||||
|
||||
[scriptable, uuid(4C9F90E0-E19B-11d2-806E-006008128C4E)]
|
||||
interface nsINntpService : nsISupports {
|
||||
|
@ -55,5 +56,7 @@ interface nsINntpService : nsISupports {
|
|||
* can handle news_message:// and news://
|
||||
*/
|
||||
void decomposeNewsURI(in string uri, out nsIMsgFolder folder, out nsMsgKey key);
|
||||
};
|
||||
|
||||
// handle to the cache session used by news....
|
||||
readonly attribute nsICacheSession cacheSession;
|
||||
};
|
||||
|
|
|
@ -78,7 +78,10 @@
|
|||
#include "nsIDocShell.h"
|
||||
|
||||
// for the memory cache...
|
||||
#include "nsICachedNetData.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
#include "nsICacheSession.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsNetCID.h"
|
||||
|
||||
#include "nsIPref.h"
|
||||
|
||||
|
@ -160,6 +163,7 @@ static NS_DEFINE_CID(kCMsgMailSessionCID, NS_MSGMAILSESSION_CID);
|
|||
static NS_DEFINE_CID(kCMsgAccountManagerCID, NS_MSGACCOUNTMANAGER_CID);
|
||||
static NS_DEFINE_CID(kPrefServiceCID,NS_PREF_CID);
|
||||
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
|
||||
static NS_DEFINE_CID(kStreamListenerTeeCID, NS_STREAMLISTENERTEE_CID);
|
||||
|
||||
typedef struct _cancelInfoEntry {
|
||||
char *from;
|
||||
|
@ -414,8 +418,9 @@ 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_ENTRY(nsINNTPProtocol)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsICacheListener)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsMsgProtocol)
|
||||
|
||||
nsNNTPProtocol::nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow)
|
||||
|
@ -656,7 +661,7 @@ NS_IMETHODIMP nsNNTPProtocol::LoadNewsUrl(nsIURI * aURL, nsISupports * aConsumer
|
|||
nsCOMPtr<nsINntpUrl> newsUrl (do_QueryInterface(aURL));
|
||||
newsUrl->GetNewsAction(&m_newsAction);
|
||||
|
||||
SetupPartExtractor(m_channelListener);
|
||||
SetupPartExtractorListener(m_channelListener);
|
||||
return LoadUrl(aURL, aConsumer);
|
||||
}
|
||||
|
||||
|
@ -748,7 +753,7 @@ nsNntpCacheStreamListener::OnDataAvailable(nsIRequest *request, nsISupports * aC
|
|||
return mListener->OnDataAvailable(ourRequest, aCtxt, aInStream, aSourceOffset, aCount);
|
||||
}
|
||||
|
||||
nsresult nsNNTPProtocol::SetupPartExtractor(nsIStreamListener * aConsumer)
|
||||
nsresult nsNNTPProtocol::SetupPartExtractorListener(nsIStreamListener * aConsumer)
|
||||
{
|
||||
if (m_newsAction == nsINntpUrl::ActionFetchPart)
|
||||
{
|
||||
|
@ -769,6 +774,165 @@ nsresult nsNNTPProtocol::SetupPartExtractor(nsIStreamListener * aConsumer)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNNTPProtocol::ReadFromMemCache(nsICacheEntryDescriptor *entry)
|
||||
{
|
||||
NS_ENSURE_ARG(entry);
|
||||
|
||||
nsCOMPtr<nsITransport> cacheTransport;
|
||||
nsresult rv = entry->GetTransport(getter_AddRefs(cacheTransport));
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsNntpCacheStreamListener * cacheListener = new nsNntpCacheStreamListener();
|
||||
NS_ADDREF(cacheListener);
|
||||
|
||||
SetLoadGroup(m_loadGroup);
|
||||
m_typeWanted = ARTICLE_WANTED;
|
||||
|
||||
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningURL);
|
||||
cacheListener->Init(m_channelListener, NS_STATIC_CAST(nsIChannel *, this), mailnewsUrl);
|
||||
|
||||
nsCOMPtr<nsIRequest> request;
|
||||
rv = cacheTransport->AsyncRead(cacheListener, m_channelContext, 0, PRUint32(-1), 0, getter_AddRefs(request));
|
||||
NS_RELEASE(cacheListener);
|
||||
|
||||
MarkCurrentMsgRead();
|
||||
if (NS_SUCCEEDED(rv)) // ONLY if we succeeded in actually starting the read should we return
|
||||
{
|
||||
// we're not calling nsMsgProtocol::AsyncRead(), which calls nsNNTPProtocol::LoadUrl, so we need to take care of some stuff it does.
|
||||
m_ContentType = "";
|
||||
m_channelListener = nsnull;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsNNTPProtocol::ReadFromNewsConnection()
|
||||
{
|
||||
return nsMsgProtocol::AsyncOpen(m_channelListener, m_channelContext);
|
||||
}
|
||||
|
||||
// for messages stored in our offline cache, we have special code to handle that...
|
||||
// If it's in the local cache, we return true and we can abort the download because
|
||||
// this method does the rest of the work.
|
||||
PRBool nsNNTPProtocol::ReadFromLocalCache()
|
||||
{
|
||||
PRBool msgIsInLocalCache = PR_FALSE;
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningURL);
|
||||
mailnewsUrl->GetMsgIsInLocalCache(&msgIsInLocalCache);
|
||||
|
||||
if (msgIsInLocalCache)
|
||||
{
|
||||
nsXPIDLCString group;
|
||||
nsXPIDLCString commandSpecificData;
|
||||
rv = ParseURL(m_url, getter_Copies(group), &m_messageID, getter_Copies(commandSpecificData));
|
||||
nsCOMPtr <nsIMsgFolder> folder = do_QueryInterface(m_newsFolder);
|
||||
if (folder && NS_SUCCEEDED(rv))
|
||||
{
|
||||
// we want to create a file channel and read the msg from there.
|
||||
nsCOMPtr<nsITransport> fileChannel;
|
||||
PRUint32 offset=0, size=0;
|
||||
rv = folder->GetOfflineFileTransport(m_key, &offset, &size, getter_AddRefs(fileChannel));
|
||||
|
||||
// get the file channel from the folder, somehow (through the message or
|
||||
// folder sink?) We also need to set the transfer offset to the message offset
|
||||
if (fileChannel && NS_SUCCEEDED(rv))
|
||||
{
|
||||
// dougt - This may break the ablity to "cancel" a read from offline mail reading.
|
||||
// fileChannel->SetLoadGroup(m_loadGroup);
|
||||
|
||||
m_typeWanted = ARTICLE_WANTED;
|
||||
nsNntpCacheStreamListener * cacheListener = new nsNntpCacheStreamListener();
|
||||
NS_ADDREF(cacheListener);
|
||||
cacheListener->Init(m_channelListener, NS_STATIC_CAST(nsIChannel *, this), mailnewsUrl);
|
||||
nsCOMPtr<nsIRequest> request;
|
||||
rv = fileChannel->AsyncRead(cacheListener, m_channelContext, offset, size, 0, getter_AddRefs(request));
|
||||
NS_RELEASE(cacheListener);
|
||||
MarkCurrentMsgRead();
|
||||
|
||||
if (NS_SUCCEEDED(rv)) // ONLY if we succeeded in actually starting the read should we return
|
||||
{
|
||||
m_ContentType = "";
|
||||
m_channelListener = nsnull;
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNNTPProtocol::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry, nsCacheAccessMode access, nsresult status)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (NS_SUCCEEDED(status))
|
||||
{
|
||||
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningURL, &rv);
|
||||
mailnewsUrl->SetMemCacheEntry(entry);
|
||||
|
||||
// if we have write access then insert a "stream T" into the flow so data
|
||||
// gets written to both
|
||||
if (access & nsICache::ACCESS_WRITE && !(access & nsICache::ACCESS_READ))
|
||||
{
|
||||
entry->MarkValid();
|
||||
// use a stream listener Tee to force data into the cache and to our current channel listener...
|
||||
nsCOMPtr<nsIStreamListener> newListener;
|
||||
nsCOMPtr<nsIStreamListenerTee> tee = do_CreateInstance(kStreamListenerTeeCID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsITransport> transport;
|
||||
rv = entry->GetTransport(getter_AddRefs(transport));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIOutputStream> out;
|
||||
rv = transport->OpenOutputStream(0, PRUint32(-1), 0, getter_AddRefs(out));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = tee->Init(m_channelListener, out);
|
||||
m_channelListener = do_QueryInterface(tee);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = ReadFromMemCache(entry);
|
||||
if (access & nsICache::ACCESS_WRITE)
|
||||
entry->MarkValid();
|
||||
if (NS_SUCCEEDED(rv)) return NS_OK; // kick out if reading from the cache succeeded...
|
||||
}
|
||||
} // if we got a valid entry back from the cache...
|
||||
|
||||
// if reading from the cache failed or if we are writing into the cache, default to ReadFromImapConnection.
|
||||
return ReadFromNewsConnection();
|
||||
}
|
||||
|
||||
nsresult nsNNTPProtocol::OpenCacheEntry()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningURL, &rv);
|
||||
// get the cache session from our nntp service...
|
||||
nsCOMPtr <nsINntpService> nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsICacheSession> cacheSession;
|
||||
rv = nntpService->GetCacheSession(getter_AddRefs(cacheSession));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Open a cache entry with key = url
|
||||
nsXPIDLCString urlSpec;
|
||||
mailnewsUrl->GetSpec(getter_Copies(urlSpec));
|
||||
// for now, truncate of the query part so we don't duplicate urls in the cache...
|
||||
char * anchor = PL_strrchr(urlSpec, '?');
|
||||
if (anchor)
|
||||
*anchor = '\0';
|
||||
return cacheSession->AsyncOpenCacheEntry(urlSpec, nsICache::ACCESS_READ_WRITE, this);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNNTPProtocol::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -782,110 +946,12 @@ NS_IMETHODIMP nsNNTPProtocol::AsyncOpen(nsIStreamListener *listener, nsISupports
|
|||
// the memory cache or the local msg cache.
|
||||
if (mailnewsUrl && (m_newsAction == nsINntpUrl::ActionFetchArticle || m_newsAction == nsINntpUrl::ActionFetchPart))
|
||||
{
|
||||
nsCOMPtr<nsICachedNetData> cacheEntry;
|
||||
PRUint32 contentLength = 0;
|
||||
PRBool partialFlag = PR_FALSE;
|
||||
PRBool msgIsInLocalCache;
|
||||
|
||||
SetupPartExtractor(m_channelListener);
|
||||
SetupPartExtractorListener(m_channelListener);
|
||||
if (ReadFromLocalCache())
|
||||
return NS_OK;
|
||||
|
||||
mailnewsUrl->GetMsgIsInLocalCache(&msgIsInLocalCache);
|
||||
if (msgIsInLocalCache)
|
||||
{
|
||||
nsXPIDLCString group;
|
||||
nsXPIDLCString commandSpecificData;
|
||||
rv = ParseURL(m_url, getter_Copies(group), &m_messageID, getter_Copies(commandSpecificData));
|
||||
nsCOMPtr <nsIMsgFolder> folder = do_QueryInterface(m_newsFolder);
|
||||
if (folder && NS_SUCCEEDED(rv))
|
||||
{
|
||||
// we want to create a file channel and read the msg from there.
|
||||
nsCOMPtr<nsITransport> fileChannel;
|
||||
PRUint32 offset=0, size=0;
|
||||
rv = folder->GetOfflineFileTransport(m_key, &offset, &size, getter_AddRefs(fileChannel));
|
||||
|
||||
// get the file channel from the folder, somehow (through the message or
|
||||
// folder sink?) We also need to set the transfer offset to the message offset
|
||||
if (fileChannel && NS_SUCCEEDED(rv))
|
||||
{
|
||||
// dougt - This may break the ablity to "cancel" a read from offline mail reading.
|
||||
// fileChannel->SetLoadGroup(m_loadGroup);
|
||||
|
||||
m_typeWanted = ARTICLE_WANTED;
|
||||
nsNntpCacheStreamListener * cacheListener = new nsNntpCacheStreamListener();
|
||||
NS_ADDREF(cacheListener);
|
||||
cacheListener->Init(m_channelListener, NS_STATIC_CAST(nsIChannel *, this), mailnewsUrl);
|
||||
nsCOMPtr<nsIRequest> request;
|
||||
rv = fileChannel->AsyncRead(cacheListener, m_channelContext, offset, size, 0, getter_AddRefs(request));
|
||||
NS_RELEASE(cacheListener);
|
||||
MarkCurrentMsgRead();
|
||||
|
||||
if (NS_SUCCEEDED(rv)) // ONLY if we succeeded in actually starting the read should we return
|
||||
{
|
||||
m_ContentType = "";
|
||||
m_channelListener = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// look to see if this url should be added to the memory cache..
|
||||
PRBool useMemoryCache = PR_FALSE;
|
||||
mailnewsUrl->GetAddToMemoryCache(&useMemoryCache);
|
||||
rv = mailnewsUrl->GetMemCacheEntry(getter_AddRefs(cacheEntry));
|
||||
if (NS_SUCCEEDED(rv) && cacheEntry)
|
||||
{
|
||||
PRBool updateInProgress;
|
||||
m_typeWanted = ARTICLE_WANTED;
|
||||
cacheEntry->GetPartialFlag(&partialFlag);
|
||||
cacheEntry->GetUpdateInProgress(&updateInProgress);
|
||||
cacheEntry->GetStoredContentLength(&contentLength);
|
||||
// only try to update the cache entry if it isn't being used.
|
||||
// We always want to try to write to the cache entry if we can
|
||||
if (!updateInProgress)
|
||||
{
|
||||
// now we need to figure out if the entry is new / or partially unfinished...
|
||||
// this determines if we are going to USE the cache entry for reading the data
|
||||
// vs. if we need to write data into the cache entry...
|
||||
if (!contentLength || partialFlag)
|
||||
{
|
||||
// we're going to fill up this cache entry,
|
||||
// do we have a listener here?
|
||||
nsIStreamListener *anotherListener = m_channelListener;
|
||||
rv = cacheEntry->InterceptAsyncRead(anotherListener, 0, getter_AddRefs(m_channelListener));
|
||||
nsCOMPtr<nsIRequest> request;
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return nsMsgProtocol::AsyncOpen(m_channelListener, ctxt);
|
||||
}
|
||||
}
|
||||
}
|
||||
// now, determine if we should be loading from the cache or if we have
|
||||
// to really load the msg with a protocol connection...
|
||||
if (cacheEntry && contentLength > 0 && !partialFlag)
|
||||
{
|
||||
nsCOMPtr<nsIChannel> cacheChannel;
|
||||
rv = cacheEntry->NewChannel(m_loadGroup, getter_AddRefs(cacheChannel));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsNntpCacheStreamListener * cacheListener = new nsNntpCacheStreamListener();
|
||||
NS_ADDREF(cacheListener);
|
||||
SetLoadGroup(m_loadGroup);
|
||||
m_typeWanted = ARTICLE_WANTED;
|
||||
cacheListener->Init(m_channelListener, NS_STATIC_CAST(nsIChannel *, this), mailnewsUrl);
|
||||
nsCOMPtr<nsIRequest> request;
|
||||
rv = cacheChannel->AsyncOpen(cacheListener, m_channelContext);
|
||||
NS_RELEASE(cacheListener);
|
||||
|
||||
MarkCurrentMsgRead();
|
||||
if (NS_SUCCEEDED(rv)) // ONLY if we succeeded in actually starting the read should we return
|
||||
{
|
||||
// we're not calling nsMsgProtocol::AsyncRead(), which calls nsNNTPProtocol::LoadUrl, so we need to take care of some stuff it does.
|
||||
m_ContentType = "";
|
||||
m_channelListener = nsnull;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
rv = OpenCacheEntry();
|
||||
if (NS_SUCCEEDED(rv)) return NS_OK; // if this didn't return an error then jump out now...
|
||||
|
||||
}
|
||||
nsCOMPtr<nsIRequest> parentRequest;
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "nsIStringBundle.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsITimerCallback.h"
|
||||
#include "nsICacheListener.h"
|
||||
|
||||
// this is only needed as long as our libmime hack is in place
|
||||
#include "prio.h"
|
||||
|
@ -145,11 +146,14 @@ NEWS_FREE,
|
|||
NEWS_FINISHED
|
||||
} StatesEnum;
|
||||
|
||||
class nsNNTPProtocol : public nsINNTPProtocol, public nsITimerCallback, public nsMsgProtocol
|
||||
class nsICacheEntryDescriptor;
|
||||
|
||||
class nsNNTPProtocol : public nsINNTPProtocol, public nsITimerCallback, public nsICacheListener, public nsMsgProtocol
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSINNTPPROTOCOL
|
||||
NS_DECL_NSICACHELISTENER
|
||||
|
||||
// nsITimerCallback interfaces
|
||||
NS_IMETHOD_(void) Notify(nsITimer *timer);
|
||||
|
@ -170,7 +174,6 @@ public:
|
|||
nsresult LoadUrl(nsIURI * aURL, nsISupports * aConsumer);
|
||||
|
||||
private:
|
||||
nsresult SetupPartExtractor(nsIStreamListener * aConsumer);
|
||||
// over-rides from nsMsgProtocol
|
||||
virtual nsresult ProcessProtocolState(nsIURI * url, nsIInputStream * inputStream,
|
||||
PRUint32 sourceOffset, PRUint32 length);
|
||||
|
@ -392,21 +395,28 @@ private:
|
|||
|
||||
void SetProgressBarPercent(PRUint32 aProgress, PRUint32 aProgressMax);
|
||||
nsresult SetProgressStatus(const PRUnichar *aMessage);
|
||||
nsresult SetCheckingForNewNewsStatus(PRInt32 current, PRInt32 total);
|
||||
nsresult MarkCurrentMsgRead(); // marks the message corresponding to the currently running url read.
|
||||
nsresult SetCheckingForNewNewsStatus(PRInt32 current, PRInt32 total);
|
||||
nsresult MarkCurrentMsgRead(); // marks the message corresponding to the currently running url read.
|
||||
nsresult InitializeNewsFolderFromUri(const char *uri);
|
||||
void TimerCallback();
|
||||
nsCOMPtr <nsIInputStream> mInputStream;
|
||||
nsCOMPtr <nsITimer> mUpdateTimer;
|
||||
nsCOMPtr <nsITimer> mUpdateTimer;
|
||||
nsresult AlertError(PRInt32 errorCode, const char *text);
|
||||
PRInt32 mBytesReceived;
|
||||
PRInt32 mBytesReceivedSinceLastStatusUpdate;
|
||||
PRTime m_startTime;
|
||||
PRInt32 mNumGroupsListed;
|
||||
nsMsgKey m_key;
|
||||
PRInt32 mBytesReceivedSinceLastStatusUpdate;
|
||||
PRTime m_startTime;
|
||||
PRInt32 mNumGroupsListed;
|
||||
nsMsgKey m_key;
|
||||
|
||||
nsresult SetCurrentGroup(); /* sets m_currentGroup. should be called after doing a successful GROUP command */
|
||||
nsresult CleanupNewsgroupList(); /* cleans up m_newsgroupList, and set it to null */
|
||||
nsresult SetCurrentGroup(); /* sets m_currentGroup. should be called after doing a successful GROUP command */
|
||||
nsresult CleanupNewsgroupList(); /* cleans up m_newsgroupList, and set it to null */
|
||||
|
||||
// cache related helper methods
|
||||
nsresult OpenCacheEntry(); // makes a request to the cache service for a cache entry for a url
|
||||
PRBool ReadFromLocalCache(); // attempts to read the url out of our local (offline) cache....
|
||||
nsresult ReadFromNewsConnection(); // creates a new news connection to read the url
|
||||
nsresult ReadFromMemCache(nsICacheEntryDescriptor *entry); // attempts to read the url out of our memory cache
|
||||
nsresult SetupPartExtractorListener(nsIStreamListener * aConsumer);
|
||||
};
|
||||
|
||||
NS_BEGIN_EXTERN_C
|
||||
|
|
|
@ -59,6 +59,9 @@
|
|||
#include "nsIPrompt.h"
|
||||
#include "nsIRDFService.h"
|
||||
#include "nsNewsDownloader.h"
|
||||
#include "nsICacheService.h"
|
||||
#include "nsNetCID.h"
|
||||
|
||||
#undef GetPort // XXX Windows!
|
||||
#undef SetPort // XXX Windows!
|
||||
|
||||
|
@ -70,6 +73,7 @@ static NS_DEFINE_CID(kCPrefServiceCID, NS_PREF_CID);
|
|||
static NS_DEFINE_CID(kMsgAccountManagerCID, NS_MSGACCOUNTMANAGER_CID);
|
||||
static NS_DEFINE_CID(kMessengerMigratorCID, NS_MESSENGERMIGRATOR_CID);
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
static NS_DEFINE_CID(kCacheServiceCID, NS_CACHESERVICE_CID);
|
||||
|
||||
nsNntpService::nsNntpService()
|
||||
{
|
||||
|
@ -361,7 +365,12 @@ NS_IMETHODIMP nsNntpService::OpenAttachment(const char *aContentType,
|
|||
|
||||
nsCOMPtr<nsIURI> url;
|
||||
nsresult rv = NS_OK;
|
||||
NewURI(aUrl, nsnull, getter_AddRefs(url));
|
||||
nsCAutoString newsUrl;
|
||||
newsUrl = aUrl;
|
||||
newsUrl += "&type=";
|
||||
newsUrl += aContentType;
|
||||
|
||||
NewURI(newsUrl, nsnull, getter_AddRefs(url));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && url)
|
||||
{
|
||||
|
@ -1537,3 +1546,20 @@ nsNntpService::DownloadNewsgroupsForOffline(nsIMsgWindow *aMsgWindow, nsIUrlList
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpService::GetCacheSession(nsICacheSession **result)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!mCacheSession)
|
||||
{
|
||||
nsCOMPtr<nsICacheService> serv = do_GetService(kCacheServiceCID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = serv->CreateSession("NNTP-memory-only", nsICache::STORE_IN_MEMORY, nsICache::STREAM_BASED, getter_AddRefs(mCacheSession));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mCacheSession->SetDoomEntriesIfExpired(PR_FALSE);
|
||||
}
|
||||
|
||||
*result = mCacheSession;
|
||||
NS_IF_ADDREF(*result);
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "nsICmdLineHandler.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIContentHandler.h"
|
||||
#include "nsICacheSession.h"
|
||||
|
||||
class nsIURI;
|
||||
class nsIUrlListener;
|
||||
|
@ -46,7 +47,7 @@ class nsNntpService : public nsINntpService,
|
|||
public nsIProtocolHandler,
|
||||
public nsIMsgProtocolInfo,
|
||||
public nsICmdLineHandler,
|
||||
public nsIContentHandler
|
||||
public nsIContentHandler
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -87,6 +88,8 @@ protected:
|
|||
PRBool mPrintingOperation; // Flag for printing operations
|
||||
PRBool mOpenAttachmentOperation; // Flag for opening attachments
|
||||
PRBool mCopyingOperation;
|
||||
|
||||
nsCOMPtr<nsICacheSession> mCacheSession; // the cache session used by news
|
||||
};
|
||||
|
||||
#endif /* nsNntpService_h___ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче