зеркало из https://github.com/mozilla/pjs.git
bug 671875 pipeline transport event fixups r=honzab
This commit is contained in:
Родитель
e3abab38ee
Коммит
7927a9bae0
|
@ -124,6 +124,10 @@ public:
|
|||
// Transfer the base http connection object along with a
|
||||
// reference to it to the caller.
|
||||
virtual nsHttpConnection *TakeHttpConnection() = 0;
|
||||
|
||||
// Get the nsISocketTransport used by the connection without changing
|
||||
// references or ownership.
|
||||
virtual nsISocketTransport *Transport() = 0;
|
||||
};
|
||||
|
||||
#define NS_DECL_NSAHTTPCONNECTION \
|
||||
|
@ -141,6 +145,7 @@ public:
|
|||
nsresult PushBack(const char *, PRUint32); \
|
||||
bool LastTransactionExpectedNoContent(); \
|
||||
void SetLastTransactionExpectedNoContent(bool); \
|
||||
nsHttpConnection *TakeHttpConnection();
|
||||
nsHttpConnection *TakeHttpConnection(); \
|
||||
nsISocketTransport *Transport();
|
||||
|
||||
#endif // nsAHttpConnection_h__
|
||||
|
|
|
@ -123,6 +123,7 @@ public:
|
|||
mLastTransactionExpectedNoContent = val;
|
||||
}
|
||||
|
||||
nsISocketTransport *Transport() { return mSocketTransport; }
|
||||
nsAHttpTransaction *Transaction() { return mTransaction; }
|
||||
nsHttpConnectionInfo *ConnectionInfo() { return mConnInfo; }
|
||||
|
||||
|
|
|
@ -1693,3 +1693,11 @@ nsConnectionHandle::SetLastTransactionExpectedNoContent(bool val)
|
|||
{
|
||||
mConn->SetLastTransactionExpectedNoContent(val);
|
||||
}
|
||||
|
||||
nsISocketTransport *
|
||||
nsHttpConnectionMgr::nsConnectionHandle::Transport()
|
||||
{
|
||||
if (!mConn)
|
||||
return nsnull;
|
||||
return mConn->Transport();
|
||||
}
|
||||
|
|
|
@ -101,6 +101,9 @@ nsHttpPipeline::nsHttpPipeline()
|
|||
, mPushBackBuf(nsnull)
|
||||
, mPushBackLen(0)
|
||||
, mPushBackMax(0)
|
||||
, mReceivingFromProgress(0)
|
||||
, mSendingToProgress(0)
|
||||
, mSuppressSendEvents(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -325,6 +328,14 @@ nsHttpPipeline::TakeHttpConnection()
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
nsISocketTransport *
|
||||
nsHttpPipeline::Transport()
|
||||
{
|
||||
if (!mConnection)
|
||||
return nsnull;
|
||||
return mConnection->Transport();
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpPipeline::SetSSLConnectFailed()
|
||||
{
|
||||
|
@ -390,21 +401,80 @@ nsHttpPipeline::OnTransportStatus(nsITransport* transport,
|
|||
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
|
||||
|
||||
nsAHttpTransaction *trans;
|
||||
PRInt32 i, count;
|
||||
|
||||
switch (status) {
|
||||
case NS_NET_STATUS_RECEIVING_FROM:
|
||||
// forward this only to the transaction currently recieving data
|
||||
trans = Response(0);
|
||||
|
||||
case NS_NET_STATUS_RESOLVING_HOST:
|
||||
case NS_NET_STATUS_RESOLVED_HOST:
|
||||
case NS_NET_STATUS_CONNECTING_TO:
|
||||
case NS_NET_STATUS_CONNECTED_TO:
|
||||
// These should only appear at most once per pipeline.
|
||||
// Deliver to the first transaction.
|
||||
|
||||
trans = Request(0);
|
||||
if (!trans)
|
||||
trans = Response(0);
|
||||
if (trans)
|
||||
trans->OnTransportStatus(transport, status, progress);
|
||||
|
||||
break;
|
||||
default:
|
||||
// forward other notifications to all transactions
|
||||
PRInt32 i, count = mRequestQ.Length();
|
||||
for (i=0; i<count; ++i) {
|
||||
trans = Request(i);
|
||||
if (trans)
|
||||
trans->OnTransportStatus(transport, status, progress);
|
||||
|
||||
case NS_NET_STATUS_SENDING_TO:
|
||||
// This is generated by the socket transport when (part) of
|
||||
// a transaction is written out
|
||||
//
|
||||
// In pipelining this is generated out of FillSendBuf(), but it cannot do
|
||||
// so until the connection is confirmed by CONNECTED_TO.
|
||||
// See patch for bug 196827.
|
||||
//
|
||||
|
||||
if (mSuppressSendEvents) {
|
||||
mSuppressSendEvents = false;
|
||||
|
||||
// catch up by sending the event to all the transactions that have
|
||||
// moved from request to response and any that have been partially
|
||||
// sent. Also send WAITING_FOR to those that were completely sent
|
||||
count = mResponseQ.Length();
|
||||
for (i = 0; i < count; ++i) {
|
||||
Response(i)->OnTransportStatus(transport,
|
||||
NS_NET_STATUS_SENDING_TO,
|
||||
progress);
|
||||
Response(i)->OnTransportStatus(transport,
|
||||
NS_NET_STATUS_WAITING_FOR,
|
||||
progress);
|
||||
}
|
||||
if (mRequestIsPartial && Request(0))
|
||||
Request(0)->OnTransportStatus(transport,
|
||||
NS_NET_STATUS_SENDING_TO,
|
||||
progress);
|
||||
mSendingToProgress = progress;
|
||||
}
|
||||
// otherwise ignore it
|
||||
break;
|
||||
|
||||
case NS_NET_STATUS_WAITING_FOR:
|
||||
// Created by nsHttpConnection when request pipeline has been totally
|
||||
// sent. Ignore it here because it is simulated in FillSendBuf() when
|
||||
// a request is moved from request to response.
|
||||
|
||||
// ignore it
|
||||
break;
|
||||
|
||||
case NS_NET_STATUS_RECEIVING_FROM:
|
||||
// Forward this only to the transaction currently recieving data. It is
|
||||
// normally generated by the socket transport, but can also
|
||||
// be repeated by the pushbackwriter if necessary.
|
||||
mReceivingFromProgress = progress;
|
||||
if (Response(0))
|
||||
Response(0)->OnTransportStatus(transport, status, progress);
|
||||
break;
|
||||
|
||||
default:
|
||||
// forward other notifications to all request transactions
|
||||
count = mRequestQ.Length();
|
||||
for (i = 0; i < count; ++i)
|
||||
Request(i)->OnTransportStatus(transport, status, progress);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -548,6 +618,16 @@ nsHttpPipeline::WriteSegments(nsAHttpSegmentWriter *writer,
|
|||
nsHttpPushBackWriter writer(mPushBackBuf, mPushBackLen);
|
||||
PRUint32 len = mPushBackLen, n;
|
||||
mPushBackLen = 0;
|
||||
|
||||
// This progress notification has previously been sent from
|
||||
// the socket transport code, but it was delivered to the
|
||||
// previous transaction on the pipeline.
|
||||
nsITransport *transport = Transport();
|
||||
if (transport)
|
||||
OnTransportStatus(transport,
|
||||
nsISocketTransport::STATUS_RECEIVING_FROM,
|
||||
mReceivingFromProgress);
|
||||
|
||||
// the push back buffer is never larger than NS_HTTP_SEGMENT_SIZE,
|
||||
// so we are guaranteed that the next response will eat the entire
|
||||
// push back buffer (even though it might again call PushBack).
|
||||
|
@ -638,6 +718,8 @@ nsHttpPipeline::FillSendBuf()
|
|||
|
||||
PRUint32 n, avail;
|
||||
nsAHttpTransaction *trans;
|
||||
nsITransport *transport = Transport();
|
||||
|
||||
while ((trans = Request(0)) != nsnull) {
|
||||
avail = trans->Available();
|
||||
if (avail) {
|
||||
|
@ -648,13 +730,29 @@ nsHttpPipeline::FillSendBuf()
|
|||
LOG(("send pipe is full"));
|
||||
break;
|
||||
}
|
||||
|
||||
mSendingToProgress += n;
|
||||
if (!mSuppressSendEvents && transport) {
|
||||
// Simulate a SENDING_TO event
|
||||
trans->OnTransportStatus(transport,
|
||||
NS_NET_STATUS_SENDING_TO,
|
||||
mSendingToProgress);
|
||||
}
|
||||
}
|
||||
|
||||
avail = trans->Available();
|
||||
if (avail == 0) {
|
||||
// move transaction from request queue to response queue
|
||||
mRequestQ.RemoveElementAt(0);
|
||||
mResponseQ.AppendElement(trans);
|
||||
mRequestIsPartial = false;
|
||||
|
||||
if (!mSuppressSendEvents && transport) {
|
||||
// Simulate a WAITING_FOR event
|
||||
trans->OnTransportStatus(transport,
|
||||
NS_NET_STATUS_WAITING_FOR,
|
||||
mSendingToProgress);
|
||||
}
|
||||
}
|
||||
else
|
||||
mRequestIsPartial = true;
|
||||
|
|
|
@ -111,6 +111,11 @@ private:
|
|||
char *mPushBackBuf;
|
||||
PRUint32 mPushBackLen;
|
||||
PRUint32 mPushBackMax;
|
||||
|
||||
// For support of OnTransportStatus()
|
||||
PRUint64 mReceivingFromProgress;
|
||||
PRUint64 mSendingToProgress;
|
||||
bool mSuppressSendEvents;
|
||||
};
|
||||
|
||||
#endif // nsHttpPipeline_h__
|
||||
|
|
Загрузка…
Ссылка в новой задаче