mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 718206 fix spdy nsitransport event generation r=honzab
This commit is contained in:
parent
2ee6ccd415
commit
d336c36446
@ -851,6 +851,8 @@ SpdySession::HandleSynReply(SpdySession *self)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->mFrameDataStream->UpdateTransportReadEvents(self->mFrameDataSize);
|
||||||
|
|
||||||
if (!self->mFrameDataStream->SetFullyOpen()) {
|
if (!self->mFrameDataStream->SetFullyOpen()) {
|
||||||
// "If an endpoint receives multiple SYN_REPLY frames for the same active
|
// "If an endpoint receives multiple SYN_REPLY frames for the same active
|
||||||
// stream ID, it must drop the stream, and send a RST_STREAM for the
|
// stream ID, it must drop the stream, and send a RST_STREAM for the
|
||||||
@ -1128,6 +1130,9 @@ SpdySession::HandleHeaders(SpdySession *self)
|
|||||||
// this is actually not legal in the HTTP mapping of SPDY. All
|
// this is actually not legal in the HTTP mapping of SPDY. All
|
||||||
// headers are in the syn or syn reply. Log and ignore it.
|
// headers are in the syn or syn reply. Log and ignore it.
|
||||||
|
|
||||||
|
// in v3 this will be legal and we must remember to note
|
||||||
|
// NS_NET_STATUS_RECEIVING_FROM from it
|
||||||
|
|
||||||
LOG3(("SpdySession::HandleHeaders %p HEADERS for Stream 0x%X. "
|
LOG3(("SpdySession::HandleHeaders %p HEADERS for Stream 0x%X. "
|
||||||
"They are ignored in the HTTP/SPDY mapping.",
|
"They are ignored in the HTTP/SPDY mapping.",
|
||||||
self, streamID));
|
self, streamID));
|
||||||
@ -1148,29 +1153,6 @@ SpdySession::HandleWindowUpdate(SpdySession *self)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used for the hashtable enumeration to propogate OnTransportStatus events
|
|
||||||
struct transportStatus
|
|
||||||
{
|
|
||||||
nsITransport *transport;
|
|
||||||
nsresult status;
|
|
||||||
PRUint64 progress;
|
|
||||||
};
|
|
||||||
|
|
||||||
static PLDHashOperator
|
|
||||||
StreamTransportStatus(nsAHttpTransaction *key,
|
|
||||||
nsAutoPtr<SpdyStream> &stream,
|
|
||||||
void *closure)
|
|
||||||
{
|
|
||||||
struct transportStatus *status =
|
|
||||||
static_cast<struct transportStatus *>(closure);
|
|
||||||
|
|
||||||
stream->Transaction()->OnTransportStatus(status->transport,
|
|
||||||
status->status,
|
|
||||||
status->progress);
|
|
||||||
return PL_DHASH_NEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// nsAHttpTransaction. It is expected that nsHttpConnection is the caller
|
// nsAHttpTransaction. It is expected that nsHttpConnection is the caller
|
||||||
// of these methods
|
// of these methods
|
||||||
@ -1183,21 +1165,47 @@ SpdySession::OnTransportStatus(nsITransport* aTransport,
|
|||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
|
NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
|
||||||
|
|
||||||
// nsHttpChannel synthesizes progress events in OnDataAvailable
|
switch (aStatus) {
|
||||||
if (aStatus == nsISocketTransport::STATUS_RECEIVING_FROM)
|
// These should appear only once, deliver to the first
|
||||||
return;
|
// transaction on the session.
|
||||||
|
case NS_NET_STATUS_RESOLVING_HOST:
|
||||||
|
case NS_NET_STATUS_RESOLVED_HOST:
|
||||||
|
case NS_NET_STATUS_CONNECTING_TO:
|
||||||
|
case NS_NET_STATUS_CONNECTED_TO:
|
||||||
|
{
|
||||||
|
SpdyStream *target = mStreamIDHash.Get(1);
|
||||||
|
if (target)
|
||||||
|
target->Transaction()->OnTransportStatus(aTransport, aStatus, aProgress);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// STATUS_SENDING_TO is handled by SpdyStream
|
default:
|
||||||
if (aStatus == nsISocketTransport::STATUS_SENDING_TO)
|
// The other transport events are ignored here because there is no good
|
||||||
return;
|
// way to map them to the right transaction in spdy. Instead, the events
|
||||||
|
// are generated again from the spdy code and passed directly to the
|
||||||
|
// correct transaction.
|
||||||
|
|
||||||
struct transportStatus status;
|
// NS_NET_STATUS_SENDING_TO:
|
||||||
|
// This is generated by the socket transport when (part) of
|
||||||
status.transport = aTransport;
|
// a transaction is written out
|
||||||
status.status = aStatus;
|
//
|
||||||
status.progress = aProgress;
|
// There is no good way to map it to the right transaction in spdy,
|
||||||
|
// so it is ignored here and generated separately when the SYN_STREAM
|
||||||
|
// is sent from SpdyStream::TransmitFrame
|
||||||
|
|
||||||
mStreamTransactionHash.Enumerate(StreamTransportStatus, &status);
|
// NS_NET_STATUS_WAITING_FOR:
|
||||||
|
// Created by nsHttpConnection when the request has been totally sent.
|
||||||
|
// There is no good way to map it to the right transaction in spdy,
|
||||||
|
// so it is ignored here and generated separately when the same
|
||||||
|
// condition is complete in SpdyStream when there is no more
|
||||||
|
// request body left to be transmitted.
|
||||||
|
|
||||||
|
// NS_NET_STATUS_RECEIVING_FROM
|
||||||
|
// Generated in spdysession whenever we read a data frame or a syn_reply
|
||||||
|
// that can be attributed to a particular stream/transaction
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadSegments() is used to write data to the network. Generally, HTTP
|
// ReadSegments() is used to write data to the network. Generally, HTTP
|
||||||
@ -1675,6 +1683,7 @@ SpdySession::OnWriteSegment(char *buf,
|
|||||||
|
|
||||||
mFrameDataRead += *countWritten;
|
mFrameDataRead += *countWritten;
|
||||||
|
|
||||||
|
mFrameDataStream->UpdateTransportReadEvents(*countWritten);
|
||||||
if ((mFrameDataRead == mFrameDataSize) && !mFrameDataLast)
|
if ((mFrameDataRead == mFrameDataSize) && !mFrameDataLast)
|
||||||
ChangeDownstreamState(BUFFERING_FRAME_HEADER);
|
ChangeDownstreamState(BUFFERING_FRAME_HEADER);
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ SpdyStream::SpdyStream(nsAHttpTransaction *httpTransaction,
|
|||||||
mSentFinOnData(0),
|
mSentFinOnData(0),
|
||||||
mRecvdFin(0),
|
mRecvdFin(0),
|
||||||
mFullyOpen(0),
|
mFullyOpen(0),
|
||||||
|
mSentWaitingFor(0),
|
||||||
mTxInlineFrameAllocation(SpdySession::kDefaultBufferSize),
|
mTxInlineFrameAllocation(SpdySession::kDefaultBufferSize),
|
||||||
mTxInlineFrameSize(0),
|
mTxInlineFrameSize(0),
|
||||||
mTxInlineFrameSent(0),
|
mTxInlineFrameSent(0),
|
||||||
@ -82,7 +83,9 @@ SpdyStream::SpdyStream(nsAHttpTransaction *httpTransaction,
|
|||||||
mTxStreamFrameSent(0),
|
mTxStreamFrameSent(0),
|
||||||
mZlib(compressionContext),
|
mZlib(compressionContext),
|
||||||
mRequestBodyLen(0),
|
mRequestBodyLen(0),
|
||||||
mPriority(priority)
|
mPriority(priority),
|
||||||
|
mTotalSent(0),
|
||||||
|
mTotalRead(0)
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
|
NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
|
||||||
|
|
||||||
@ -458,6 +461,36 @@ SpdyStream::ParseHttpRequestHeaders(const char *buf,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SpdyStream::UpdateTransportReadEvents(PRUint32 count)
|
||||||
|
{
|
||||||
|
mTotalRead += count;
|
||||||
|
|
||||||
|
mTransaction->OnTransportStatus(mSocketTransport,
|
||||||
|
NS_NET_STATUS_RECEIVING_FROM,
|
||||||
|
mTotalRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SpdyStream::UpdateTransportSendEvents(PRUint32 count)
|
||||||
|
{
|
||||||
|
mTotalSent += count;
|
||||||
|
|
||||||
|
if (mUpstreamState != SENDING_FIN_STREAM)
|
||||||
|
mTransaction->OnTransportStatus(mSocketTransport,
|
||||||
|
NS_NET_STATUS_SENDING_TO,
|
||||||
|
mTotalSent);
|
||||||
|
|
||||||
|
if (!mSentWaitingFor && !mRequestBodyLen &&
|
||||||
|
mTxInlineFrameSent == mTxInlineFrameSize &&
|
||||||
|
mTxStreamFrameSent == mTxStreamFrameSize) {
|
||||||
|
mSentWaitingFor = 1;
|
||||||
|
mTransaction->OnTransportStatus(mSocketTransport,
|
||||||
|
NS_NET_STATUS_WAITING_FOR,
|
||||||
|
LL_ZERO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
SpdyStream::TransmitFrame(const char *buf,
|
SpdyStream::TransmitFrame(const char *buf,
|
||||||
PRUint32 *countUsed)
|
PRUint32 *countUsed)
|
||||||
@ -538,16 +571,11 @@ SpdyStream::TransmitFrame(const char *buf,
|
|||||||
SpdySession::LogIO(mSession, this, "Writing from Transaction Buffer",
|
SpdySession::LogIO(mSession, this, "Writing from Transaction Buffer",
|
||||||
buf + offset, transmittedCount);
|
buf + offset, transmittedCount);
|
||||||
|
|
||||||
if (mUpstreamState == SENDING_REQUEST_BODY) {
|
|
||||||
mTransaction->OnTransportStatus(mSocketTransport,
|
|
||||||
nsISocketTransport::STATUS_SENDING_TO,
|
|
||||||
transmittedCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
*countUsed += transmittedCount;
|
*countUsed += transmittedCount;
|
||||||
avail -= transmittedCount;
|
avail -= transmittedCount;
|
||||||
offset += transmittedCount;
|
offset += transmittedCount;
|
||||||
mTxStreamFrameSent += transmittedCount;
|
mTxStreamFrameSent += transmittedCount;
|
||||||
|
UpdateTransportSendEvents(transmittedCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!avail) {
|
if (!avail) {
|
||||||
|
@ -89,6 +89,9 @@ public:
|
|||||||
void SetRecvdFin(bool aStatus) { mRecvdFin = aStatus ? 1 : 0; }
|
void SetRecvdFin(bool aStatus) { mRecvdFin = aStatus ? 1 : 0; }
|
||||||
bool RecvdFin() { return mRecvdFin; }
|
bool RecvdFin() { return mRecvdFin; }
|
||||||
|
|
||||||
|
void UpdateTransportSendEvents(PRUint32 count);
|
||||||
|
void UpdateTransportReadEvents(PRUint32 count);
|
||||||
|
|
||||||
// The zlib header compression dictionary defined by SPDY,
|
// The zlib header compression dictionary defined by SPDY,
|
||||||
// and hooks to the mozilla allocator for zlib to use.
|
// and hooks to the mozilla allocator for zlib to use.
|
||||||
static const char *kDictionary;
|
static const char *kDictionary;
|
||||||
@ -171,6 +174,9 @@ private:
|
|||||||
// Flag is set after syn reply received
|
// Flag is set after syn reply received
|
||||||
PRUint32 mFullyOpen : 1;
|
PRUint32 mFullyOpen : 1;
|
||||||
|
|
||||||
|
// Flag is set after the WAITING_FOR Transport event has been generated
|
||||||
|
PRUint32 mSentWaitingFor : 1;
|
||||||
|
|
||||||
// The InlineFrame and associated data is used for composing control
|
// The InlineFrame and associated data is used for composing control
|
||||||
// frames and data frame headers.
|
// frames and data frame headers.
|
||||||
nsAutoArrayPtr<char> mTxInlineFrame;
|
nsAutoArrayPtr<char> mTxInlineFrame;
|
||||||
@ -200,6 +206,9 @@ private:
|
|||||||
// based on nsISupportsPriority definitions
|
// based on nsISupportsPriority definitions
|
||||||
PRInt32 mPriority;
|
PRInt32 mPriority;
|
||||||
|
|
||||||
|
// For Progress Events
|
||||||
|
PRUint64 mTotalSent;
|
||||||
|
PRUint64 mTotalRead;
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace mozilla::net
|
}} // namespace mozilla::net
|
||||||
|
Loading…
Reference in New Issue
Block a user