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 <string.h>
71131Smax.romanov@nginx.com #include <stdlib.h>
81131Smax.romanov@nginx.com
91131Smax.romanov@nginx.com #include <nxt_unit.h>
101131Smax.romanov@nginx.com #include <nxt_unit_request.h>
111131Smax.romanov@nginx.com #include <nxt_clang.h>
121131Smax.romanov@nginx.com #include <nxt_websocket.h>
131131Smax.romanov@nginx.com #include <nxt_unit_websocket.h>
141131Smax.romanov@nginx.com
151131Smax.romanov@nginx.com
161131Smax.romanov@nginx.com static void
ws_echo_request_handler(nxt_unit_request_info_t * req)171131Smax.romanov@nginx.com ws_echo_request_handler(nxt_unit_request_info_t *req)
181131Smax.romanov@nginx.com {
191131Smax.romanov@nginx.com int rc;
201131Smax.romanov@nginx.com const char *target;
211131Smax.romanov@nginx.com
221131Smax.romanov@nginx.com rc = NXT_UNIT_OK;
231131Smax.romanov@nginx.com target = nxt_unit_sptr_get(&req->request->target);
241131Smax.romanov@nginx.com
251131Smax.romanov@nginx.com if (strcmp(target, "/") == 0) {
261131Smax.romanov@nginx.com if (!nxt_unit_request_is_websocket_handshake(req)) {
271131Smax.romanov@nginx.com goto notfound;
281131Smax.romanov@nginx.com }
291131Smax.romanov@nginx.com
301131Smax.romanov@nginx.com rc = nxt_unit_response_init(req, 101, 0, 0);
311131Smax.romanov@nginx.com if (nxt_slow_path(rc != NXT_UNIT_OK)) {
321131Smax.romanov@nginx.com goto fail;
331131Smax.romanov@nginx.com }
341131Smax.romanov@nginx.com
351131Smax.romanov@nginx.com nxt_unit_response_upgrade(req);
361131Smax.romanov@nginx.com nxt_unit_response_send(req);
371131Smax.romanov@nginx.com
381131Smax.romanov@nginx.com return;
391131Smax.romanov@nginx.com }
401131Smax.romanov@nginx.com
411131Smax.romanov@nginx.com notfound:
421131Smax.romanov@nginx.com
431131Smax.romanov@nginx.com rc = nxt_unit_response_init(req, 404, 0, 0);
441131Smax.romanov@nginx.com
451131Smax.romanov@nginx.com fail:
461131Smax.romanov@nginx.com
471131Smax.romanov@nginx.com nxt_unit_request_done(req, rc);
481131Smax.romanov@nginx.com }
491131Smax.romanov@nginx.com
501131Smax.romanov@nginx.com
511131Smax.romanov@nginx.com static void
ws_echo_websocket_handler(nxt_unit_websocket_frame_t * ws)521131Smax.romanov@nginx.com ws_echo_websocket_handler(nxt_unit_websocket_frame_t *ws)
531131Smax.romanov@nginx.com {
541131Smax.romanov@nginx.com uint8_t opcode;
551131Smax.romanov@nginx.com ssize_t size;
561131Smax.romanov@nginx.com nxt_unit_request_info_t *req;
571131Smax.romanov@nginx.com
581131Smax.romanov@nginx.com static size_t buf_size = 0;
591131Smax.romanov@nginx.com static uint8_t *buf = NULL;
601131Smax.romanov@nginx.com
611131Smax.romanov@nginx.com if (buf_size < ws->content_length) {
621131Smax.romanov@nginx.com buf = realloc(buf, ws->content_length);
631131Smax.romanov@nginx.com buf_size = ws->content_length;
641131Smax.romanov@nginx.com }
651131Smax.romanov@nginx.com
661131Smax.romanov@nginx.com req = ws->req;
671131Smax.romanov@nginx.com opcode = ws->header->opcode;
681131Smax.romanov@nginx.com
691131Smax.romanov@nginx.com if (opcode == NXT_WEBSOCKET_OP_PONG) {
701131Smax.romanov@nginx.com nxt_unit_websocket_done(ws);
711131Smax.romanov@nginx.com return;
721131Smax.romanov@nginx.com }
731131Smax.romanov@nginx.com
741131Smax.romanov@nginx.com size = nxt_unit_websocket_read(ws, buf, ws->content_length);
751131Smax.romanov@nginx.com
761131Smax.romanov@nginx.com nxt_unit_websocket_send(req, opcode, ws->header->fin, buf, size);
771131Smax.romanov@nginx.com nxt_unit_websocket_done(ws);
781131Smax.romanov@nginx.com
791131Smax.romanov@nginx.com if (opcode == NXT_WEBSOCKET_OP_CLOSE) {
801131Smax.romanov@nginx.com nxt_unit_request_done(req, NXT_UNIT_OK);
811131Smax.romanov@nginx.com }
821131Smax.romanov@nginx.com }
831131Smax.romanov@nginx.com
841131Smax.romanov@nginx.com
851131Smax.romanov@nginx.com int
main(void)86*2229Sa.clayton@nginx.com main(void)
871131Smax.romanov@nginx.com {
881131Smax.romanov@nginx.com nxt_unit_ctx_t *ctx;
891131Smax.romanov@nginx.com nxt_unit_init_t init;
901131Smax.romanov@nginx.com
911131Smax.romanov@nginx.com memset(&init, 0, sizeof(nxt_unit_init_t));
921131Smax.romanov@nginx.com
931131Smax.romanov@nginx.com init.callbacks.request_handler = ws_echo_request_handler;
941131Smax.romanov@nginx.com init.callbacks.websocket_handler = ws_echo_websocket_handler;
951131Smax.romanov@nginx.com
961131Smax.romanov@nginx.com ctx = nxt_unit_init(&init);
971131Smax.romanov@nginx.com if (ctx == NULL) {
981131Smax.romanov@nginx.com return 1;
991131Smax.romanov@nginx.com }
1001131Smax.romanov@nginx.com
1011131Smax.romanov@nginx.com nxt_unit_run(ctx);
1021131Smax.romanov@nginx.com nxt_unit_done(ctx);
1031131Smax.romanov@nginx.com
1041131Smax.romanov@nginx.com return 0;
1051131Smax.romanov@nginx.com }
106