72 lines
2.4 KiB
C
72 lines
2.4 KiB
C
#include <sys/random.h>
|
|
#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;
|
|
}
|