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