mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-27 17:47:34 +09:00
[network] Add locking around access to WebSocketChannel::mPMCECompressor
This commit is contained in:
parent
d33ab5822f
commit
058e936f62
2 changed files with 49 additions and 33 deletions
|
|
@ -1191,6 +1191,7 @@ WebSocketChannel::WebSocketChannel() :
|
||||||
mBufferSize(kIncomingBufferInitialSize),
|
mBufferSize(kIncomingBufferInitialSize),
|
||||||
mCurrentOut(nullptr),
|
mCurrentOut(nullptr),
|
||||||
mCurrentOutSent(0),
|
mCurrentOutSent(0),
|
||||||
|
mCompressorMutex("WebSocketChannel::mCompressorMutex"),
|
||||||
mDynamicOutputSize(0),
|
mDynamicOutputSize(0),
|
||||||
mDynamicOutput(nullptr),
|
mDynamicOutput(nullptr),
|
||||||
mPrivateBrowsing(false),
|
mPrivateBrowsing(false),
|
||||||
|
|
@ -1627,6 +1628,7 @@ WebSocketChannel::ProcessInput(uint8_t *buffer, uint32_t count)
|
||||||
if (rsvBits) {
|
if (rsvBits) {
|
||||||
// PMCE sets RSV1 bit in the first fragment when the non-control frame
|
// PMCE sets RSV1 bit in the first fragment when the non-control frame
|
||||||
// is deflated
|
// is deflated
|
||||||
|
MutexAutoLock lock(mCompressorMutex);
|
||||||
if (mPMCECompressor && rsvBits == kRsv1Bit && mFragmentAccumulator == 0 &&
|
if (mPMCECompressor && rsvBits == kRsv1Bit && mFragmentAccumulator == 0 &&
|
||||||
!(opcode & kControlFrameMask)) {
|
!(opcode & kControlFrameMask)) {
|
||||||
mPMCECompressor->SetMessageDeflated();
|
mPMCECompressor->SetMessageDeflated();
|
||||||
|
|
@ -1700,13 +1702,15 @@ WebSocketChannel::ProcessInput(uint8_t *buffer, uint32_t count)
|
||||||
LOG(("WebSocketChannel:: ignoring read frame code %d after completion\n",
|
LOG(("WebSocketChannel:: ignoring read frame code %d after completion\n",
|
||||||
opcode));
|
opcode));
|
||||||
} else if (opcode == nsIWebSocketFrame::OPCODE_TEXT) {
|
} else if (opcode == nsIWebSocketFrame::OPCODE_TEXT) {
|
||||||
|
if (mListenerMT) {
|
||||||
|
nsCString utf8Data;
|
||||||
|
|
||||||
|
{ // lockscope
|
||||||
|
MutexAutoLock lock(mCompressorMutex);
|
||||||
bool isDeflated = mPMCECompressor && mPMCECompressor->IsMessageDeflated();
|
bool isDeflated = mPMCECompressor && mPMCECompressor->IsMessageDeflated();
|
||||||
LOG(("WebSocketChannel:: %stext frame received\n",
|
LOG(("WebSocketChannel:: %stext frame received\n",
|
||||||
isDeflated ? "deflated " : ""));
|
isDeflated ? "deflated " : ""));
|
||||||
|
|
||||||
if (mListenerMT) {
|
|
||||||
nsCString utf8Data;
|
|
||||||
|
|
||||||
if (isDeflated) {
|
if (isDeflated) {
|
||||||
rv = mPMCECompressor->Inflate(payload, payloadLength, utf8Data);
|
rv = mPMCECompressor->Inflate(payload, payloadLength, utf8Data);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
|
@ -1721,6 +1725,7 @@ WebSocketChannel::ProcessInput(uint8_t *buffer, uint32_t count)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Section 8.1 says to fail connection if invalid utf-8 in text message
|
// Section 8.1 says to fail connection if invalid utf-8 in text message
|
||||||
if (!IsUTF8(utf8Data, false)) {
|
if (!IsUTF8(utf8Data, false)) {
|
||||||
|
|
@ -1835,13 +1840,15 @@ WebSocketChannel::ProcessInput(uint8_t *buffer, uint32_t count)
|
||||||
mService->FrameReceived(mSerial, mInnerWindowID, frame.forget());
|
mService->FrameReceived(mSerial, mInnerWindowID, frame.forget());
|
||||||
}
|
}
|
||||||
} else if (opcode == nsIWebSocketFrame::OPCODE_BINARY) {
|
} else if (opcode == nsIWebSocketFrame::OPCODE_BINARY) {
|
||||||
|
if (mListenerMT) {
|
||||||
|
nsCString binaryData;
|
||||||
|
|
||||||
|
{ //lockscope
|
||||||
|
MutexAutoLock lock(mCompressorMutex);
|
||||||
bool isDeflated = mPMCECompressor && mPMCECompressor->IsMessageDeflated();
|
bool isDeflated = mPMCECompressor && mPMCECompressor->IsMessageDeflated();
|
||||||
LOG(("WebSocketChannel:: %sbinary frame received\n",
|
LOG(("WebSocketChannel:: %sbinary frame received\n",
|
||||||
isDeflated ? "deflated " : ""));
|
isDeflated ? "deflated " : ""));
|
||||||
|
|
||||||
if (mListenerMT) {
|
|
||||||
nsCString binaryData;
|
|
||||||
|
|
||||||
if (isDeflated) {
|
if (isDeflated) {
|
||||||
rv = mPMCECompressor->Inflate(payload, payloadLength, binaryData);
|
rv = mPMCECompressor->Inflate(payload, payloadLength, binaryData);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
|
@ -1856,6 +1863,7 @@ WebSocketChannel::ProcessInput(uint8_t *buffer, uint32_t count)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<WebSocketFrame> frame =
|
RefPtr<WebSocketFrame> frame =
|
||||||
mService->CreateFrameIfNeeded(finBit, rsvBit1, rsvBit2, rsvBit3,
|
mService->CreateFrameIfNeeded(finBit, rsvBit1, rsvBit2, rsvBit3,
|
||||||
|
|
@ -2156,6 +2164,7 @@ WebSocketChannel::PrimeNewOutgoingMessage()
|
||||||
}
|
}
|
||||||
|
|
||||||
// deflate the payload if PMCE is negotiated
|
// deflate the payload if PMCE is negotiated
|
||||||
|
MutexAutoLock lock(mCompressorMutex);
|
||||||
if (mPMCECompressor &&
|
if (mPMCECompressor &&
|
||||||
(msgType == kMsgTypeString || msgType == kMsgTypeBinaryString)) {
|
(msgType == kMsgTypeString || msgType == kMsgTypeBinaryString)) {
|
||||||
if (mCurrentOut->DeflatePayload(mPMCECompressor)) {
|
if (mCurrentOut->DeflatePayload(mPMCECompressor)) {
|
||||||
|
|
@ -2447,7 +2456,10 @@ WebSocketChannel::StopSession(nsresult reason)
|
||||||
mCancelable = nullptr;
|
mCancelable = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
MutexAutoLock lock(mCompressorMutex);
|
||||||
mPMCECompressor = nullptr;
|
mPMCECompressor = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (!mCalledOnStop) {
|
if (!mCalledOnStop) {
|
||||||
mCalledOnStop = 1;
|
mCalledOnStop = 1;
|
||||||
|
|
@ -2702,6 +2714,7 @@ WebSocketChannel::HandleExtensions()
|
||||||
serverMaxWindowBits = 15;
|
serverMaxWindowBits = 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MutexAutoLock lock(mCompressorMutex);
|
||||||
mPMCECompressor = new PMCECompression(clientNoContextTakeover,
|
mPMCECompressor = new PMCECompression(clientNoContextTakeover,
|
||||||
clientMaxWindowBits,
|
clientMaxWindowBits,
|
||||||
serverMaxWindowBits);
|
serverMaxWindowBits);
|
||||||
|
|
@ -3678,6 +3691,7 @@ WebSocketChannel::OnTransportAvailable(nsISocketTransport *aTransport,
|
||||||
serverMaxWindowBits = 15;
|
serverMaxWindowBits = 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MutexAutoLock lock(mCompressorMutex);
|
||||||
mPMCECompressor = new PMCECompression(serverNoContextTakeover,
|
mPMCECompressor = new PMCECompression(serverNoContextTakeover,
|
||||||
serverMaxWindowBits,
|
serverMaxWindowBits,
|
||||||
clientMaxWindowBits);
|
clientMaxWindowBits);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
#include "nsIChannelEventSink.h"
|
#include "nsIChannelEventSink.h"
|
||||||
#include "nsIHttpChannelInternal.h"
|
#include "nsIHttpChannelInternal.h"
|
||||||
#include "nsIStringStream.h"
|
#include "nsIStringStream.h"
|
||||||
|
#include "mozilla/Mutex.h"
|
||||||
#include "BaseWebSocketChannel.h"
|
#include "BaseWebSocketChannel.h"
|
||||||
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
|
|
@ -288,6 +289,7 @@ private:
|
||||||
uint32_t mHdrOutToSend;
|
uint32_t mHdrOutToSend;
|
||||||
uint8_t *mHdrOut;
|
uint8_t *mHdrOut;
|
||||||
uint8_t mOutHeader[kCopyBreak + 16];
|
uint8_t mOutHeader[kCopyBreak + 16];
|
||||||
|
Mutex mCompressorMutex;
|
||||||
nsAutoPtr<PMCECompression> mPMCECompressor;
|
nsAutoPtr<PMCECompression> mPMCECompressor;
|
||||||
uint32_t mDynamicOutputSize;
|
uint32_t mDynamicOutputSize;
|
||||||
uint8_t *mDynamicOutput;
|
uint8_t *mDynamicOutput;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue