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? */
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