1 2 /* 3 * Copyright (C) NGINX, Inc. 4 */ 5 6 #include <nxt_main.h> 7 #include <nxt_websocket.h> 8 #include <nxt_websocket_header.h> 9 10 11 nxt_inline uint16_t nxt_ntoh16(const uint8_t * b)12nxt_ntoh16(const uint8_t *b) 13 { 14 return ((uint16_t) b[0]) << 8 | ((uint16_t) b[1]); 15 } 16 17 18 nxt_inline void nxt_hton16(uint8_t * b,uint16_t v)19nxt_hton16(uint8_t *b, uint16_t v) 20 { 21 b[0] = (v >> 8); 22 b[1] = (v & 0xFFu); 23 } 24 25 26 nxt_inline uint64_t nxt_ntoh64(const uint8_t * b)27nxt_ntoh64(const uint8_t *b) 28 { 29 return ((uint64_t) b[0]) << 56 30 | ((uint64_t) b[1]) << 48 31 | ((uint64_t) b[2]) << 40 32 | ((uint64_t) b[3]) << 32 33 | ((uint64_t) b[4]) << 24 34 | ((uint64_t) b[5]) << 16 35 | ((uint64_t) b[6]) << 8 36 | ((uint64_t) b[7]); 37 } 38 39 40 nxt_inline void nxt_hton64(uint8_t * b,uint64_t v)41nxt_hton64(uint8_t *b, uint64_t v) 42 { 43 b[0] = (v >> 56); 44 b[1] = (v >> 48) & 0xFFu; 45 b[2] = (v >> 40) & 0xFFu; 46 b[3] = (v >> 32) & 0xFFu; 47 b[4] = (v >> 24) & 0xFFu; 48 b[5] = (v >> 16) & 0xFFu; 49 b[6] = (v >> 8) & 0xFFu; 50 b[7] = v & 0xFFu; 51 } 52 53 54 size_t nxt_websocket_frame_header_size(const void * data)55nxt_websocket_frame_header_size(const void *data) 56 { 57 size_t res; 58 uint64_t p; 59 const nxt_websocket_header_t *h; 60 61 h = data; 62 p = h->payload_len; 63 64 res = 2; 65 66 if (p == 126) { 67 res += 2; 68 } else if (p == 127) { 69 res += 8; 70 } 71 72 if (h->mask) { 73 res += 4; 74 } 75 76 return res; 77 } 78 79 80 uint64_t nxt_websocket_frame_payload_len(const void * data)81nxt_websocket_frame_payload_len(const void *data) 82 { 83 uint64_t p; 84 const nxt_websocket_header_t *h; 85 86 h = data; 87 p = h->payload_len; 88 89 if (p == 126) { 90 p = nxt_ntoh16(h->payload_len_); 91 } else if (p == 127) { 92 p = nxt_ntoh64(h->payload_len_); 93 } 94 95 return p; 96 } 97 98 99 void * nxt_websocket_frame_init(void * data,uint64_t payload_len)100nxt_websocket_frame_init(void *data, uint64_t payload_len) 101 { 102 uint8_t *p; 103 nxt_websocket_header_t *h; 104 105 h = data; 106 p = data; 107 108 if (payload_len < 126) { 109 h->payload_len = payload_len; 110 return p + 2; 111 } 112 113 if (payload_len < 65536) { 114 h->payload_len = 126; 115 nxt_hton16(h->payload_len_, payload_len); 116 return p + 4; 117 } 118 119 h->payload_len = 127; 120 nxt_hton64(h->payload_len_, payload_len); 121 return p + 10; 122 } 123