xref: /unit/src/nxt_websocket.c (revision 1235:4d5998f60f20)
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)12 nxt_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)19 nxt_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)27 nxt_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)41 nxt_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)55 nxt_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)81 nxt_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)100 nxt_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