diff options
author | Max Romanov <max.romanov@nginx.com> | 2019-08-20 16:31:53 +0300 |
---|---|---|
committer | Max Romanov <max.romanov@nginx.com> | 2019-08-20 16:31:53 +0300 |
commit | e501c74ddceab86e48c031ca9b5e154f52dcdae0 (patch) | |
tree | 7bfe94354df516d1ceefc5af3194ba943e443aa2 /src/nxt_websocket.c | |
parent | 9bbf54e23e185e94054072fff2673f6f5cd203e9 (diff) | |
download | unit-e501c74ddceab86e48c031ca9b5e154f52dcdae0.tar.gz unit-e501c74ddceab86e48c031ca9b5e154f52dcdae0.tar.bz2 |
Introducing websocket support in router and libunit.
Diffstat (limited to '')
-rw-r--r-- | src/nxt_websocket.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/src/nxt_websocket.c b/src/nxt_websocket.c new file mode 100644 index 00000000..9a099760 --- /dev/null +++ b/src/nxt_websocket.c @@ -0,0 +1,122 @@ + +/* + * Copyright (C) NGINX, Inc. + */ + +#include <nxt_main.h> +#include <nxt_websocket.h> +#include <nxt_websocket_header.h> + + +nxt_inline uint16_t +nxt_ntoh16(const uint8_t *b) +{ + return ((uint16_t) b[0]) << 8 | ((uint16_t) b[1]); +} + + +nxt_inline void +nxt_hton16(uint8_t *b, uint16_t v) +{ + b[0] = (v >> 8); + b[1] = (v & 0xFFu); +} + + +nxt_inline uint64_t +nxt_ntoh64(const uint8_t *b) +{ + return ((uint64_t) b[0]) << 56 + | ((uint64_t) b[1]) << 48 + | ((uint64_t) b[2]) << 40 + | ((uint64_t) b[3]) << 32 + | ((uint64_t) b[4]) << 24 + | ((uint64_t) b[5]) << 16 + | ((uint64_t) b[6]) << 8 + | ((uint64_t) b[7]); +} + + +nxt_inline void +nxt_hton64(uint8_t *b, uint64_t v) +{ + b[0] = (v >> 56); + b[1] = (v >> 48) & 0xFFu; + b[2] = (v >> 40) & 0xFFu; + b[3] = (v >> 32) & 0xFFu; + b[4] = (v >> 24) & 0xFFu; + b[5] = (v >> 16) & 0xFFu; + b[6] = (v >> 8) & 0xFFu; + b[7] = v & 0xFFu; +} + + +size_t +nxt_websocket_frame_header_size(const void *data) +{ + size_t res; + uint64_t p; + const nxt_websocket_header_t *h; + + h = data; + p = h->payload_len; + + res = 2; + + if (p == 126) { + res += 2; + } else if (p == 127) { + res += 8; + } + + if (h->mask) { + res += 4; + } + + return res; +} + + +uint64_t +nxt_websocket_frame_payload_len(const void *data) +{ + uint64_t p; + const nxt_websocket_header_t *h; + + h = data; + p = h->payload_len; + + if (p == 126) { + p = nxt_ntoh16(h->payload_len_); + } else if (p == 127) { + p = nxt_ntoh64(h->payload_len_); + } + + return p; +} + + +void * +nxt_websocket_frame_init(void *data, uint64_t payload_len) +{ + uint8_t *p; + nxt_websocket_header_t *h; + + h = data; + p = data; + + if (payload_len < 126) { + h->payload_len = payload_len; + return p + 2; + } + + if (payload_len < 65536) { + h->payload_len = 126; + nxt_hton16(h->payload_len_, payload_len); + return p + 4; + } + + h->payload_len = 127; + nxt_hton64(h->payload_len_, payload_len); + return p + 10; +} |