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:
sspitzer%netscape.com 2002-10-03 09:47:36 +00:00
Родитель 35ba6ab2bc
Коммит 5841265063
1 изменённых файлов: 150 добавлений и 146 удалений

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

@ -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? */ /* End of list? */
if (line[0]=='.' && line[1]=='\0') 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".
// just skip that that.
// see bug #69231
PR_FREEIF(orig_line);
return status;
}
/* The NNTP server quotes all lines beginning with "." by doubling it. */
line++;
}
/* almost correct /* almost correct
*/ */
if(status > 1) if(status > 1)
{ {
mBytesReceived += status; mBytesReceived += status;
mBytesReceivedSinceLastStatusUpdate += status; mBytesReceivedSinceLastStatusUpdate += status;
if ((mBytesReceivedSinceLastStatusUpdate > UPDATE_THRESHHOLD) && m_msgWindow) { if ((mBytesReceivedSinceLastStatusUpdate > UPDATE_THRESHHOLD) && m_msgWindow) {
mBytesReceivedSinceLastStatusUpdate = 0; mBytesReceivedSinceLastStatusUpdate = 0;
nsCOMPtr <nsIMsgStatusFeedback> msgStatusFeedback; nsCOMPtr <nsIMsgStatusFeedback> msgStatusFeedback;
rv = m_msgWindow->GetStatusFeedback(getter_AddRefs(msgStatusFeedback)); rv = m_msgWindow->GetStatusFeedback(getter_AddRefs(msgStatusFeedback));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsXPIDLString statusString; nsXPIDLString statusString;
nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStringBundle> bundle; nsCOMPtr<nsIStringBundle> bundle;
rv = bundleService->CreateBundle(NEWS_MSGS_URL, getter_AddRefs(bundle)); rv = bundleService->CreateBundle(NEWS_MSGS_URL, getter_AddRefs(bundle));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsAutoString bytesStr; nsAutoString bytesStr;
bytesStr.AppendInt(mBytesReceived / 1024); bytesStr.AppendInt(mBytesReceived / 1024);
// compute the rate, and then convert it have one // compute the rate, and then convert it have one
// decimal precision. // decimal precision.
float rate = 0.0; float rate = 0.0;
ComputeRate(mBytesReceived, m_startTime, &rate); ComputeRate(mBytesReceived, m_startTime, &rate);
char rate_buf[RATE_STR_BUF_LEN]; char rate_buf[RATE_STR_BUF_LEN];
PR_snprintf(rate_buf,RATE_STR_BUF_LEN,"%.1f", rate); PR_snprintf(rate_buf,RATE_STR_BUF_LEN,"%.1f", rate);
nsAutoString rateStr; nsAutoString rateStr;
rateStr.AppendWithConversion(rate_buf); rateStr.AppendWithConversion(rate_buf);
nsAutoString numGroupsStr; nsAutoString numGroupsStr;
numGroupsStr.AppendInt(mNumGroupsListed); numGroupsStr.AppendInt(mNumGroupsListed);
const PRUnichar *formatStrings[3] = { numGroupsStr.get(), bytesStr.get(), rateStr.get() }; const PRUnichar *formatStrings[3] = { numGroupsStr.get(), bytesStr.get(), rateStr.get() };
rv = bundle->FormatStringFromName(NS_LITERAL_STRING("bytesReceived").get(), rv = bundle->FormatStringFromName(NS_LITERAL_STRING("bytesReceived").get(),
formatStrings, 3, formatStrings, 3,
getter_Copies(statusString)); getter_Copies(statusString));
rv = msgStatusFeedback->ShowStatusString(statusString); rv = msgStatusFeedback->ShowStatusString(statusString);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
PR_FREEIF(orig_line); PR_FREEIF(orig_line);
return rv; return rv;
} }
}
} }
}
/* find whitespace separator if it exits */ /* find whitespace separator if it exits */
for(i=0; line[i] != '\0' && !NET_IS_SPACE(line[i]); i++) for(i=0; line[i] != '\0' && !NET_IS_SPACE(line[i]); i++)
; /* null body */ ; /* null body */
char *description; char *description;
if(line[i] == '\0') if(line[i] == '\0')
description = &line[i]; description = &line[i];
else else
description = &line[i+1]; description = &line[i+1];
line[i] = 0; /* terminate group name */ line[i] = 0; /* terminate group name */
/* store all the group names */ /* store all the group names */
NS_ASSERTION(m_nntpServer, "no nntp incoming server"); NS_ASSERTION(m_nntpServer, "no nntp incoming server");
if (m_nntpServer) { if (m_nntpServer) {
m_readNewsListCount++; m_readNewsListCount++;
mNumGroupsListed++; mNumGroupsListed++;
rv = m_nntpServer->AddNewsgroupToList(line); rv = m_nntpServer->AddNewsgroupToList(line);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to add to subscribe ds"); 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.
else { rv = NS_OK;
rv = NS_ERROR_FAILURE; }
} else {
rv = NS_ERROR_FAILURE;
}
if (m_readNewsListCount == READ_NEWS_LIST_COUNT_MAX) { if (m_readNewsListCount == READ_NEWS_LIST_COUNT_MAX) {
m_readNewsListCount = 0; m_readNewsListCount = 0;
if (mUpdateTimer) { if (mUpdateTimer) {
mUpdateTimer->Cancel(); mUpdateTimer->Cancel();
mUpdateTimer = nsnull; mUpdateTimer = nsnull;
} }
mUpdateTimer = do_CreateInstance("@mozilla.org/timer;1", &rv); mUpdateTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to create timer"); NS_ASSERTION(NS_SUCCEEDED(rv),"failed to create timer");
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
PR_FREEIF(orig_line); PR_FREEIF(orig_line);
return -1; 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); mInputStream = inputStream;
if (NS_FAILED(rv)) return -1;
return(status); 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);
if (NS_FAILED(rv)) return -1;
return(status);
} }
NS_IMETHODIMP NS_IMETHODIMP