fixes bug 240053 "lock icon not updated properly on redirect of HTTPS request" r=biesi sr=bz a=dbaron

This commit is contained in:
darin%meer.net 2004-04-10 20:03:03 +00:00
Родитель cb3bfa896c
Коммит 3acc4108ab
4 изменённых файлов: 63 добавлений и 16 удалений

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

@ -3467,6 +3467,28 @@ nsHttpChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
} }
if (mListener) { if (mListener) {
//
// synthesize transport progress event. we do this here since we want
// to delay OnProgress events until we start streaming data. this is
// crucially important since it impacts the lock icon (see bug 240053).
//
nsresult transportStatus;
if (request == mCachePump)
transportStatus = nsITransport::STATUS_READING;
else
transportStatus = nsISocketTransport::STATUS_RECEIVING_FROM;
// mResponseHead may reference new or cached headers, but either way it
// holds our best estimate of the total content length. Even in the case
// of a byte range request, the content length stored in the cached
// response headers is what we want to use here.
PRUint32 progressMax = mResponseHead->ContentLength();
PRUint32 progress = mLogicalOffset + count;
NS_ASSERTION(progress <= progressMax, "unexpected progress values");
OnTransportStatus(nsnull, transportStatus, progress, progressMax);
// //
// we have to manually keep the logical offset of the stream up-to-date. // we have to manually keep the logical offset of the stream up-to-date.
// we cannot depend soley on the offset provided, since we may have // we cannot depend soley on the offset provided, since we may have
@ -3479,7 +3501,7 @@ nsHttpChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
mLogicalOffset, mLogicalOffset,
count); count);
if (NS_SUCCEEDED(rv)) if (NS_SUCCEEDED(rv))
mLogicalOffset += count; mLogicalOffset = progress;
return rv; return rv;
} }
@ -3502,11 +3524,8 @@ nsHttpChannel::OnTransportStatus(nsITransport *trans, nsresult status,
NS_ConvertASCIItoUCS2 host(mConnectionInfo->Host()); NS_ConvertASCIItoUCS2 host(mConnectionInfo->Host());
mProgressSink->OnStatus(this, nsnull, status, host.get()); mProgressSink->OnStatus(this, nsnull, status, host.get());
// suppress "sending to" progress event if not uploading if (progress > 0)
if (status == nsISocketTransport::STATUS_RECEIVING_FROM ||
(status == nsISocketTransport::STATUS_SENDING_TO && mUploadStream)) {
mProgressSink->OnProgress(this, nsnull, progress, progressMax); mProgressSink->OnProgress(this, nsnull, progress, progressMax);
}
} }
#ifdef DEBUG #ifdef DEBUG
else else

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

@ -122,6 +122,7 @@ nsHttpTransaction::nsHttpTransaction()
, mSentData(PR_FALSE) , mSentData(PR_FALSE)
, mReceivedData(PR_FALSE) , mReceivedData(PR_FALSE)
, mStatusEventPending(PR_FALSE) , mStatusEventPending(PR_FALSE)
, mHasRequestBody(PR_FALSE)
{ {
LOG(("Creating nsHttpTransaction @%x\n", this)); LOG(("Creating nsHttpTransaction @%x\n", this));
} }
@ -202,6 +203,8 @@ nsHttpTransaction::Init(PRUint8 caps,
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
if (requestBody) { if (requestBody) {
mHasRequestBody = PR_TRUE;
// wrap the headers and request body in a multiplexed input stream. // wrap the headers and request body in a multiplexed input stream.
nsCOMPtr<nsIMultiplexInputStream> multi = nsCOMPtr<nsIMultiplexInputStream> multi =
do_CreateInstance(kMultiplexInputStream, &rv); do_CreateInstance(kMultiplexInputStream, &rv);
@ -273,17 +276,17 @@ nsHttpTransaction::OnTransportStatus(nsresult status, PRUint32 progress)
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
// nsHttpChannel synthesizes progress events in OnDataAvailable
if (status == nsISocketTransport::STATUS_RECEIVING_FROM)
return;
PRUint32 progressMax; PRUint32 progressMax;
if (status == nsISocketTransport::STATUS_RECEIVING_FROM) { if (status == nsISocketTransport::STATUS_SENDING_TO) {
// ignore the progress argument and use our own. as a result, // suppress progress when only writing request headers
// the progress reported will not include the size of the response if (!mHasRequestBody)
// headers. this is OK b/c we only want to report the progress return;
// downloading the body of the response.
progress = mContentRead;
progressMax = mContentLength;
}
else if (status == nsISocketTransport::STATUS_SENDING_TO) {
// when uploading, we include the request headers in the progress // when uploading, we include the request headers in the progress
// notifications. // notifications.
progressMax = mRequestSize; progressMax = mRequestSize;

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

@ -178,6 +178,7 @@ private:
PRUint32 mSentData : 1; PRUint32 mSentData : 1;
PRUint32 mReceivedData : 1; PRUint32 mReceivedData : 1;
PRUint32 mStatusEventPending : 1; PRUint32 mStatusEventPending : 1;
PRUint32 mHasRequestBody : 1;
// mClosed := transaction has been explicitly closed // mClosed := transaction has been explicitly closed
// mTransactionDone := transaction ran to completion or was interrupted // mTransactionDone := transaction ran to completion or was interrupted

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

@ -61,6 +61,9 @@
#include "nsIStringBundle.h" #include "nsIStringBundle.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
#include "nsITransport.h"
#include "nsISocketTransport.h"
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
#if defined(PR_LOGGING) #if defined(PR_LOGGING)
@ -97,13 +100,14 @@ static NS_DEFINE_IID(kIContentViewerContainerIID, NS_ICONTENTVIEWERCONTAINER_II
struct nsRequestInfo : public PLDHashEntryHdr struct nsRequestInfo : public PLDHashEntryHdr
{ {
nsRequestInfo(const void *key) nsRequestInfo(const void *key)
: mKey(key), mCurrentProgress(0), mMaxProgress(0) : mKey(key), mCurrentProgress(0), mMaxProgress(0), mUploading(PR_FALSE)
{ {
} }
const void* mKey; // Must be first for the pldhash stubs to work const void* mKey; // Must be first for the pldhash stubs to work
PRInt32 mCurrentProgress; PRInt32 mCurrentProgress;
PRInt32 mMaxProgress; PRInt32 mMaxProgress;
PRBool mUploading;
}; };
@ -1006,7 +1010,8 @@ NS_IMETHODIMP nsDocLoaderImpl::OnProgress(nsIRequest *aRequest, nsISupports* ctx
// //
info = GetRequestInfo(aRequest); info = GetRequestInfo(aRequest);
if (info) { if (info) {
if ((0 == info->mCurrentProgress) && (0 == info->mMaxProgress)) { // suppress sending STATE_TRANSFERRING if this is upload progress (see bug 240053)
if (!info->mUploading && (0 == info->mCurrentProgress) && (0 == info->mMaxProgress)) {
// //
// This is the first progress notification for the entry. If // This is the first progress notification for the entry. If
// (aMaxProgress > 0) then the content-length of the data is known, // (aMaxProgress > 0) then the content-length of the data is known,
@ -1078,6 +1083,25 @@ NS_IMETHODIMP nsDocLoaderImpl::OnStatus(nsIRequest* aRequest, nsISupports* ctxt,
// Fire progress notifications out to any registered nsIWebProgressListeners // Fire progress notifications out to any registered nsIWebProgressListeners
// //
if (aStatus) { if (aStatus) {
// Remember the current status for this request
nsRequestInfo *info;
info = GetRequestInfo(aRequest);
if (info) {
PRBool uploading = (aStatus == nsITransport::STATUS_WRITING ||
aStatus == nsISocketTransport::STATUS_SENDING_TO);
// If switching from uploading to downloading (or vice versa), then we
// need to reset our progress counts. This is designed with HTTP form
// submission in mind, where an upload is performed followed by download
// of possibly several documents.
if (info->mUploading != uploading) {
mCurrentSelfProgress = mMaxSelfProgress = 0;
mCurrentTotalProgress = mMaxTotalProgress = 0;
info->mUploading = uploading;
info->mCurrentProgress = 0;
info->mMaxProgress = 0;
}
}
nsresult rv; nsresult rv;
nsCOMPtr<nsIStringBundleService> sbs = do_GetService(kStringBundleServiceCID, &rv); nsCOMPtr<nsIStringBundleService> sbs = do_GetService(kStringBundleServiceCID, &rv);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;