зеркало из https://github.com/mozilla/gecko-dev.git
Bug 712191 - Clean up websocket close codes and abort logic. r?mcmanus
This commit is contained in:
Родитель
ca650533dc
Коммит
6fbcd1727e
|
@ -728,7 +728,6 @@ WebSocketChannel::~WebSocketChannel()
|
|||
sWebSocketAdmissions->DecrementSessionCount();
|
||||
|
||||
// this stop is a nop if the normal connect/close is followed
|
||||
mStopped = 1;
|
||||
StopSession(NS_ERROR_UNEXPECTED);
|
||||
NS_ABORT_IF_FALSE(!mOpenRunning && !mOpenBlocked, "op");
|
||||
|
||||
|
@ -802,7 +801,7 @@ WebSocketChannel::BeginOpen()
|
|||
nsCOMPtr<nsIChannel> localChannel = do_QueryInterface(mChannel, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("WebSocketChannel::BeginOpen: cannot async open\n"));
|
||||
AbortSession(NS_ERROR_CONNECTION_REFUSED);
|
||||
AbortSession(NS_ERROR_UNEXPECTED);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -906,7 +905,6 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
|||
avail = count;
|
||||
} else {
|
||||
if (!UpdateReadBuffer(buffer, count, mFragmentAccumulator, &avail)) {
|
||||
AbortSession(NS_ERROR_FILE_TOO_BIG);
|
||||
return NS_ERROR_FILE_TOO_BIG;
|
||||
}
|
||||
}
|
||||
|
@ -945,7 +943,6 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
|||
// Section 4.2 says that the most significant bit MUST be
|
||||
// 0. (i.e. this is really a 63 bit value)
|
||||
LOG(("WebSocketChannel:: high bit of 64 bit length set"));
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
|
@ -962,7 +959,6 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
|||
payloadLength, avail));
|
||||
|
||||
if (payloadLength + mFragmentAccumulator > mMaxMessageSize) {
|
||||
AbortSession(NS_ERROR_FILE_TOO_BIG);
|
||||
return NS_ERROR_FILE_TOO_BIG;
|
||||
}
|
||||
|
||||
|
@ -986,13 +982,11 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
|||
// Control codes are required to have the fin bit set
|
||||
if (!finBit && (opcode & kControlFrameMask)) {
|
||||
LOG(("WebSocketChannel:: fragmented control frame code %d\n", opcode));
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
if (rsvBits) {
|
||||
LOG(("WebSocketChannel:: unexpected reserved bits %x\n", rsvBits));
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
|
@ -1003,7 +997,6 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
|||
// first frame while some old fragments are open
|
||||
if ((mFragmentAccumulator != 0) && (opcode != kContinuation)) {
|
||||
LOG(("WebSocketChannel:: nested fragments\n"));
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
|
@ -1014,7 +1007,6 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
|||
// Make sure this continuation fragment isn't the first fragment
|
||||
if (mFragmentOpcode == kContinuation) {
|
||||
LOG(("WebSocketHeandler:: continuation code in first fragment\n"));
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
|
@ -1048,7 +1040,6 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
|||
// have an open fragment.. it must be a control code or else
|
||||
// we have a problem
|
||||
LOG(("WebSocketChannel:: illegal fragment sequence\n"));
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
|
@ -1067,8 +1058,7 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
|||
// Section 8.1 says to fail connection if invalid utf-8 in text message
|
||||
if (!IsUTF8(utf8Data, false)) {
|
||||
LOG(("WebSocketChannel:: text frame invalid utf-8\n"));
|
||||
AbortSession(NS_ERROR_CANNOT_CONVERT_DATA);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
return NS_ERROR_CANNOT_CONVERT_DATA;
|
||||
}
|
||||
|
||||
NS_DispatchToMainThread(new CallOnMessageAvailable(this, utf8Data, -1));
|
||||
|
@ -1078,7 +1068,6 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
|||
if (payloadLength > 125) {
|
||||
LOG(("WebSocketChannel:: bad control frame code %d length %d\n",
|
||||
opcode, payloadLength));
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
|
@ -1103,8 +1092,7 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
|||
// inappropriate - so we will fail the connection instead.
|
||||
if (!IsUTF8(mServerCloseReason, false)) {
|
||||
LOG(("WebSocketChannel:: close frame invalid utf-8\n"));
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
return NS_ERROR_CANNOT_CONVERT_DATA;
|
||||
}
|
||||
|
||||
LOG(("WebSocketChannel:: close msg %s\n",
|
||||
|
@ -1133,7 +1121,6 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
|||
} else {
|
||||
/* unknown control frame opcode */
|
||||
LOG(("WebSocketChannel:: unknown control op code %d\n", opcode));
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
|
@ -1160,7 +1147,6 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
|||
} else if (opcode != kContinuation) {
|
||||
/* unknown opcode */
|
||||
LOG(("WebSocketChannel:: unknown op code %d\n", opcode));
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
|
@ -1181,8 +1167,7 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
|||
|
||||
if (!UpdateReadBuffer(mFramePtr - mFragmentAccumulator,
|
||||
totalAvail + mFragmentAccumulator, 0, nsnull)) {
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
return NS_ERROR_FILE_TOO_BIG;
|
||||
}
|
||||
|
||||
// UpdateReadBuffer will reset the frameptr to the beginning
|
||||
|
@ -1191,8 +1176,7 @@ WebSocketChannel::ProcessInput(PRUint8 *buffer, PRUint32 count)
|
|||
} else if (totalAvail) {
|
||||
LOG(("WebSocketChannel:: Setup Buffer due to partial frame"));
|
||||
if (!UpdateReadBuffer(mFramePtr, totalAvail, 0, nsnull)) {
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
return NS_ERROR_FILE_TOO_BIG;
|
||||
}
|
||||
}
|
||||
} else if (!mFragmentAccumulator && !totalAvail) {
|
||||
|
@ -1295,17 +1279,18 @@ WebSocketChannel::ResultToCloseCode(nsresult resultCode)
|
|||
{
|
||||
if (NS_SUCCEEDED(resultCode))
|
||||
return CLOSE_NORMAL;
|
||||
if (resultCode == NS_ERROR_FILE_TOO_BIG)
|
||||
return CLOSE_TOO_LARGE;
|
||||
if (resultCode == NS_BASE_STREAM_CLOSED ||
|
||||
resultCode == NS_ERROR_NET_TIMEOUT ||
|
||||
resultCode == NS_ERROR_CONNECTION_REFUSED) {
|
||||
return CLOSE_ABNORMAL;
|
||||
}
|
||||
if (resultCode == NS_ERROR_CANNOT_CONVERT_DATA)
|
||||
return CLOSE_INVALID_PAYLOAD;
|
||||
|
||||
return CLOSE_PROTOCOL_ERROR;
|
||||
switch (resultCode) {
|
||||
case NS_ERROR_FILE_TOO_BIG:
|
||||
case NS_ERROR_OUT_OF_MEMORY:
|
||||
return CLOSE_TOO_LARGE;
|
||||
case NS_ERROR_CANNOT_CONVERT_DATA:
|
||||
return CLOSE_INVALID_PAYLOAD;
|
||||
case NS_ERROR_UNEXPECTED:
|
||||
return CLOSE_INTERNAL_ERROR;
|
||||
default:
|
||||
return CLOSE_PROTOCOL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1414,7 +1399,7 @@ WebSocketChannel::PrimeNewOutgoingMessage()
|
|||
// TODO: bug 704447: don't block socket thread!
|
||||
rv = mCurrentOut->ConvertStreamToString();
|
||||
if (NS_FAILED(rv)) {
|
||||
AbortSession(rv);
|
||||
AbortSession(NS_ERROR_FILE_TOO_BIG);
|
||||
return;
|
||||
}
|
||||
// Now we're a binary string
|
||||
|
@ -1574,8 +1559,7 @@ WebSocketChannel::StopSession(nsresult reason)
|
|||
// normally this should be called on socket thread, but it is ok to call it
|
||||
// from OnStartRequest before the socket thread machine has gotten underway
|
||||
|
||||
NS_ABORT_IF_FALSE(mStopped,
|
||||
"stopsession() has not transitioned through abort or close");
|
||||
mStopped = 1;
|
||||
|
||||
if (!mChannelWasOpened) {
|
||||
// The HTTP channel information will never be used in this case
|
||||
|
@ -1717,7 +1701,6 @@ WebSocketChannel::ReleaseSession()
|
|||
|
||||
if (mStopped)
|
||||
return;
|
||||
mStopped = 1;
|
||||
StopSession(NS_OK);
|
||||
}
|
||||
|
||||
|
@ -2493,7 +2476,7 @@ WebSocketChannel::OnStartRequest(nsIRequest *aRequest,
|
|||
if (NS_FAILED(rv)) {
|
||||
LOG(("WebSocketChannel::OnStartRequest: "
|
||||
"HTTP response header Upgrade: websocket not found\n"));
|
||||
AbortSession(rv);
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -2517,7 +2500,7 @@ WebSocketChannel::OnStartRequest(nsIRequest *aRequest,
|
|||
if (NS_FAILED(rv)) {
|
||||
LOG(("WebSocketChannel::OnStartRequest: "
|
||||
"HTTP response header 'Connection: Upgrade' not found\n"));
|
||||
AbortSession(rv);
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -2530,7 +2513,7 @@ WebSocketChannel::OnStartRequest(nsIRequest *aRequest,
|
|||
respAccept.IsEmpty() || !respAccept.Equals(mHashedSecret)) {
|
||||
LOG(("WebSocketChannel::OnStartRequest: "
|
||||
"HTTP response header Sec-WebSocket-Accept check failed\n"));
|
||||
LOG(("WebSocketChannel::OnStartRequest: Expected %s recevied %s\n",
|
||||
LOG(("WebSocketChannel::OnStartRequest: Expected %s received %s\n",
|
||||
mHashedSecret.get(), respAccept.get()));
|
||||
AbortSession(NS_ERROR_ILLEGAL_VALUE);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
|
@ -2770,7 +2753,7 @@ WebSocketChannel::OnDataAvailable(nsIRequest *aRequest,
|
|||
PRUint8 buffer[2048];
|
||||
PRUint32 maxRead;
|
||||
PRUint32 count;
|
||||
nsresult rv;
|
||||
nsresult rv = NS_OK; // aCount always > 0, so this just avoids warning
|
||||
|
||||
while (aCount > 0) {
|
||||
if (mStopped)
|
||||
|
@ -2781,14 +2764,18 @@ WebSocketChannel::OnDataAvailable(nsIRequest *aRequest,
|
|||
LOG(("WebSocketChannel::OnDataAvailable: InflateRead read %u rv %x\n",
|
||||
count, rv));
|
||||
if (NS_FAILED(rv) || count == 0) {
|
||||
AbortSession(rv);
|
||||
AbortSession(NS_ERROR_UNEXPECTED);
|
||||
break;
|
||||
}
|
||||
|
||||
aCount -= count;
|
||||
rv = ProcessInput(buffer, count);
|
||||
if (NS_FAILED(rv)) {
|
||||
AbortSession(rv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aContext == mSocketOut) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче