mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +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