diff --git a/websocket/api/api.script_api b/websocket/api/api.script_api index 5e5bd7f..f79b776 100644 --- a/websocket/api/api.script_api +++ b/websocket/api/api.script_api @@ -19,7 +19,11 @@ members: - name: timeout type: number - desc: Timeout for the connection sequence (milliseconds). Default: 3000 + desc: Timeout for the connection sequence (milliseconds). Not used on HTML5. Default: 3000 + + - name: headers + type: string + desc: list of http headers. Each pair is separated with "\r\n". Not used on HTML5. - name: callback type: function @@ -83,7 +87,10 @@ function init(self) self.url = "ws://echo.websocket.org" - local params = {} + local params = { + timeout = 3000, + headers = "Sec-WebSocket-Protocol: chat\r\nOrigin: mydomain.com\r\n" + } self.connection = websocket.connect(self.url, params, websocket_callback) end diff --git a/websocket/src/handshake.cpp b/websocket/src/handshake.cpp index 2a6302b..c545ce9 100644 --- a/websocket/src/handshake.cpp +++ b/websocket/src/handshake.cpp @@ -54,9 +54,17 @@ static Result SendClientHandshakeHeaders(WebsocketConnection* conn) WS_SENDALL("\r\n"); WS_SENDALL("Sec-WebSocket-Version: 13\r\n"); - // Add custom protocols - - // Add custom headers + if (conn->m_CustomHeaders) + { + WS_SENDALL(conn->m_CustomHeaders); + // make sure we ended with '\r\n' + int len = strlen(conn->m_CustomHeaders); + bool ended_with_sentinel = len >= 2 && conn->m_CustomHeaders[len - 2] == '\r' && conn->m_CustomHeaders[len - 1] == '\n'; + if (!ended_with_sentinel) + { + WS_SENDALL("\r\n"); + } + } WS_SENDALL("\r\n"); diff --git a/websocket/src/websocket.cpp b/websocket/src/websocket.cpp index 651a79c..38ab469 100644 --- a/websocket/src/websocket.cpp +++ b/websocket/src/websocket.cpp @@ -211,6 +211,8 @@ static void DestroyConnection(WebsocketConnection* conn) WSL_Exit(conn->m_Ctx); #endif + free((void*)conn->m_CustomHeaders); + if (conn->m_Callback) dmScript::DestroyCallback(conn->m_Callback); @@ -228,6 +230,7 @@ static void DestroyConnection(WebsocketConnection* conn) free((void*)conn->m_Buffer); delete conn; + DebugLog(2, "DestroyConnection: %p", conn); } @@ -266,12 +269,20 @@ static int LuaConnect(lua_State* L) return DM_LUA_ERROR("The web socket module isn't initialized"); const char* url = luaL_checkstring(L, 1); + lua_Number timeout = dmScript::CheckTableNumber(L, 2, "timeout", 3000); + const char* custom_headers = dmScript::CheckTableString(L, 2, "headers", 0); + + if (custom_headers != 0) + { + if (strstr(custom_headers, "\r\n\r\n") != 0) + { + return DM_LUA_ERROR("The header field must not contain double '\\r\\n\\r\\n': '%s'", custom_headers); + } + } WebsocketConnection* conn = CreateConnection(url); - - // milliseconds - lua_Number timeout = dmScript::CheckTableNumber(L, 2, "timeout", 3000); conn->m_ConnectTimeout = dmTime::GetTime() + timeout * 1000; + conn->m_CustomHeaders = custom_headers ? strdup(custom_headers) : 0; conn->m_Callback = dmScript::CreateCallback(L, 3); diff --git a/websocket/src/websocket.h b/websocket/src/websocket.h index 010745c..156c6a4 100644 --- a/websocket/src/websocket.h +++ b/websocket/src/websocket.h @@ -91,6 +91,7 @@ namespace dmWebsocket dmArray m_Messages; // lengths of the messages in the data buffer uint64_t m_ConnectTimeout; uint8_t m_Key[16]; + const char* m_CustomHeaders; State m_State; char* m_Buffer; int m_BufferSize;