ws.h (2138B)
1 /* ws.h - WebSocket (RFC 6455) del lado servidor, sobre buffers: sin sockets ni estado 2 * global, para que el servidor de lineas (srv.c) lo use en tres puntos y se pueda 3 * probar en el selftest. Un cliente en navegador (la version web del juego) manda el 4 * mismo protocolo de lineas de texto, solo que envuelto en frames. */ 5 #ifndef COMUN_WS_H 6 #define COMUN_WS_H 7 8 #include <stdint.h> 9 10 enum { WS_CONT = 0, WS_TEXT = 1, WS_BINARY = 2, WS_CLOSE = 8, WS_PING = 9, WS_PONG = 10 }; 11 #define WS_CTL_MAX 125 /* payload maximo de un frame de control */ 12 13 /* Pedido HTTP de upgrade (req, n bytes, puede venir incompleto o con frames detras). 14 * Devuelve el largo de la respuesta "101 Switching Protocols" escrita en resp y deja 15 * en *consumed lo que ocupo el pedido; 0 si todavia no llego el pedido entero; -1 si 16 * no es un upgrade valido (en ese caso resp trae una respuesta 400 para mandar). */ 17 int ws_handshake(const char *req, int n, int *consumed, char *resp, int cap); 18 19 /* Desenvuelve los frames completos que haya en buf[0..n) (del cliente: enmascarados). 20 * El payload de los frames de datos (texto/binario/continuacion) se copia seguido en 21 * out (hasta cap bytes; *outlen recibe cuantos). *ctl recibe una mascara de bits 22 * (1 << opcode) con los frames de control vistos (WS_CLOSE / WS_PING / WS_PONG); el 23 * payload del ultimo PING queda en ping[] (*pinglen bytes) para devolverlo en el PONG. 24 * Despues de un CLOSE no se procesa nada mas. Devuelve los bytes consumidos de buf: lo 25 * que queda es un frame incompleto (o uno cuyo payload no entra en out todavia), para 26 * la proxima llamada. -1 si el flujo es invalido (sin mascara, extensiones, opcode 27 * desconocido, control sin FIN o de mas de 125 bytes, frame mayor que WS_MAX_FRAME, o 28 * un frame que nunca va a entrar en out). */ 29 int ws_unwrap(const uint8_t *buf, int n, char *out, int cap, int *outlen, int *ctl, uint8_t ping[WS_CTL_MAX], int *pinglen); 30 31 /* Arma un frame del servidor (sin mascara) con ese opcode y payload. Devuelve el largo 32 * escrito en out o -1 si no entra. */ 33 int ws_wrap(int opcode, const void *data, int n, uint8_t *out, int cap); 34 35 #endif