xref: /unit/src/nxt_websocket.c (revision 1235:4d5998f60f20)
11131Smax.romanov@nginx.com 
21131Smax.romanov@nginx.com /*
31131Smax.romanov@nginx.com  * Copyright (C) NGINX, Inc.
41131Smax.romanov@nginx.com  */
51131Smax.romanov@nginx.com 
61131Smax.romanov@nginx.com #include <nxt_main.h>
71131Smax.romanov@nginx.com #include <nxt_websocket.h>
81131Smax.romanov@nginx.com #include <nxt_websocket_header.h>
91131Smax.romanov@nginx.com 
101131Smax.romanov@nginx.com 
111131Smax.romanov@nginx.com nxt_inline uint16_t
nxt_ntoh16(const uint8_t * b)121131Smax.romanov@nginx.com nxt_ntoh16(const uint8_t *b)
131131Smax.romanov@nginx.com {
141131Smax.romanov@nginx.com     return ((uint16_t) b[0]) << 8 | ((uint16_t) b[1]);
151131Smax.romanov@nginx.com }
161131Smax.romanov@nginx.com 
171131Smax.romanov@nginx.com 
181131Smax.romanov@nginx.com nxt_inline void
nxt_hton16(uint8_t * b,uint16_t v)191131Smax.romanov@nginx.com nxt_hton16(uint8_t *b, uint16_t v)
201131Smax.romanov@nginx.com {
211131Smax.romanov@nginx.com     b[0] = (v >> 8);
22*1235Sigor@sysoev.ru     b[1] = (v & 0xFFu);
231131Smax.romanov@nginx.com }
241131Smax.romanov@nginx.com 
251131Smax.romanov@nginx.com 
261131Smax.romanov@nginx.com nxt_inline uint64_t
nxt_ntoh64(const uint8_t * b)271131Smax.romanov@nginx.com nxt_ntoh64(const uint8_t *b)
281131Smax.romanov@nginx.com {
291131Smax.romanov@nginx.com     return  ((uint64_t) b[0]) << 56
301131Smax.romanov@nginx.com           | ((uint64_t) b[1]) << 48
311131Smax.romanov@nginx.com           | ((uint64_t) b[2]) << 40
321131Smax.romanov@nginx.com           | ((uint64_t) b[3]) << 32
331131Smax.romanov@nginx.com           | ((uint64_t) b[4]) << 24
341131Smax.romanov@nginx.com           | ((uint64_t) b[5]) << 16
351131Smax.romanov@nginx.com           | ((uint64_t) b[6]) << 8
361131Smax.romanov@nginx.com           | ((uint64_t) b[7]);
371131Smax.romanov@nginx.com }
381131Smax.romanov@nginx.com 
391131Smax.romanov@nginx.com 
401131Smax.romanov@nginx.com nxt_inline void
nxt_hton64(uint8_t * b,uint64_t v)411131Smax.romanov@nginx.com nxt_hton64(uint8_t *b, uint64_t v)
421131Smax.romanov@nginx.com {
431131Smax.romanov@nginx.com     b[0] = (v >> 56);
441131Smax.romanov@nginx.com     b[1] = (v >> 48) & 0xFFu;
451131Smax.romanov@nginx.com     b[2] = (v >> 40) & 0xFFu;
461131Smax.romanov@nginx.com     b[3] = (v >> 32) & 0xFFu;
471131Smax.romanov@nginx.com     b[4] = (v >> 24) & 0xFFu;
481131Smax.romanov@nginx.com     b[5] = (v >> 16) & 0xFFu;
491131Smax.romanov@nginx.com     b[6] = (v >>  8) & 0xFFu;
501131Smax.romanov@nginx.com     b[7] =  v        & 0xFFu;
511131Smax.romanov@nginx.com }
521131Smax.romanov@nginx.com 
531131Smax.romanov@nginx.com 
541131Smax.romanov@nginx.com size_t
nxt_websocket_frame_header_size(const void * data)551131Smax.romanov@nginx.com nxt_websocket_frame_header_size(const void *data)
561131Smax.romanov@nginx.com {
571131Smax.romanov@nginx.com     size_t                        res;
581131Smax.romanov@nginx.com     uint64_t                      p;
591131Smax.romanov@nginx.com     const nxt_websocket_header_t  *h;
601131Smax.romanov@nginx.com 
611131Smax.romanov@nginx.com     h = data;
621131Smax.romanov@nginx.com     p = h->payload_len;
631131Smax.romanov@nginx.com 
641131Smax.romanov@nginx.com     res = 2;
651131Smax.romanov@nginx.com 
661131Smax.romanov@nginx.com     if (p == 126) {
671131Smax.romanov@nginx.com         res += 2;
681131Smax.romanov@nginx.com     } else if (p == 127) {
691131Smax.romanov@nginx.com         res += 8;
701131Smax.romanov@nginx.com     }
711131Smax.romanov@nginx.com 
721131Smax.romanov@nginx.com     if (h->mask) {
731131Smax.romanov@nginx.com         res += 4;
741131Smax.romanov@nginx.com     }
751131Smax.romanov@nginx.com 
761131Smax.romanov@nginx.com     return res;
771131Smax.romanov@nginx.com }
781131Smax.romanov@nginx.com 
791131Smax.romanov@nginx.com 
801131Smax.romanov@nginx.com uint64_t
nxt_websocket_frame_payload_len(const void * data)811131Smax.romanov@nginx.com nxt_websocket_frame_payload_len(const void *data)
821131Smax.romanov@nginx.com {
831131Smax.romanov@nginx.com     uint64_t                      p;
841131Smax.romanov@nginx.com     const nxt_websocket_header_t  *h;
851131Smax.romanov@nginx.com 
861131Smax.romanov@nginx.com     h = data;
871131Smax.romanov@nginx.com     p = h->payload_len;
881131Smax.romanov@nginx.com 
891131Smax.romanov@nginx.com     if (p == 126) {
901131Smax.romanov@nginx.com         p = nxt_ntoh16(h->payload_len_);
911131Smax.romanov@nginx.com     } else if (p == 127) {
921131Smax.romanov@nginx.com         p = nxt_ntoh64(h->payload_len_);
931131Smax.romanov@nginx.com     }
941131Smax.romanov@nginx.com 
951131Smax.romanov@nginx.com     return p;
961131Smax.romanov@nginx.com }
971131Smax.romanov@nginx.com 
981131Smax.romanov@nginx.com 
991131Smax.romanov@nginx.com void *
nxt_websocket_frame_init(void * data,uint64_t payload_len)1001131Smax.romanov@nginx.com nxt_websocket_frame_init(void *data, uint64_t payload_len)
1011131Smax.romanov@nginx.com {
1021131Smax.romanov@nginx.com     uint8_t                 *p;
1031131Smax.romanov@nginx.com     nxt_websocket_header_t  *h;
1041131Smax.romanov@nginx.com 
1051131Smax.romanov@nginx.com     h = data;
1061131Smax.romanov@nginx.com     p = data;
1071131Smax.romanov@nginx.com 
1081131Smax.romanov@nginx.com     if (payload_len < 126) {
1091131Smax.romanov@nginx.com         h->payload_len = payload_len;
1101131Smax.romanov@nginx.com         return p + 2;
1111131Smax.romanov@nginx.com     }
1121131Smax.romanov@nginx.com 
1131131Smax.romanov@nginx.com     if (payload_len < 65536) {
1141131Smax.romanov@nginx.com         h->payload_len = 126;
1151131Smax.romanov@nginx.com         nxt_hton16(h->payload_len_, payload_len);
1161131Smax.romanov@nginx.com         return p + 4;
1171131Smax.romanov@nginx.com     }
1181131Smax.romanov@nginx.com 
1191131Smax.romanov@nginx.com     h->payload_len = 127;
1201131Smax.romanov@nginx.com     nxt_hton64(h->payload_len_, payload_len);
1211131Smax.romanov@nginx.com     return p + 10;
1221131Smax.romanov@nginx.com }
123