Commit a75e3d27 authored by Ian Craggs's avatar Ian Craggs

Check the websocket HTTP response #506

parent b00e6980
......@@ -26,6 +26,7 @@
#include "SHA1.h"
#include "LinkedList.h"
#include "MQTTProtocolOut.h"
#include "StackTrace.h"
#if defined(__linux__)
# include <endian.h>
......@@ -180,6 +181,7 @@ static int WebSocket_buildFrame(networkHandles* net, int opcode, int mask_data,
int buf_len = 0u;
size_t data_len = buf0len;
FUNC_ENTRY;
for (i = 0; i < count; ++i)
data_len += buflens[i];
......@@ -255,6 +257,8 @@ static int WebSocket_buildFrame(networkHandles* net, int opcode, int mask_data,
}
}
}
FUNC_EXIT_RC(buf_len);
return buf_len;
}
......@@ -310,6 +314,7 @@ int WebSocket_connect( networkHandles *net, const char *uri )
int port = 80;
const char *topic = NULL;
FUNC_ENTRY;
/* Generate UUID */
if (net->websocket_key == NULL)
net->websocket_key = malloc(25u);
......@@ -374,6 +379,8 @@ int WebSocket_connect( networkHandles *net, const char *uri )
net->websocket_key = NULL;
rc = SOCKET_ERROR;
}
FUNC_EXIT_RC(rc);
return rc;
}
......@@ -386,6 +393,8 @@ int WebSocket_connect( networkHandles *net, const char *uri )
*/
void WebSocket_close(networkHandles *net, int status_code, const char *reason)
{
FUNC_ENTRY;
if ( net->websocket )
{
char *buf0;
......@@ -436,6 +445,8 @@ void WebSocket_close(networkHandles *net, int status_code, const char *reason)
free( net->websocket_key );
net->websocket_key = NULL;
}
FUNC_EXIT;
}
/**
......@@ -453,6 +464,8 @@ void WebSocket_close(networkHandles *net, int status_code, const char *reason)
int WebSocket_getch(networkHandles *net, char* c)
{
int rc = SOCKET_ERROR;
FUNC_ENTRY;
if ( net->websocket )
{
struct ws_frame *frame = NULL;
......@@ -487,6 +500,8 @@ int WebSocket_getch(networkHandles *net, char* c)
#endif
else
rc = Socket_getch(net->socket, c);
FUNC_EXIT_RC(rc);
return rc;
}
......@@ -504,6 +519,9 @@ int WebSocket_getch(networkHandles *net, char* c)
char *WebSocket_getdata(networkHandles *net, size_t bytes, size_t* actual_len)
{
char *rv = NULL;
int rc = 0;
FUNC_ENTRY;
if ( net->websocket )
{
struct ws_frame *frame = NULL;
......@@ -558,6 +576,9 @@ char *WebSocket_getdata(networkHandles *net, size_t bytes, size_t* actual_len)
}
else
rv = WebSocket_getRawSocketData(net, bytes, actual_len);
rc = rv != NULL;
FUNC_EXIT_RC(rc);
return rv;
}
......@@ -593,6 +614,7 @@ char *WebSocket_getRawSocketData(
void WebSocket_pong(networkHandles *net, char *app_data,
size_t app_data_len)
{
FUNC_ENTRY;
if ( net->websocket )
{
char *buf0;
......@@ -625,6 +647,7 @@ void WebSocket_pong(networkHandles *net, char *app_data,
/* clean up memory */
free( buf0 );
}
FUNC_EXIT;
}
/**
......@@ -652,6 +675,7 @@ int WebSocket_putdatas(networkHandles* net, char* buf0, size_t buf0len,
{
int rc;
FUNC_ENTRY;
/* prepend WebSocket frame */
if ( net->websocket )
{
......@@ -682,6 +706,8 @@ int WebSocket_putdatas(networkHandles* net, char* buf0, size_t buf0len,
else
#endif
rc = Socket_putdatas(net->socket, buf0, buf0len, count, buffers, buflens, freeData);
FUNC_EXIT_RC(rc);
return rc;
}
......@@ -700,7 +726,9 @@ int WebSocket_receiveFrame(networkHandles *net,
size_t bytes, size_t *actual_len )
{
struct ws_frame *res = NULL;
int rc = TCPSOCKET_COMPLETE;
FUNC_ENTRY;
if ( !in_frames )
in_frames = ListInitialize();
......@@ -727,7 +755,10 @@ int WebSocket_receiveFrame(networkHandles *net,
b = WebSocket_getRawSocketData(net, 2u, &len);
if ( !b || len == 0u )
return TCPSOCKET_INTERRUPTED;
{
rc = TCPSOCKET_INTERRUPTED;
goto exit;
}
/* 1st byte */
final = (b[0] & 0xFF) >> 7;
......@@ -741,7 +772,10 @@ int WebSocket_receiveFrame(networkHandles *net,
opcode > WebSocket_OP_PONG ||
( opcode > WebSocket_OP_BINARY &&
opcode < WebSocket_OP_CLOSE ) )
return SOCKET_ERROR;
{
rc = SOCKET_ERROR;
goto exit;
}
/* 2nd byte */
has_mask = (b[1] & 0xFF) >> 7;
......@@ -753,7 +787,10 @@ int WebSocket_receiveFrame(networkHandles *net,
b = WebSocket_getRawSocketData( net,
2u, &len);
if ( !b || len == 0u )
return TCPSOCKET_INTERRUPTED;
{
rc = TCPSOCKET_INTERRUPTED;
goto exit;
}
/* convert from big endian 16 to host */
payload_len = be16toh(*(uint16_t*)b);
}
......@@ -762,7 +799,10 @@ int WebSocket_receiveFrame(networkHandles *net,
b = WebSocket_getRawSocketData( net,
8u, &len);
if ( !b || len == 0u )
return TCPSOCKET_INTERRUPTED;
{
rc = TCPSOCKET_INTERRUPTED;
goto exit;
}
/* convert from big-endian 64 to host */
payload_len = (size_t)be64toh(*(uint64_t*)b);
}
......@@ -772,7 +812,10 @@ int WebSocket_receiveFrame(networkHandles *net,
uint8_t mask[4];
b = WebSocket_getRawSocketData(net, 4u, &len);
if ( !b || len == 0u )
return TCPSOCKET_INTERRUPTED;
{
rc = TCPSOCKET_INTERRUPTED;
goto exit;
}
memcpy( &mask[0], b, sizeof(uint32_t));
}
......@@ -780,7 +823,10 @@ int WebSocket_receiveFrame(networkHandles *net,
payload_len, &len);
if ( !b || len == 0u )
return TCPSOCKET_INTERRUPTED;
{
rc = TCPSOCKET_INTERRUPTED;
goto exit;
}
/* unmask data */
if ( has_mask )
......@@ -821,7 +867,8 @@ int WebSocket_receiveFrame(networkHandles *net,
/* server end closed websocket connection */
free( res );
WebSocket_close( net, WebSocket_CLOSE_GOING_AWAY, NULL );
return SOCKET_ERROR; /* closes socket */
rc = SOCKET_ERROR; /* closes socket */
goto exit;
}
} while ( opcode == WebSocket_OP_PING || opcode == WebSocket_OP_PONG );
}
......@@ -829,7 +876,10 @@ int WebSocket_receiveFrame(networkHandles *net,
/* add new frame to end of list */
ListAppend( in_frames, res, sizeof(struct ws_frame) + res->len);
*actual_len = res->len - res->pos;
return TCPSOCKET_COMPLETE;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
......@@ -866,6 +916,7 @@ const char *WebSocket_strcasefind(const char *buf, const char *str, size_t len)
*/
void WebSocket_terminate( void )
{
FUNC_ENTRY;
/* clean up and un-processed websocket frames */
if ( in_frames )
{
......@@ -887,6 +938,7 @@ void WebSocket_terminate( void )
#if defined(OPENSSL)
SSLSocket_terminate();
#endif
FUNC_EXIT;
}
/**
......@@ -904,6 +956,8 @@ int WebSocket_upgrade( networkHandles *net )
static const char *const ws_guid =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
int rc = SOCKET_ERROR;
FUNC_ENTRY;
if ( net->websocket_key )
{
SHA_CTX ctx;
......@@ -921,7 +975,18 @@ int WebSocket_upgrade( networkHandles *net )
rc = TCPSOCKET_INTERRUPTED;
read_buf = WebSocket_getRawSocketData( net, 12u, &rcv );
if ( rcv > 0 && strncmp( read_buf, "HTTP/1.1 101", 11u ) == 0 )
if ( rcv > 0 && strncmp( read_buf, "HTTP/1.1", 8u ) == 0 )
{
if (strncmp( &read_buf[9], "101", 3u ) != 0)
{
Log(TRACE_PROTOCOL, 1, "WebSocket HTTP rc %.3s", &read_buf[9]);
rc = SOCKET_ERROR;
goto exit;
}
}
if ( rcv > 0 && strncmp( read_buf, "HTTP/1.1 101", 12u ) == 0 )
{
const char *p;
read_buf = WebSocket_getRawSocketData( net, 500u, &rcv );
......@@ -990,6 +1055,9 @@ int WebSocket_upgrade( networkHandles *net )
WebSocket_getRawSocketData( net, 0u, &rcv );
}
}
exit:
FUNC_EXIT_RC(rc);
return rc;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment