mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-28 13:16:41 +00:00
xbmc: add PR2353
Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
parent
107e046f43
commit
04102ad874
309
packages/mediacenter/xbmc/patches/xbmc-990.16-PR2353.patch
Normal file
309
packages/mediacenter/xbmc/patches/xbmc-990.16-PR2353.patch
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
From 0a2c144355ed750e61fadabe2dde185a76064f0a Mon Sep 17 00:00:00 2001
|
||||||
|
From: montellese <montellese@xbmc.org>
|
||||||
|
Date: Fri, 1 Mar 2013 17:53:54 +0100
|
||||||
|
Subject: [PATCH] websocket: fix inability to handle multiple queued websocket
|
||||||
|
frames/messages (fixes #13848)
|
||||||
|
|
||||||
|
---
|
||||||
|
xbmc/network/TCPServer.cpp | 31 +++---
|
||||||
|
xbmc/network/websocket/WebSocket.cpp | 174 +++++++++++++++++++---------------
|
||||||
|
xbmc/network/websocket/WebSocket.h | 2 +-
|
||||||
|
3 files changed, 114 insertions(+), 93 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/xbmc/network/TCPServer.cpp b/xbmc/network/TCPServer.cpp
|
||||||
|
index 2d9fde0..e4b5984 100644
|
||||||
|
--- a/xbmc/network/TCPServer.cpp
|
||||||
|
+++ b/xbmc/network/TCPServer.cpp
|
||||||
|
@@ -654,23 +654,28 @@ void CTCPServer::CWebSocketClient::Send(const char *data, unsigned int size)
|
||||||
|
void CTCPServer::CWebSocketClient::PushBuffer(CTCPServer *host, const char *buffer, int length)
|
||||||
|
{
|
||||||
|
bool send;
|
||||||
|
- const CWebSocketMessage *msg;
|
||||||
|
- if ((msg = m_websocket->Handle(buffer, length, send)) != NULL && msg->IsComplete())
|
||||||
|
+ const CWebSocketMessage *msg = NULL;
|
||||||
|
+ size_t len = length;
|
||||||
|
+ do
|
||||||
|
{
|
||||||
|
- std::vector<const CWebSocketFrame *> frames = msg->GetFrames();
|
||||||
|
- if (send)
|
||||||
|
- {
|
||||||
|
- for (unsigned int index = 0; index < frames.size(); index++)
|
||||||
|
- Send(frames.at(index)->GetFrameData(), (unsigned int)frames.at(index)->GetFrameLength());
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
+ if ((msg = m_websocket->Handle(buffer, len, send)) != NULL && msg->IsComplete())
|
||||||
|
{
|
||||||
|
- for (unsigned int index = 0; index < frames.size(); index++)
|
||||||
|
- CTCPClient::PushBuffer(host, frames.at(index)->GetApplicationData(), (int)frames.at(index)->GetLength());
|
||||||
|
- }
|
||||||
|
+ std::vector<const CWebSocketFrame *> frames = msg->GetFrames();
|
||||||
|
+ if (send)
|
||||||
|
+ {
|
||||||
|
+ for (unsigned int index = 0; index < frames.size(); index++)
|
||||||
|
+ Send(frames.at(index)->GetFrameData(), (unsigned int)frames.at(index)->GetFrameLength());
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ for (unsigned int index = 0; index < frames.size(); index++)
|
||||||
|
+ CTCPClient::PushBuffer(host, frames.at(index)->GetApplicationData(), (int)frames.at(index)->GetLength());
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- delete msg;
|
||||||
|
+ delete msg;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+ while (len > 0 && msg != NULL);
|
||||||
|
|
||||||
|
if (m_websocket->GetState() == WebSocketStateClosed)
|
||||||
|
Disconnect();
|
||||||
|
diff --git a/xbmc/network/websocket/WebSocket.cpp b/xbmc/network/websocket/WebSocket.cpp
|
||||||
|
index 94e7ab0..5008073 100644
|
||||||
|
--- a/xbmc/network/websocket/WebSocket.cpp
|
||||||
|
+++ b/xbmc/network/websocket/WebSocket.cpp
|
||||||
|
@@ -80,11 +80,11 @@
|
||||||
|
// Get the MASK flag
|
||||||
|
m_masked = ((m_data[1] & MASK_MASK) == MASK_MASK);
|
||||||
|
|
||||||
|
- // Get the playload length
|
||||||
|
+ // Get the payload length
|
||||||
|
m_length = (uint64_t)(m_data[1] & MASK_LENGTH);
|
||||||
|
- if ((m_length <= 125 && length < m_length + LENGTH_MIN) ||
|
||||||
|
- (m_length == 126 && length < LENGTH_MIN + 2) ||
|
||||||
|
- (m_length == 127 && length < LENGTH_MIN + 8))
|
||||||
|
+ if ((m_length <= 125 && m_lengthFrame < m_length + LENGTH_MIN) ||
|
||||||
|
+ (m_length == 126 && m_lengthFrame < LENGTH_MIN + 2) ||
|
||||||
|
+ (m_length == 127 && m_lengthFrame < LENGTH_MIN + 8))
|
||||||
|
{
|
||||||
|
CLog::Log(LOGINFO, "WebSocket: Frame with invalid length received");
|
||||||
|
reset();
|
||||||
|
@@ -110,7 +110,7 @@
|
||||||
|
offset = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (length < LENGTH_MIN + offset + m_length)
|
||||||
|
+ if (m_lengthFrame < LENGTH_MIN + offset + m_length)
|
||||||
|
{
|
||||||
|
CLog::Log(LOGINFO, "WebSocket: Frame with invalid length received");
|
||||||
|
reset();
|
||||||
|
@@ -124,12 +124,8 @@
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (length != LENGTH_MIN + offset + m_length)
|
||||||
|
- {
|
||||||
|
- CLog::Log(LOGINFO, "WebSocket: Frame with invalid length received");
|
||||||
|
- reset();
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
+ if (m_lengthFrame != LENGTH_MIN + offset + m_length)
|
||||||
|
+ m_lengthFrame = LENGTH_MIN + offset + m_length;
|
||||||
|
|
||||||
|
// Get application data
|
||||||
|
if (m_length > 0)
|
||||||
|
@@ -305,102 +301,122 @@ void CWebSocketMessage::Clear()
|
||||||
|
m_frames.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
-const CWebSocketMessage* CWebSocket::Handle(const char *buffer, size_t length, bool &send)
|
||||||
|
+const CWebSocketMessage* CWebSocket::Handle(const char* &buffer, size_t &length, bool &send)
|
||||||
|
{
|
||||||
|
send = false;
|
||||||
|
|
||||||
|
- switch (m_state)
|
||||||
|
+ while (length > 0)
|
||||||
|
{
|
||||||
|
- case WebSocketStateConnected:
|
||||||
|
+ switch (m_state)
|
||||||
|
{
|
||||||
|
- CWebSocketFrame *frame = GetFrame(buffer, length);
|
||||||
|
- if (!frame->IsValid())
|
||||||
|
+ case WebSocketStateConnected:
|
||||||
|
{
|
||||||
|
- CLog::Log(LOGINFO, "WebSocket: Invalid frame received");
|
||||||
|
- delete frame;
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (frame->IsControlFrame())
|
||||||
|
- {
|
||||||
|
- if (!frame->IsFinal())
|
||||||
|
+ CWebSocketFrame *frame = GetFrame(buffer, length);
|
||||||
|
+ if (!frame->IsValid())
|
||||||
|
{
|
||||||
|
+ CLog::Log(LOGINFO, "WebSocket: Invalid frame received");
|
||||||
|
delete frame;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- CWebSocketMessage *msg = NULL;
|
||||||
|
- switch (frame->GetOpcode())
|
||||||
|
+ // adjust the length and the buffer values
|
||||||
|
+ length -= frame->GetFrameLength();
|
||||||
|
+ buffer += frame->GetFrameLength();
|
||||||
|
+
|
||||||
|
+ if (frame->IsControlFrame())
|
||||||
|
{
|
||||||
|
- case WebSocketPing:
|
||||||
|
- msg = GetMessage();
|
||||||
|
- if (msg != NULL)
|
||||||
|
- msg->AddFrame(Pong(frame->GetApplicationData()));
|
||||||
|
- break;
|
||||||
|
+ if (!frame->IsFinal())
|
||||||
|
+ {
|
||||||
|
+ delete frame;
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ CWebSocketMessage *msg = NULL;
|
||||||
|
+ switch (frame->GetOpcode())
|
||||||
|
+ {
|
||||||
|
+ case WebSocketPing:
|
||||||
|
+ msg = GetMessage();
|
||||||
|
+ if (msg != NULL)
|
||||||
|
+ msg->AddFrame(Pong(frame->GetApplicationData()));
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
- case WebSocketConnectionClose:
|
||||||
|
- CLog::Log(LOGINFO, "WebSocket: connection closed by client");
|
||||||
|
-
|
||||||
|
- msg = GetMessage();
|
||||||
|
- if (msg != NULL)
|
||||||
|
- msg->AddFrame(Close());
|
||||||
|
-
|
||||||
|
- m_state = WebSocketStateClosed;
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- case WebSocketContinuationFrame:
|
||||||
|
- case WebSocketTextFrame:
|
||||||
|
- case WebSocketBinaryFrame:
|
||||||
|
- case WebSocketPong:
|
||||||
|
- case WebSocketUnknownFrame:
|
||||||
|
- default:
|
||||||
|
- break;
|
||||||
|
+ case WebSocketConnectionClose:
|
||||||
|
+ CLog::Log(LOGINFO, "WebSocket: connection closed by client");
|
||||||
|
+
|
||||||
|
+ msg = GetMessage();
|
||||||
|
+ if (msg != NULL)
|
||||||
|
+ msg->AddFrame(Close());
|
||||||
|
+
|
||||||
|
+ m_state = WebSocketStateClosed;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case WebSocketContinuationFrame:
|
||||||
|
+ case WebSocketTextFrame:
|
||||||
|
+ case WebSocketBinaryFrame:
|
||||||
|
+ case WebSocketPong:
|
||||||
|
+ case WebSocketUnknownFrame:
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ delete frame;
|
||||||
|
+
|
||||||
|
+ if (msg != NULL)
|
||||||
|
+ send = true;
|
||||||
|
+
|
||||||
|
+ return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
- delete frame;
|
||||||
|
+ if (m_message == NULL && (m_message = GetMessage()) == NULL)
|
||||||
|
+ {
|
||||||
|
+ CLog::Log(LOGINFO, "WebSocket: Could not allocate a new websocket message");
|
||||||
|
+ delete frame;
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (msg != NULL)
|
||||||
|
- send = true;
|
||||||
|
+ m_message->AddFrame(frame);
|
||||||
|
+ if (!m_message->IsComplete())
|
||||||
|
+ {
|
||||||
|
+ if (length > 0)
|
||||||
|
+ continue;
|
||||||
|
+ else
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+ CWebSocketMessage *msg = m_message;
|
||||||
|
+ m_message = NULL;
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (m_message == NULL && (m_message = GetMessage()) == NULL)
|
||||||
|
+ case WebSocketStateClosing:
|
||||||
|
{
|
||||||
|
- CLog::Log(LOGINFO, "WebSocket: Could not allocate a new websocket message");
|
||||||
|
- delete frame;
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
+ CWebSocketFrame *frame = GetFrame(buffer, length);
|
||||||
|
|
||||||
|
- m_message->AddFrame(frame);
|
||||||
|
- if (!m_message->IsComplete())
|
||||||
|
- return NULL;
|
||||||
|
+ if (frame->IsValid())
|
||||||
|
+ {
|
||||||
|
+ // adjust the length and the buffer values
|
||||||
|
+ length -= frame->GetFrameLength();
|
||||||
|
+ buffer += frame->GetFrameLength();
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- CWebSocketMessage *msg = m_message;
|
||||||
|
- m_message = NULL;
|
||||||
|
- return msg;
|
||||||
|
- }
|
||||||
|
+ if (!frame->IsValid() || frame->GetOpcode() == WebSocketConnectionClose)
|
||||||
|
+ {
|
||||||
|
+ CLog::Log(LOGINFO, "WebSocket: Invalid or unexpected frame received (only closing handshake expected)");
|
||||||
|
+ delete frame;
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- case WebSocketStateClosing:
|
||||||
|
- {
|
||||||
|
- CWebSocketFrame *frame = GetFrame(buffer, length);
|
||||||
|
- if (!frame->IsValid() || frame->GetOpcode() == WebSocketConnectionClose)
|
||||||
|
- {
|
||||||
|
- CLog::Log(LOGINFO, "WebSocket: Invalid or unexpected frame received (only closing handshake expected)");
|
||||||
|
- delete frame;
|
||||||
|
+ m_state = WebSocketStateClosed;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- m_state = WebSocketStateClosed;
|
||||||
|
- return NULL;
|
||||||
|
+ case WebSocketStateNotConnected:
|
||||||
|
+ case WebSocketStateClosed:
|
||||||
|
+ case WebSocketStateHandshaking:
|
||||||
|
+ default:
|
||||||
|
+ CLog::Log(LOGINFO, "WebSocket: No frame expected in the current state");
|
||||||
|
+ return NULL;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- case WebSocketStateNotConnected:
|
||||||
|
- case WebSocketStateClosed:
|
||||||
|
- case WebSocketStateHandshaking:
|
||||||
|
- default:
|
||||||
|
- CLog::Log(LOGINFO, "WebSocket: No frame expected in the current state");
|
||||||
|
- return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
diff --git a/xbmc/network/websocket/WebSocket.h b/xbmc/network/websocket/WebSocket.h
|
||||||
|
index bbfaa89..e0d3cae 100644
|
||||||
|
--- a/xbmc/network/websocket/WebSocket.h
|
||||||
|
+++ b/xbmc/network/websocket/WebSocket.h
|
||||||
|
@@ -122,7 +122,7 @@ class CWebSocket
|
||||||
|
WebSocketState GetState() { return m_state; }
|
||||||
|
|
||||||
|
virtual bool Handshake(const char* data, size_t length, std::string &response) = 0;
|
||||||
|
- virtual const CWebSocketMessage* Handle(const char *buffer, size_t length, bool &send);
|
||||||
|
+ virtual const CWebSocketMessage* Handle(const char* &buffer, size_t &length, bool &send);
|
||||||
|
virtual const CWebSocketMessage* Send(WebSocketFrameOpcode opcode, const char* data = NULL, uint32_t length = 0);
|
||||||
|
virtual const CWebSocketFrame* Ping(const char* data = NULL) const = 0;
|
||||||
|
virtual const CWebSocketFrame* Pong(const char* data = NULL) const = 0;
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user