xref: /unit/src/test/nxt_unit_websocket_echo.c (revision 2229:3a230013e58a)
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