bug 672384 - WebSocket connection drops on moderately-large fragmented messages r=biesi

This commit is contained in:
Patrick McManus
2011-07-22 16:06:57 -04:00
parent aa724452f6
commit 9b26fab477
2 changed files with 19 additions and 9 deletions

View File

@@ -627,8 +627,14 @@ WebSocketChannel::IsPersistentFramePtr()
// Extends the internal buffer by count and returns the total
// amount of data available for read
//
// Accumulated fragment size is passed in instead of using the member
// variable beacuse when transitioning from the stack to the persistent
// read buffer we want to explicitly include them in the buffer instead
// of as already existing data.
PRUint32
WebSocketChannel::UpdateReadBuffer(PRUint8 *buffer, PRUint32 count)
WebSocketChannel::UpdateReadBuffer(PRUint8 *buffer, PRUint32 count,
PRUint32 accumulatedFragments)
{
LOG(("WebSocketChannel::UpdateReadBuffer() %p [%p %u]\n",
this, buffer, count));
@@ -637,16 +643,19 @@ WebSocketChannel::UpdateReadBuffer(PRUint8 *buffer, PRUint32 count)
mFramePtr = mBuffer;
NS_ABORT_IF_FALSE(IsPersistentFramePtr(), "update read buffer bad mFramePtr");
NS_ABORT_IF_FALSE(mFramePtr - accumulatedFragments >= mBuffer,
"reserved FramePtr bad");
if (mBuffered + count <= mBufferSize) {
// append to existing buffer
LOG(("WebSocketChannel: update read buffer absorbed %u\n", count));
} else if (mBuffered + count - (mFramePtr - mBuffer) <= mBufferSize) {
} else if (mBuffered + count -
(mFramePtr - accumulatedFragments - mBuffer) <= mBufferSize) {
// make room in existing buffer by shifting unused data to start
mBuffered -= (mFramePtr - mBuffer);
mBuffered -= (mFramePtr - mBuffer - accumulatedFragments);
LOG(("WebSocketChannel: update read buffer shifted %u\n", mBuffered));
::memmove(mBuffer, mFramePtr, mBuffered);
mFramePtr = mBuffer;
::memmove(mBuffer, mFramePtr - accumulatedFragments, mBuffered);
mFramePtr = mBuffer + accumulatedFragments;
} else {
// existing buffer is not sufficient, extend it
mBufferSize += count + 8192;
@@ -686,7 +695,7 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
mFramePtr = buffer;
avail = count;
} else {
avail = UpdateReadBuffer(buffer, count);
avail = UpdateReadBuffer(buffer, count, mFragmentAccumulator);
}
PRUint8 *payload;
@@ -945,14 +954,14 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
LOG(("WebSocketChannel:: Setup Buffer due to fragment"));
UpdateReadBuffer(mFramePtr - mFragmentAccumulator,
totalAvail + mFragmentAccumulator);
totalAvail + mFragmentAccumulator, 0);
// UpdateReadBuffer will reset the frameptr to the beginning
// of new saved state, so we need to skip past processed framgents
mFramePtr += mFragmentAccumulator;
} else if (totalAvail) {
LOG(("WebSocketChannel:: Setup Buffer due to partial frame"));
UpdateReadBuffer(mFramePtr, totalAvail);
UpdateReadBuffer(mFramePtr, totalAvail, 0);
}
} else if (!mFragmentAccumulator && !totalAvail) {
// If we were working off a saved buffer state and there is no partial