xref: /unit/src/test/nxt_unit_websocket_echo.c (revision 1131:ec7d924d8dfb)
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 <string.h>
7*1131Smax.romanov@nginx.com #include <stdlib.h>
8*1131Smax.romanov@nginx.com 
9*1131Smax.romanov@nginx.com #include <nxt_unit.h>
10*1131Smax.romanov@nginx.com #include <nxt_unit_request.h>
11*1131Smax.romanov@nginx.com #include <nxt_clang.h>
12*1131Smax.romanov@nginx.com #include <nxt_websocket.h>
13*1131Smax.romanov@nginx.com #include <nxt_unit_websocket.h>
14*1131Smax.romanov@nginx.com 
15*1131Smax.romanov@nginx.com 
16*1131Smax.romanov@nginx.com static void
ws_echo_request_handler(nxt_unit_request_info_t * req)17*1131Smax.romanov@nginx.com ws_echo_request_handler(nxt_unit_request_info_t *req)
18*1131Smax.romanov@nginx.com {
19*1131Smax.romanov@nginx.com     int         rc;
20*1131Smax.romanov@nginx.com     const char  *target;
21*1131Smax.romanov@nginx.com 
22*1131Smax.romanov@nginx.com     rc = NXT_UNIT_OK;
23*1131Smax.romanov@nginx.com     target = nxt_unit_sptr_get(&req->request->target);
24*1131Smax.romanov@nginx.com 
25*1131Smax.romanov@nginx.com     if (strcmp(target, "/") == 0) {
26*1131Smax.romanov@nginx.com         if (!nxt_unit_request_is_websocket_handshake(req)) {
27*1131Smax.romanov@nginx.com             goto notfound;
28*1131Smax.romanov@nginx.com         }
29*1131Smax.romanov@nginx.com 
30*1131Smax.romanov@nginx.com         rc = nxt_unit_response_init(req, 101, 0, 0);
31*1131Smax.romanov@nginx.com         if (nxt_slow_path(rc != NXT_UNIT_OK)) {
32*1131Smax.romanov@nginx.com             goto fail;
33*1131Smax.romanov@nginx.com         }
34*1131Smax.romanov@nginx.com 
35*1131Smax.romanov@nginx.com         nxt_unit_response_upgrade(req);
36*1131Smax.romanov@nginx.com         nxt_unit_response_send(req);
37*1131Smax.romanov@nginx.com 
38*1131Smax.romanov@nginx.com         return;
39*1131Smax.romanov@nginx.com     }
40*1131Smax.romanov@nginx.com 
41*1131Smax.romanov@nginx.com notfound:
42*1131Smax.romanov@nginx.com 
43*1131Smax.romanov@nginx.com     rc = nxt_unit_response_init(req, 404, 0, 0);
44*1131Smax.romanov@nginx.com 
45*1131Smax.romanov@nginx.com fail:
46*1131Smax.romanov@nginx.com 
47*1131Smax.romanov@nginx.com     nxt_unit_request_done(req, rc);
48*1131Smax.romanov@nginx.com }
49*1131Smax.romanov@nginx.com 
50*1131Smax.romanov@nginx.com 
51*1131Smax.romanov@nginx.com static void
ws_echo_websocket_handler(nxt_unit_websocket_frame_t * ws)52*1131Smax.romanov@nginx.com ws_echo_websocket_handler(nxt_unit_websocket_frame_t *ws)
53*1131Smax.romanov@nginx.com {
54*1131Smax.romanov@nginx.com     uint8_t                  opcode;
55*1131Smax.romanov@nginx.com     ssize_t                  size;
56*1131Smax.romanov@nginx.com     nxt_unit_request_info_t  *req;
57*1131Smax.romanov@nginx.com 
58*1131Smax.romanov@nginx.com     static size_t            buf_size = 0;
59*1131Smax.romanov@nginx.com     static uint8_t           *buf = NULL;
60*1131Smax.romanov@nginx.com 
61*1131Smax.romanov@nginx.com     if (buf_size < ws->content_length) {
62*1131Smax.romanov@nginx.com         buf = realloc(buf, ws->content_length);
63*1131Smax.romanov@nginx.com         buf_size = ws->content_length;
64*1131Smax.romanov@nginx.com     }
65*1131Smax.romanov@nginx.com 
66*1131Smax.romanov@nginx.com     req = ws->req;
67*1131Smax.romanov@nginx.com     opcode = ws->header->opcode;
68*1131Smax.romanov@nginx.com 
69*1131Smax.romanov@nginx.com     if (opcode == NXT_WEBSOCKET_OP_PONG) {
70*1131Smax.romanov@nginx.com         nxt_unit_websocket_done(ws);
71*1131Smax.romanov@nginx.com         return;
72*1131Smax.romanov@nginx.com     }
73*1131Smax.romanov@nginx.com 
74*1131Smax.romanov@nginx.com     size = nxt_unit_websocket_read(ws, buf, ws->content_length);
75*1131Smax.romanov@nginx.com 
76*1131Smax.romanov@nginx.com     nxt_unit_websocket_send(req, opcode, ws->header->fin, buf, size);
77*1131Smax.romanov@nginx.com     nxt_unit_websocket_done(ws);
78*1131Smax.romanov@nginx.com 
79*1131Smax.romanov@nginx.com     if (opcode == NXT_WEBSOCKET_OP_CLOSE) {
80*1131Smax.romanov@nginx.com         nxt_unit_request_done(req, NXT_UNIT_OK);
81*1131Smax.romanov@nginx.com     }
82*1131Smax.romanov@nginx.com }
83*1131Smax.romanov@nginx.com 
84*1131Smax.romanov@nginx.com 
85*1131Smax.romanov@nginx.com int
main()86*1131Smax.romanov@nginx.com main()
87*1131Smax.romanov@nginx.com {
88*1131Smax.romanov@nginx.com     nxt_unit_ctx_t   *ctx;
89*1131Smax.romanov@nginx.com     nxt_unit_init_t  init;
90*1131Smax.romanov@nginx.com 
91*1131Smax.romanov@nginx.com     memset(&init, 0, sizeof(nxt_unit_init_t));
92*1131Smax.romanov@nginx.com 
93*1131Smax.romanov@nginx.com     init.callbacks.request_handler = ws_echo_request_handler;
94*1131Smax.romanov@nginx.com     init.callbacks.websocket_handler = ws_echo_websocket_handler;
95*1131Smax.romanov@nginx.com 
96*1131Smax.romanov@nginx.com     ctx = nxt_unit_init(&init);
97*1131Smax.romanov@nginx.com     if (ctx == NULL) {
98*1131Smax.romanov@nginx.com         return 1;
99*1131Smax.romanov@nginx.com     }
100*1131Smax.romanov@nginx.com 
101*1131Smax.romanov@nginx.com     nxt_unit_run(ctx);
102*1131Smax.romanov@nginx.com     nxt_unit_done(ctx);
103*1131Smax.romanov@nginx.com 
104*1131Smax.romanov@nginx.com     return 0;
105*1131Smax.romanov@nginx.com }
106