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