#include #include "websock.h" #define SAT_WEBSOCK_HANDSHAKE_UNIQUE "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" #define SAT_WEBSOCK_HANDSHAKE_VERSION_10 "HTTP/1.0 " #define SAT_WEBSOCK_HANDSHAKE_VERSION_11 "HTTP/1.1 " #define SAT_WEBSOCK_HANDSHAKE_LINE_END (0x0D0A) sat_websock_handshake_ptr sat_websock_handshake_alloc(void) { sat_websock_handshake_ptr hs = malloc(sizeof(sat_websock_handshake)); memset(hs, 0, sizeof(sat_websock_handshake)); return hs; } void sat_websock_handshake_free(sat_websock_handshake_ptr hs, bool freeArg) { if(hs == NULL) return; if(freeArg) free(hs); } int sat_websock_handshake_gen_key(sat_websock_handshake_ptr hs) { return getrandom(hs->key, 16, 0); } int sat_websock_handshake_send(sat_websock_handshake_ptr hs) { char buffer[1024] = {0}; size_t count = 0; count += sprintf(buffer + count, "GET %s HTTP/1.1\r\n", hs->path); count += sprintf(buffer + count, "Host: %s\r\n", hs->host); count += sprintf(buffer + count, "Upgrade: websocket\r\n"); count += sprintf(buffer + count, "Connection: Upgrade\r\n"); count += sprintf(buffer + count, "Sec-WebSocket-Version: 13\r\n"); count += sprintf(buffer + count, "Sec-WebSocket-Key: %s\r\n", hs->key); if(hs->origin != NULL) count += sprintf(buffer + count, "Origin: %s\r\n", hs->origin); if(hs->protocol != NULL) count += sprintf(buffer + count, "Sec-WebSocket-Protocol: %s\r\n", hs->protocol); count += sprintf(buffer + count, "\r\n"); return sat_websock_send(hs->websock, (uint8_t*)buffer, count); } int sat_websock_handshake_recv(sat_websock_handshake_ptr hs) { char buffer[1024] = {0}; sat_websock_buffer(hs->websock, 100); int expect = strlen(SAT_WEBSOCK_HANDSHAKE_VERSION_11); int read = sat_websock_recv(hs->websock, (uint8_t*)buffer, expect); if(read != expect) return -1; if(strcmp(SAT_WEBSOCK_HANDSHAKE_VERSION_11, buffer) != 0 && strcmp(SAT_WEBSOCK_HANDSHAKE_VERSION_10, buffer) != 0) return -2; uint16_t checkCrLf = 0; int i; for(i = 0; i < sizeof buffer && checkCrLf != SAT_WEBSOCK_HANDSHAKE_LINE_END; ++i) { buffer[i] = sat_buffer_getc(hs->websock->buffer); checkCrLf <<= 8; checkCrLf |= buffer[i]; } buffer[i] = '\0'; if(sscanf(buffer, "%hd %s", &hs->statusCode, hs->statusReason) != 2) return -3; hs->completed = true; hs->upgraded = hs->statusCode == 101; return 0; }