зеркало из https://github.com/mozilla/gecko-dev.git
fix for #141628. don't drop the NNTP connection when doing list if the server
sends us a line like: ". 0000000001 0000000002 y". r/sr=bienvenu
This commit is contained in:
Родитель
35ba6ab2bc
Коммит
5841265063
|
@ -3152,157 +3152,161 @@ static void ComputeRate(PRInt32 bytes, PRTime startTime, float *rate)
|
||||||
*/
|
*/
|
||||||
PRInt32 nsNNTPProtocol::ReadNewsList(nsIInputStream * inputStream, PRUint32 length)
|
PRInt32 nsNNTPProtocol::ReadNewsList(nsIInputStream * inputStream, PRUint32 length)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
PRInt32 i=0;
|
PRInt32 i=0;
|
||||||
PRUint32 status = 1;
|
PRUint32 status = 1;
|
||||||
|
|
||||||
PRBool pauseForMoreData = PR_FALSE;
|
PRBool pauseForMoreData = PR_FALSE;
|
||||||
char *line = m_lineStreamBuffer->ReadNextLine(inputStream, status, pauseForMoreData);
|
char *line = m_lineStreamBuffer->ReadNextLine(inputStream, status, pauseForMoreData);
|
||||||
char *orig_line = line;
|
char *orig_line = line;
|
||||||
|
|
||||||
if (pauseForMoreData)
|
if (pauseForMoreData)
|
||||||
{
|
{
|
||||||
SetFlag(NNTP_PAUSE_FOR_READ);
|
SetFlag(NNTP_PAUSE_FOR_READ);
|
||||||
PR_FREEIF(orig_line);
|
PR_FREEIF(orig_line);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!line) return(status); /* no line yet */
|
if (!line)
|
||||||
|
return(status); /* no line yet */
|
||||||
/* End of list? */
|
|
||||||
if (line[0]=='.' && line[1]=='\0')
|
/* End of list? */
|
||||||
|
if (line[0]=='.' && line[1]=='\0')
|
||||||
|
{
|
||||||
|
PRBool listpnames=PR_FALSE;
|
||||||
|
rv = m_nntpServer->QueryExtension("LISTPNAMES",&listpnames);
|
||||||
|
if (NS_SUCCEEDED(rv) && listpnames)
|
||||||
|
m_nextState = NNTP_LIST_PRETTY_NAMES;
|
||||||
|
else
|
||||||
|
m_nextState = DISPLAY_NEWSGROUPS;
|
||||||
|
ClearFlag(NNTP_PAUSE_FOR_READ);
|
||||||
|
PR_FREEIF(orig_line);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (line[0] == '.')
|
||||||
|
{
|
||||||
|
if ((line[1] == ' ') || (line[1] == '.' && line [2] == '.' && line[3] == ' '))
|
||||||
{
|
{
|
||||||
PRBool listpnames=PR_FALSE;
|
// some servers send "... 0000000001 0000000002 y"
|
||||||
rv = m_nntpServer->QueryExtension("LISTPNAMES",&listpnames);
|
// and some servers send ". 0000000001 0000000002 y"
|
||||||
if (NS_SUCCEEDED(rv) && listpnames)
|
// just skip that those lines
|
||||||
m_nextState = NNTP_LIST_PRETTY_NAMES;
|
// see bug #69231 and #123560
|
||||||
else
|
PR_FREEIF(orig_line);
|
||||||
m_nextState = DISPLAY_NEWSGROUPS;
|
return status;
|
||||||
ClearFlag(NNTP_PAUSE_FOR_READ);
|
|
||||||
PR_FREEIF(orig_line);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
else if (line [0] == '.' && line [1] == '.')
|
// The NNTP server quotes all lines beginning with "." by doubling it, so unquote
|
||||||
{
|
line++;
|
||||||
if (line [2] == '.')
|
}
|
||||||
{
|
|
||||||
// some servers send "... 0000000001 0000000002 y".
|
/* almost correct
|
||||||
// just skip that that.
|
*/
|
||||||
// see bug #69231
|
if(status > 1)
|
||||||
PR_FREEIF(orig_line);
|
{
|
||||||
return status;
|
mBytesReceived += status;
|
||||||
}
|
mBytesReceivedSinceLastStatusUpdate += status;
|
||||||
/* The NNTP server quotes all lines beginning with "." by doubling it. */
|
|
||||||
line++;
|
if ((mBytesReceivedSinceLastStatusUpdate > UPDATE_THRESHHOLD) && m_msgWindow) {
|
||||||
}
|
mBytesReceivedSinceLastStatusUpdate = 0;
|
||||||
|
|
||||||
/* almost correct
|
nsCOMPtr <nsIMsgStatusFeedback> msgStatusFeedback;
|
||||||
*/
|
|
||||||
if(status > 1)
|
rv = m_msgWindow->GetStatusFeedback(getter_AddRefs(msgStatusFeedback));
|
||||||
{
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
mBytesReceived += status;
|
|
||||||
mBytesReceivedSinceLastStatusUpdate += status;
|
nsXPIDLString statusString;
|
||||||
|
|
||||||
if ((mBytesReceivedSinceLastStatusUpdate > UPDATE_THRESHHOLD) && m_msgWindow) {
|
nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
||||||
mBytesReceivedSinceLastStatusUpdate = 0;
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsCOMPtr <nsIMsgStatusFeedback> msgStatusFeedback;
|
nsCOMPtr<nsIStringBundle> bundle;
|
||||||
|
rv = bundleService->CreateBundle(NEWS_MSGS_URL, getter_AddRefs(bundle));
|
||||||
rv = m_msgWindow->GetStatusFeedback(getter_AddRefs(msgStatusFeedback));
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
nsAutoString bytesStr;
|
||||||
nsXPIDLString statusString;
|
bytesStr.AppendInt(mBytesReceived / 1024);
|
||||||
|
|
||||||
nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
// compute the rate, and then convert it have one
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
// decimal precision.
|
||||||
|
float rate = 0.0;
|
||||||
nsCOMPtr<nsIStringBundle> bundle;
|
ComputeRate(mBytesReceived, m_startTime, &rate);
|
||||||
rv = bundleService->CreateBundle(NEWS_MSGS_URL, getter_AddRefs(bundle));
|
char rate_buf[RATE_STR_BUF_LEN];
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
PR_snprintf(rate_buf,RATE_STR_BUF_LEN,"%.1f", rate);
|
||||||
|
|
||||||
nsAutoString bytesStr;
|
nsAutoString rateStr;
|
||||||
bytesStr.AppendInt(mBytesReceived / 1024);
|
rateStr.AppendWithConversion(rate_buf);
|
||||||
|
|
||||||
// compute the rate, and then convert it have one
|
nsAutoString numGroupsStr;
|
||||||
// decimal precision.
|
numGroupsStr.AppendInt(mNumGroupsListed);
|
||||||
float rate = 0.0;
|
|
||||||
ComputeRate(mBytesReceived, m_startTime, &rate);
|
const PRUnichar *formatStrings[3] = { numGroupsStr.get(), bytesStr.get(), rateStr.get() };
|
||||||
char rate_buf[RATE_STR_BUF_LEN];
|
rv = bundle->FormatStringFromName(NS_LITERAL_STRING("bytesReceived").get(),
|
||||||
PR_snprintf(rate_buf,RATE_STR_BUF_LEN,"%.1f", rate);
|
formatStrings, 3,
|
||||||
|
getter_Copies(statusString));
|
||||||
nsAutoString rateStr;
|
|
||||||
rateStr.AppendWithConversion(rate_buf);
|
rv = msgStatusFeedback->ShowStatusString(statusString);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
nsAutoString numGroupsStr;
|
PR_FREEIF(orig_line);
|
||||||
numGroupsStr.AppendInt(mNumGroupsListed);
|
return rv;
|
||||||
|
}
|
||||||
const PRUnichar *formatStrings[3] = { numGroupsStr.get(), bytesStr.get(), rateStr.get() };
|
}
|
||||||
rv = bundle->FormatStringFromName(NS_LITERAL_STRING("bytesReceived").get(),
|
}
|
||||||
formatStrings, 3,
|
|
||||||
getter_Copies(statusString));
|
/* find whitespace separator if it exits */
|
||||||
|
for(i=0; line[i] != '\0' && !NET_IS_SPACE(line[i]); i++)
|
||||||
rv = msgStatusFeedback->ShowStatusString(statusString);
|
; /* null body */
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
PR_FREEIF(orig_line);
|
char *description;
|
||||||
return rv;
|
if(line[i] == '\0')
|
||||||
}
|
description = &line[i];
|
||||||
}
|
else
|
||||||
|
description = &line[i+1];
|
||||||
|
|
||||||
|
line[i] = 0; /* terminate group name */
|
||||||
|
|
||||||
|
/* store all the group names */
|
||||||
|
NS_ASSERTION(m_nntpServer, "no nntp incoming server");
|
||||||
|
if (m_nntpServer) {
|
||||||
|
m_readNewsListCount++;
|
||||||
|
mNumGroupsListed++;
|
||||||
|
rv = m_nntpServer->AddNewsgroupToList(line);
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to add to subscribe ds");
|
||||||
|
// since it's not fatal, don't let this error stop the LIST command.
|
||||||
|
rv = NS_OK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rv = NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_readNewsListCount == READ_NEWS_LIST_COUNT_MAX) {
|
||||||
|
m_readNewsListCount = 0;
|
||||||
|
if (mUpdateTimer) {
|
||||||
|
mUpdateTimer->Cancel();
|
||||||
|
mUpdateTimer = nsnull;
|
||||||
|
}
|
||||||
|
mUpdateTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to create timer");
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
PR_FREEIF(orig_line);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find whitespace separator if it exits */
|
mInputStream = inputStream;
|
||||||
for(i=0; line[i] != '\0' && !NET_IS_SPACE(line[i]); i++)
|
|
||||||
; /* null body */
|
const PRUint32 kUpdateTimerDelay = READ_NEWS_LIST_TIMEOUT;
|
||||||
|
rv = mUpdateTimer->InitWithCallback(NS_STATIC_CAST(nsITimerCallback*,this), kUpdateTimerDelay,
|
||||||
char *description;
|
nsITimer::TYPE_ONE_SHOT);
|
||||||
if(line[i] == '\0')
|
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to init timer");
|
||||||
description = &line[i];
|
if (NS_FAILED(rv)) {
|
||||||
else
|
PR_FREEIF(orig_line);
|
||||||
description = &line[i+1];
|
return -1;
|
||||||
|
|
||||||
line[i] = 0; /* terminate group name */
|
|
||||||
|
|
||||||
/* store all the group names */
|
|
||||||
NS_ASSERTION(m_nntpServer, "no nntp incoming server");
|
|
||||||
if (m_nntpServer) {
|
|
||||||
m_readNewsListCount++;
|
|
||||||
mNumGroupsListed++;
|
|
||||||
rv = m_nntpServer->AddNewsgroupToList(line);
|
|
||||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to add to subscribe ds");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rv = NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_readNewsListCount == READ_NEWS_LIST_COUNT_MAX) {
|
|
||||||
m_readNewsListCount = 0;
|
|
||||||
if (mUpdateTimer) {
|
|
||||||
mUpdateTimer->Cancel();
|
|
||||||
mUpdateTimer = nsnull;
|
|
||||||
}
|
|
||||||
mUpdateTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
|
|
||||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to create timer");
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
PR_FREEIF(orig_line);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mInputStream = inputStream;
|
|
||||||
|
|
||||||
const PRUint32 kUpdateTimerDelay = READ_NEWS_LIST_TIMEOUT;
|
|
||||||
rv = mUpdateTimer->InitWithCallback(NS_STATIC_CAST(nsITimerCallback*,this), kUpdateTimerDelay,
|
|
||||||
nsITimer::TYPE_ONE_SHOT);
|
|
||||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to init timer");
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
PR_FREEIF(orig_line);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_nextState = NEWS_FINISHED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PR_FREEIF(orig_line);
|
m_nextState = NEWS_FINISHED;
|
||||||
if (NS_FAILED(rv)) return -1;
|
}
|
||||||
return(status);
|
|
||||||
|
PR_FREEIF(orig_line);
|
||||||
|
if (NS_FAILED(rv)) return -1;
|
||||||
|
return(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
Загрузка…
Ссылка в новой задаче