fix problem downloading large imap headers, r=putterman, more work on MPOD

This commit is contained in:
bienvenu%netscape.com 2000-03-22 21:45:24 +00:00
Родитель dc59f1654f
Коммит 76e1e4e8f5
4 изменённых файлов: 45 добавлений и 24 удалений

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

@ -27,6 +27,10 @@
#include "nsHashtable.h" #include "nsHashtable.h"
#include "nsMimeTypes.h" #include "nsMimeTypes.h"
#include "nsIPref.h"
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
// need to talk to Rich about this... // need to talk to Rich about this...
#define IMAP_EXTERNAL_CONTENT_HEADER "X-Mozilla-IMAP-Part" #define IMAP_EXTERNAL_CONTENT_HEADER "X-Mozilla-IMAP-Part"
@ -36,6 +40,10 @@
// These are used to parse IMAP BODYSTRUCTURE responses, and intelligently (?) // These are used to parse IMAP BODYSTRUCTURE responses, and intelligently (?)
// figure out what parts we need to display inline. // figure out what parts we need to display inline.
static PRInt32 gMaxDepth = 0; // Maximum depth that we will descend before marking a shell invalid.
// This will be initialized from the prefs the first time a shell is created.
// This is to protect against excessively complex (deep) BODYSTRUCTURE responses.
/* /*
Create a nsIMAPBodyShell from a full BODYSTRUCUTRE response from the parser. Create a nsIMAPBodyShell from a full BODYSTRUCUTRE response from the parser.
@ -55,6 +63,15 @@
nsIMAPBodyShell::nsIMAPBodyShell(nsImapProtocol *protocolConnection, const char *buf, PRUint32 UID, const char *folderName) nsIMAPBodyShell::nsIMAPBodyShell(nsImapProtocol *protocolConnection, const char *buf, PRUint32 UID, const char *folderName)
{ {
if (gMaxDepth == 0)
{
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
if (NS_SUCCEEDED(rv) && prefs)
// one-time initialization
prefs->GetIntPref("mail.imap.mime_parts_on_demand_max_depth", &gMaxDepth);
}
m_isValid = PR_FALSE; m_isValid = PR_FALSE;
m_isBeingGenerated = PR_FALSE; m_isBeingGenerated = PR_FALSE;
m_cached = PR_FALSE; m_cached = PR_FALSE;
@ -82,6 +99,10 @@ nsIMAPBodyShell::nsIMAPBodyShell(nsImapProtocol *protocolConnection, const char
m_folderName = nsCRT::strdup(folderName); m_folderName = nsCRT::strdup(folderName);
if (!m_folderName) if (!m_folderName)
return; return;
if (GetShowAttachmentsInline())
SetContentModified(IMAP_CONTENT_MODIFIED_VIEW_INLINE);
else
SetContentModified(IMAP_CONTENT_MODIFIED_VIEW_AS_LINKS);
// Turn the BODYSTRUCTURE response into a form that the nsIMAPBodypartMessage can be constructed from. // Turn the BODYSTRUCTURE response into a form that the nsIMAPBodypartMessage can be constructed from.
char *doctoredBuf = PR_smprintf("(\"message\" \"rfc822\" NIL NIL NIL NIL 0 () %s 0)", buf); char *doctoredBuf = PR_smprintf("(\"message\" \"rfc822\" NIL NIL NIL NIL 0 () %s 0)", buf);
if (!doctoredBuf) if (!doctoredBuf)

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

@ -272,6 +272,8 @@ public:
PRBool IsShellCached() { return m_cached; } PRBool IsShellCached() { return m_cached; }
void SetIsCached(PRBool isCached) { m_cached = isCached; } void SetIsCached(PRBool isCached) { m_cached = isCached; }
PRBool GetGeneratingWholeMessage() { return m_generatingWholeMessage; } PRBool GetGeneratingWholeMessage() { return m_generatingWholeMessage; }
IMAP_ContentModifiedType GetContentModified() { return m_contentModified; }
void SetContentModified(IMAP_ContentModifiedType modType) { m_contentModified = modType; }
protected: protected:
@ -290,6 +292,8 @@ protected:
PRBool m_cached; // Whether or not this shell is cached PRBool m_cached; // Whether or not this shell is cached
PRBool m_generatingWholeMessage; // whether or not we are generating the whole (non-MPOD) message PRBool m_generatingWholeMessage; // whether or not we are generating the whole (non-MPOD) message
// Set to PR_FALSE if we are generating by parts // Set to PR_FALSE if we are generating by parts
IMAP_ContentModifiedType m_contentModified; // under what conditions the content has been modified.
// Either IMAP_CONTENT_MODIFIED_VIEW_INLINE or IMAP_CONTENT_MODIFIED_VIEW_AS_LINKS
}; };

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

@ -409,7 +409,6 @@ void nsImapServerResponseParser::ProcessOkCommand(const char *commandToken)
char *imapPart = nsnull; char *imapPart = nsnull;
fServerConnection.GetCurrentUrl()->GetImapPartToFetch(&imapPart); fServerConnection.GetCurrentUrl()->GetImapPartToFetch(&imapPart);
if (imapPart)
m_shell->Generate(imapPart); m_shell->Generate(imapPart);
PR_FREEIF(imapPart); PR_FREEIF(imapPart);
@ -1166,12 +1165,14 @@ void nsImapServerResponseParser::msg_fetch()
{ {
fDownloadingHeaders = PR_TRUE; fDownloadingHeaders = PR_TRUE;
bNeedEndMessageDownload = PR_TRUE; bNeedEndMessageDownload = PR_TRUE;
BeginMessageDownload(MESSAGE_RFC822);
envelope_data(); envelope_data();
} }
else if (!PL_strcasecmp(fNextToken, "INTERNALDATE")) else if (!PL_strcasecmp(fNextToken, "INTERNALDATE"))
internal_date(); internal_date();
else if (!PL_strcasecmp(fNextToken, "XAOL-ENVELOPE")) else if (!PL_strcasecmp(fNextToken, "XAOL-ENVELOPE"))
{ {
BeginMessageDownload(MESSAGE_RFC822);
xaolenvelope_data(); xaolenvelope_data();
fDownloadingHeaders = PR_TRUE; fDownloadingHeaders = PR_TRUE;
bNeedEndMessageDownload = PR_TRUE; bNeedEndMessageDownload = PR_TRUE;
@ -1194,16 +1195,6 @@ void nsImapServerResponseParser::msg_fetch()
{ {
if (ContinueParse()) if (ContinueParse())
{ {
nsresult rv;
rv = fServerConnection.BeginMessageDownLoad(fSizeOfMostRecentMessage,
MESSAGE_RFC822);
if (NS_FAILED(rv))
{
skip_to_CRLF();
fServerConnection.PseudoInterrupt(PR_TRUE);
fServerConnection.AbortMessageDownLoad();
return;
}
// complete the message download // complete the message download
fServerConnection.NormalMessageEndDownload(); fServerConnection.NormalMessageEndDownload();
} }
@ -1806,21 +1797,12 @@ void nsImapServerResponseParser::msg_fetch_content(PRBool chunk, PRInt32 origin,
// Don't do it if we are filling in a shell or downloading a part. // Don't do it if we are filling in a shell or downloading a part.
// DO do it if we are downloading a whole message as a result of // DO do it if we are downloading a whole message as a result of
// an invalid shell trying to generate. // an invalid shell trying to generate.
if ((!chunk || (origin == 0)) && if ((!chunk || (origin == 0)) && !GetDownloadingHeaders() &&
(GetFillingInShell() ? m_shell->GetGeneratingWholeMessage() : PR_TRUE)) (GetFillingInShell() ? m_shell->GetGeneratingWholeMessage() : PR_TRUE))
{ {
NS_ASSERTION(fSizeOfMostRecentMessage > 0, "most recent message has 0 or negative size"); if (!NS_SUCCEEDED(BeginMessageDownload(content_type)))
nsresult rv;
rv = fServerConnection.BeginMessageDownLoad(fSizeOfMostRecentMessage,
content_type);
if (NS_FAILED(rv))
{
skip_to_CRLF();
fServerConnection.PseudoInterrupt(PR_TRUE);
fServerConnection.AbortMessageDownLoad();
return; return;
} }
}
if (PL_strcasecmp(fNextToken, "NIL")) if (PL_strcasecmp(fNextToken, "NIL"))
{ {
@ -2607,3 +2589,16 @@ void nsImapServerResponseParser::SetSyntaxError(PRBool error)
} }
} }
nsresult nsImapServerResponseParser::BeginMessageDownload(const char *content_type)
{
NS_ASSERTION(fSizeOfMostRecentMessage > 0, "most recent message has 0 or negative size");
nsresult rv = fServerConnection.BeginMessageDownLoad(fSizeOfMostRecentMessage,
content_type);
if (NS_FAILED(rv))
{
skip_to_CRLF();
fServerConnection.PseudoInterrupt(PR_TRUE);
fServerConnection.AbortMessageDownLoad();
}
return rv;
}

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

@ -142,6 +142,7 @@ protected:
virtual void xaolenvelope_data(); virtual void xaolenvelope_data();
virtual void parse_address(nsCAutoString &addressLine); virtual void parse_address(nsCAutoString &addressLine);
virtual void internal_date(); virtual void internal_date();
virtual nsresult BeginMessageDownload(const char *content_type);
virtual void response_data(); virtual void response_data();
virtual void resp_text(); virtual void resp_text();