fixes for hierarchy delimiter handling, multiple fetches of imap messages to retrieve inline attachments, crash in morkRowObject::CloseRowObject r=mscott 52260, 59376 58691

This commit is contained in:
bienvenu%netscape.com 2000-11-13 22:35:50 +00:00
Родитель bb8b2a822e
Коммит 68e1cad16c
7 изменённых файлов: 125 добавлений и 98 удалений

Просмотреть файл

@ -22,6 +22,7 @@
#include "nsISupports.idl"
#include "MailNewsTypes2.idl"
#include "nsIImapUrl.idl"
interface nsIFileSpec;
@ -50,4 +51,5 @@ interface nsIImapMessageSink : nsISupports {
void GetMessageSizeFromDB(in string id, in boolean idIsUid, out unsigned long size);
void SetContentModified(in nsIImapUrl aImapUrl, in nsImapContentModifiedType modified);
};

Просмотреть файл

@ -463,6 +463,7 @@ nsImapIncomingServer::LoadNextQueuedUrl(PRBool *aResult)
aSupport(getter_AddRefs(m_urlQueue->ElementAt(0)));
nsCOMPtr<nsIImapUrl>
aImapUrl(do_QueryInterface(aSupport, &rv));
nsCOMPtr<nsIMsgMailNewsUrl> aMailNewsUrl(do_QueryInterface(aSupport, &rv));
if (aImapUrl)
{
@ -479,22 +480,10 @@ nsImapIncomingServer::LoadNextQueuedUrl(PRBool *aResult)
mockChannel->Close(); // try closing it to get channel listener nulled out.
nsCOMPtr<nsINetDataCacheManager> cacheManager = do_GetService(NS_NETWORK_CACHE_MANAGER_CONTRACTID, &res);
if (NS_SUCCEEDED(res) && cacheManager)
if (aMailNewsUrl)
{
nsCOMPtr<nsICachedNetData> cacheEntry;
// 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.......
url->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';
res = cacheManager->GetCachedNetData(urlCString, 0, 0, nsINetDataCacheManager::BYPASS_PERSISTENT_CACHE,
getter_AddRefs(cacheEntry));
res = aMailNewsUrl->GetMemCacheEntry(getter_AddRefs(cacheEntry));
if (NS_SUCCEEDED(res) && cacheEntry)
cacheEntry->Delete();
}
@ -917,7 +906,7 @@ NS_IMETHODIMP nsImapIncomingServer::PossibleImapMailbox(const char *folderPath,
}
nsCAutoString dupFolderPath(folderPath);
if (dupFolderPath.Last() == '/')
if (dupFolderPath.Last() == hierarchyDelimiter)
{
dupFolderPath.SetLength(dupFolderPath.Length()-1);
// *** this is what we did in 4.x in order to list uw folder only
@ -934,7 +923,7 @@ NS_IMETHODIMP nsImapIncomingServer::PossibleImapMailbox(const char *folderPath,
uri.Assign(serverUri);
PRInt32 leafPos = folderName.RFindChar('/');
PRInt32 leafPos = folderName.RFindChar(hierarchyDelimiter);
nsCAutoString parentName(folderName);
nsCAutoString parentUri(uri);

Просмотреть файл

@ -326,13 +326,16 @@ nsresult nsImapMailFolder::CreateSubFolders(nsFileSpec &path)
// take the full unicode folder name and find the unicode leaf name.
currentFolderNameStr.Assign(unicodeName);
PRInt32 leafPos = currentFolderNameStr.RFindChar('/');
PRUnichar delimiter = 0;
GetHierarchyDelimiter(&delimiter);
PRInt32 leafPos = currentFolderNameStr.RFindChar(delimiter);
if (leafPos > 0)
currentFolderNameStr.Cut(0, leafPos + 1);
// take the utf7 full online name, and determine the utf7 leaf name
utf7LeafName.AssignWithConversion(onlineFullUtf7Name);
leafPos = utf7LeafName.RFindChar('/');
leafPos = utf7LeafName.RFindChar(delimiter);
if (leafPos > 0)
utf7LeafName.Cut(0, leafPos + 1);
}
@ -567,7 +570,7 @@ NS_IMETHODIMP nsImapMailFolder::CreateClientSubfolderInfo(const char *folderName
nsAutoString leafName; leafName.AssignWithConversion(folderName);
nsAutoString folderNameStr;
nsAutoString parentName = leafName;
PRInt32 folderStart = leafName.FindChar('/');
PRInt32 folderStart = leafName.FindChar(hierarchyDelimiter);
if (folderStart > 0)
{
NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &rv);
@ -626,11 +629,11 @@ NS_IMETHODIMP nsImapMailFolder::CreateClientSubfolderInfo(const char *folderName
//need to set the folder name
nsCOMPtr <nsIDBFolderInfo> folderInfo;
rv = unusedDB->GetDBFolderInfo(getter_AddRefs(folderInfo));
if(NS_SUCCEEDED(rv))
{
// if(NS_SUCCEEDED(rv))
// {
// ### DMB used to be leafNameFromUser?
folderInfo->SetMailboxName(&folderNameStr);
}
// folderInfo->SetMailboxName(&folderNameStr);
// }
//Now let's create the actual new folder
rv = AddSubfolderWithPath(&folderNameStr, dbFileSpec, getter_AddRefs(child));
@ -647,6 +650,14 @@ NS_IMETHODIMP nsImapMailFolder::CreateClientSubfolderInfo(const char *folderName
imapFolder->SetVerifiedAsOnlineFolder(PR_TRUE);
imapFolder->SetOnlineName(onlineName.GetBuffer());
imapFolder->SetHierarchyDelimiter(hierarchyDelimiter);
// store the online name as the mailbox name in the db folder info
// I don't think anyone uses the mailbox name, so we'll use it
// to restore the online name when blowing away an imap db.
if (folderInfo)
{
nsAutoString unicodeOnlineName; unicodeOnlineName.AssignWithConversion(onlineName);
folderInfo->SetMailboxName(&unicodeOnlineName);
}
}
unusedDB->SetSummaryValid(PR_TRUE);
@ -785,6 +796,7 @@ NS_IMETHODIMP nsImapMailFolder::GetHierarchyDelimiter(PRUnichar *aHierarchyDelim
{
if (!aHierarchyDelimiter)
return NS_ERROR_NULL_POINTER;
ReadDBFolderInfo(PR_FALSE); // update cache first.
*aHierarchyDelimiter = m_hierarchyDelimiter;
return NS_OK;
}
@ -1366,7 +1378,7 @@ NS_IMETHODIMP nsImapMailFolder::SetOnlineName(const char * aOnlineFolderName)
nsCOMPtr<nsIDBFolderInfo> folderInfo;
m_onlineFolderName = aOnlineFolderName;
rv = GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(db));
if(NS_SUCCEEDED(rv))
if(NS_SUCCEEDED(rv) && folderInfo)
{
nsAutoString onlineName; onlineName.AssignWithConversion(aOnlineFolderName);
rv = folderInfo->SetProperty("onlineName", &onlineName);
@ -1397,6 +1409,7 @@ nsImapMailFolder::GetDBFolderInfoAndDB(nsIDBFolderInfo **folderInfo, nsIMsgDatab
nsresult openErr=NS_ERROR_UNEXPECTED;
if(!db || !folderInfo)
return NS_ERROR_NULL_POINTER; //ducarroz: should we use NS_ERROR_INVALID_ARG?
nsresult rv;
openErr = GetDatabase(nsnull);
@ -1414,19 +1427,22 @@ nsImapMailFolder::GetDBFolderInfoAndDB(nsIDBFolderInfo **folderInfo, nsIMsgDatab
m_onlineFolderName.Assign(onlineName);
else
{
char *uri = nsnull;
nsresult rv = GetURI(&uri);
nsAutoString autoOnlineName;
// autoOnlineName.AssignWithConversion(name);
(*folderInfo)->GetMailboxName(&autoOnlineName);
if (autoOnlineName.Length() == 0)
{
nsXPIDLCString uri;
rv = GetURI(getter_Copies(uri));
if (NS_FAILED(rv)) return rv;
char * hostname = nsnull;
rv = GetHostname(&hostname);
nsXPIDLCString hostname;
rv = GetHostname(getter_Copies(hostname));
if (NS_FAILED(rv)) return rv;
nsXPIDLCString name;
rv = nsImapURI2FullName(kImapRootURI, hostname, uri, getter_Copies(name));
m_onlineFolderName.Assign(name);
nsAutoString autoOnlineName; autoOnlineName.AssignWithConversion(name);
}
rv = (*folderInfo)->SetProperty("onlineName", &autoOnlineName);
PR_FREEIF(uri);
PR_FREEIF(hostname);
}
}
}
@ -1855,6 +1871,7 @@ NS_IMETHODIMP nsImapMailFolder::UpdateImapMailboxInfo(
if (mDatabase)
{
dbFolderInfo = null_nsCOMPtr();
NotifyStoreClosedAllHeaders();
mDatabase->ForceClosed();
}
mDatabase = null_nsCOMPtr();
@ -3289,6 +3306,12 @@ nsImapMailFolder::GetMessageSizeFromDB(const char *id, PRBool idIsUid, PRUint32
return rv;
}
NS_IMETHODIMP
nsImapMailFolder::SetContentModified(nsIImapUrl *aImapUrl, nsImapContentModifiedType modified)
{
return aImapUrl->SetContentModified(modified);
}
NS_IMETHODIMP
nsImapMailFolder::OnStartRunningUrl(nsIURI *aUrl)
{

Просмотреть файл

@ -59,8 +59,6 @@
#include "nsIDNSService.h"
// for the memory cache...
#include "nsINetDataCacheManager.h"
#include "nsINetDataCache.h"
#include "nsICachedNetData.h"
#include "nsCOMPtr.h"
@ -3527,8 +3525,8 @@ PRBool nsImapProtocol::GetActive()
void nsImapProtocol::SetContentModified(IMAP_ContentModifiedType modified)
{
if (m_runningUrl)
m_runningUrl->SetContentModified(modified);
if (m_runningUrl && m_imapMessageSink)
m_imapMessageSink->SetContentModified(m_runningUrl, modified);
}
@ -6809,21 +6807,7 @@ NS_IMETHODIMP nsImapMockChannel::AsyncRead(nsIStreamListener *listener, nsISuppo
// look to see if this url should be added to the memory cache..
PRBool useMemoryCache = PR_FALSE;
mailnewsUrl->GetAddToMemoryCache(&useMemoryCache);
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.......
m_url->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(cacheEntry));
rv = mailnewsUrl->GetMemCacheEntry(getter_AddRefs(cacheEntry));
if (NS_SUCCEEDED(rv) && cacheEntry)
{
PRBool updateInProgress;
@ -6831,8 +6815,8 @@ NS_IMETHODIMP nsImapMockChannel::AsyncRead(nsIStreamListener *listener, nsISuppo
cacheEntry->GetUpdateInProgress(&updateInProgress);
cacheEntry->GetStoredContentLength(&contentLength);
// only try to update the cache entry if it isn't being used.
// and we want to write to the memory cache.
if (!updateInProgress && useMemoryCache)
// 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
@ -6842,7 +6826,6 @@ NS_IMETHODIMP nsImapMockChannel::AsyncRead(nsIStreamListener *listener, nsISuppo
rv = cacheEntry->InterceptAsyncRead(listener, 0, getter_AddRefs(m_channelListener));
}
}
}
// regardless as to whether we are inserting into the cache or not, proceed with
// setting up the load group!
@ -6865,6 +6848,13 @@ NS_IMETHODIMP nsImapMockChannel::AsyncRead(nsIStreamListener *listener, nsISuppo
// 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))
{
nsCOMPtr<nsIChannel> cacheChannel;
rv = cacheEntry->NewChannel(m_loadGroup, getter_AddRefs(cacheChannel));
@ -6893,6 +6883,7 @@ NS_IMETHODIMP nsImapMockChannel::AsyncRead(nsIStreamListener *listener, nsISuppo
}
}
}
}
// okay, add the mock channel to the load group..
imapUrl->AddChannelToLoadGroup();

Просмотреть файл

@ -42,7 +42,7 @@
#include "nsXPIDLString.h"
#include "nsAutoLock.h"
#include "nsIMAPNamespace.h"
#include "nsICachedNetData.h"
// rdf stuff is needed to get the charset from the imap folder associated with the url.
#include "nsIRDFService.h"
#include "rdf.h"
@ -893,6 +893,28 @@ NS_IMETHODIMP nsImapUrl::SetAllowContentChange(PRBool allowContentChange)
NS_IMETHODIMP nsImapUrl::SetContentModified(nsImapContentModifiedType contentModified)
{
m_contentModified = contentModified;
nsCOMPtr<nsICachedNetData> cacheEntry;
nsresult res = GetMemCacheEntry(getter_AddRefs(cacheEntry));
if (NS_SUCCEEDED(res) && cacheEntry)
{
const char *contentModifiedAnnotation = "";
switch (m_contentModified)
{
case IMAP_CONTENT_NOT_MODIFIED:
contentModifiedAnnotation = "Not Modified";
break;
case IMAP_CONTENT_MODIFIED_VIEW_INLINE:
contentModifiedAnnotation = "Modified View Inline";
break;
case IMAP_CONTENT_MODIFIED_VIEW_AS_LINKS:
NS_ASSERTION(PR_FALSE, "we're not using this anymore!");
break;
case IMAP_CONTENT_FORCE_CONTENT_NOT_MODIFIED:
contentModifiedAnnotation = "Force Content Not Modified";
break;
}
cacheEntry->SetAnnotation("ContentModified", nsCRT::strlen(contentModifiedAnnotation), contentModifiedAnnotation);
}
return NS_OK;
}

Просмотреть файл

@ -159,7 +159,7 @@ nsImapURI2Path(const char* rootURI, const char* uriStr, nsFileSpec& pathResult)
}
nsresult
nsImapURI2FullName(const char* rootURI, const char* hostname, char* uriStr,
nsImapURI2FullName(const char* rootURI, const char* hostname, const char* uriStr,
char **name)
{
nsAutoString uri; uri.AssignWithConversion(uriStr);

Просмотреть файл

@ -35,7 +35,7 @@ nsImapURI2Path(const char* rootURI, const char* uriStr,
nsFileSpec& pathResult);
extern nsresult
nsImapURI2FullName(const char* rootURI, const char* hostname, char* uriStr,
nsImapURI2FullName(const char* rootURI, const char* hostname, const char* uriStr,
char **name);
extern nsresult