зеркало из https://github.com/mozilla/pjs.git
fix problem downloading large imap headers, r=putterman, more work on MPOD
This commit is contained in:
Родитель
dc59f1654f
Коммит
76e1e4e8f5
|
@ -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();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче