Bug 1675207 - Fail the websocket connection when there is no enough memory r=necko-reviewers,valentin

Differential Revision: https://phabricator.services.mozilla.com/D99145
This commit is contained in:
Kershaw Chang
2020-12-11 09:35:05 +00:00
parent 514bb94009
commit 2cffa76813
5 changed files with 62 additions and 7 deletions

View File

@@ -860,6 +860,23 @@ WebSocketImpl::OnServerClose(nsISupports* aContext, uint16_t aCode,
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
WebSocketImpl::OnError() {
if (!IsTargetThread()) {
return Dispatch(
NS_NewRunnableFunction("dom::FailConnectionRunnable",
[self = RefPtr{this}]() {
self->FailConnection(
nsIWebSocketChannel::CLOSE_ABNORMAL);
}),
NS_DISPATCH_NORMAL);
}
AssertIsOnTargetThread();
FailConnection(nsIWebSocketChannel::CLOSE_ABNORMAL);
return NS_OK;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// WebSocketImpl::nsIInterfaceRequestor // WebSocketImpl::nsIInterfaceRequestor
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@@ -294,22 +294,44 @@ class MessageEvent : public WebSocketEvent {
bool mBinary; bool mBinary;
}; };
void WebSocketChannelChild::RecvOnMessageAvailableInternal( bool WebSocketChannelChild::RecvOnMessageAvailableInternal(
const nsDependentCSubstring& aMsg, bool aMoreData, bool aBinary) { const nsDependentCSubstring& aMsg, bool aMoreData, bool aBinary) {
if (aMoreData) { if (aMoreData) {
mReceivedMsgBuffer.Append(aMsg); return mReceivedMsgBuffer.Append(aMsg, fallible);
return; }
if (!mReceivedMsgBuffer.Append(aMsg, fallible)) {
return false;
} }
mReceivedMsgBuffer.Append(aMsg);
mEventQ->RunOrEnqueue(new EventTargetDispatcher( mEventQ->RunOrEnqueue(new EventTargetDispatcher(
this, new MessageEvent(mReceivedMsgBuffer, aBinary), mTargetThread)); this, new MessageEvent(mReceivedMsgBuffer, aBinary), mTargetThread));
mReceivedMsgBuffer.Truncate(); mReceivedMsgBuffer.Truncate();
return true;
}
class ErrorEvent : public WebSocketEvent {
public:
ErrorEvent() = default;
void Run(WebSocketChannelChild* aChild) override { aChild->OnError(); }
};
void WebSocketChannelChild::OnError() {
LOG(("WebSocketChannelChild::OnError() %p", this));
if (mListenerMT) {
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
Unused << mListenerMT->mListener->OnError();
}
} }
mozilla::ipc::IPCResult WebSocketChannelChild::RecvOnMessageAvailable( mozilla::ipc::IPCResult WebSocketChannelChild::RecvOnMessageAvailable(
const nsDependentCSubstring& aMsg, const bool& aMoreData) { const nsDependentCSubstring& aMsg, const bool& aMoreData) {
RecvOnMessageAvailableInternal(aMsg, aMoreData, false); if (!RecvOnMessageAvailableInternal(aMsg, aMoreData, false)) {
LOG(("WebSocketChannelChild %p append message failed", this));
mEventQ->RunOrEnqueue(
new EventTargetDispatcher(this, new ErrorEvent(), mTargetThread));
}
return IPC_OK(); return IPC_OK();
} }
@@ -331,7 +353,11 @@ void WebSocketChannelChild::OnMessageAvailable(const nsCString& aMsg) {
mozilla::ipc::IPCResult WebSocketChannelChild::RecvOnBinaryMessageAvailable( mozilla::ipc::IPCResult WebSocketChannelChild::RecvOnBinaryMessageAvailable(
const nsDependentCSubstring& aMsg, const bool& aMoreData) { const nsDependentCSubstring& aMsg, const bool& aMoreData) {
RecvOnMessageAvailableInternal(aMsg, aMoreData, true); if (!RecvOnMessageAvailableInternal(aMsg, aMoreData, true)) {
LOG(("WebSocketChannelChild %p append message failed", this));
mEventQ->RunOrEnqueue(
new EventTargetDispatcher(this, new ErrorEvent(), mTargetThread));
}
return IPC_OK(); return IPC_OK();
} }

View File

@@ -82,9 +82,11 @@ class WebSocketChannelChild final : public BaseWebSocketChannel,
// This function tries to get a labeled event target for |mNeckoTarget|. // This function tries to get a labeled event target for |mNeckoTarget|.
void SetupNeckoTarget(); void SetupNeckoTarget();
void RecvOnMessageAvailableInternal(const nsDependentCSubstring& aMsg, bool RecvOnMessageAvailableInternal(const nsDependentCSubstring& aMsg,
bool aMoreData, bool aBinary); bool aMoreData, bool aBinary);
void OnError();
RefPtr<ChannelEventQueue> mEventQ; RefPtr<ChannelEventQueue> mEventQ;
nsString mEffectiveURL; nsString mEffectiveURL;
nsCString mReceivedMsgBuffer; nsCString mReceivedMsgBuffer;
@@ -100,6 +102,7 @@ class WebSocketChannelChild final : public BaseWebSocketChannel,
friend class AcknowledgeEvent; friend class AcknowledgeEvent;
friend class ServerCloseEvent; friend class ServerCloseEvent;
friend class AsyncOpenFailedEvent; friend class AsyncOpenFailedEvent;
friend class ErrorEvent;
}; };
} // namespace net } // namespace net

View File

@@ -307,6 +307,9 @@ WebSocketChannelParent::OnServerClose(nsISupports* aContext, uint16_t code,
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
WebSocketChannelParent::OnError() { return NS_OK; }
void WebSocketChannelParent::ActorDestroy(ActorDestroyReason why) { void WebSocketChannelParent::ActorDestroy(ActorDestroyReason why) {
LOG(("WebSocketChannelParent::ActorDestroy() %p\n", this)); LOG(("WebSocketChannelParent::ActorDestroy() %p\n", this));

View File

@@ -85,6 +85,12 @@ interface nsIWebSocketListener : nsISupports
in unsigned short aCode, in unsigned short aCode,
in AUTF8String aReason); in AUTF8String aReason);
/**
* Called to inform an error is happened. The connection will be closed
* when this is called.
*/
[must_use] void OnError();
}; };