diff options
author | Max Romanov <max.romanov@nginx.com> | 2019-08-20 16:31:53 +0300 |
---|---|---|
committer | Max Romanov <max.romanov@nginx.com> | 2019-08-20 16:31:53 +0300 |
commit | e501c74ddceab86e48c031ca9b5e154f52dcdae0 (patch) | |
tree | 7bfe94354df516d1ceefc5af3194ba943e443aa2 /src/test/nxt_unit_websocket_echo.c | |
parent | 9bbf54e23e185e94054072fff2673f6f5cd203e9 (diff) | |
download | unit-e501c74ddceab86e48c031ca9b5e154f52dcdae0.tar.gz unit-e501c74ddceab86e48c031ca9b5e154f52dcdae0.tar.bz2 |
Introducing websocket support in router and libunit.
Diffstat (limited to '')
-rw-r--r-- | src/test/nxt_unit_websocket_echo.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/test/nxt_unit_websocket_echo.c b/src/test/nxt_unit_websocket_echo.c new file mode 100644 index 00000000..2a89cdc0 --- /dev/null +++ b/src/test/nxt_unit_websocket_echo.c @@ -0,0 +1,105 @@ + +/* + * Copyright (C) NGINX, Inc. + */ + +#include <string.h> +#include <stdlib.h> + +#include <nxt_unit.h> +#include <nxt_unit_request.h> +#include <nxt_clang.h> +#include <nxt_websocket.h> +#include <nxt_unit_websocket.h> + + +static void +ws_echo_request_handler(nxt_unit_request_info_t *req) +{ + int rc; + const char *target; + + rc = NXT_UNIT_OK; + target = nxt_unit_sptr_get(&req->request->target); + + if (strcmp(target, "/") == 0) { + if (!nxt_unit_request_is_websocket_handshake(req)) { + goto notfound; + } + + rc = nxt_unit_response_init(req, 101, 0, 0); + if (nxt_slow_path(rc != NXT_UNIT_OK)) { + goto fail; + } + + nxt_unit_response_upgrade(req); + nxt_unit_response_send(req); + + return; + } + +notfound: + + rc = nxt_unit_response_init(req, 404, 0, 0); + +fail: + + nxt_unit_request_done(req, rc); +} + + +static void +ws_echo_websocket_handler(nxt_unit_websocket_frame_t *ws) +{ + uint8_t opcode; + ssize_t size; + nxt_unit_request_info_t *req; + + static size_t buf_size = 0; + static uint8_t *buf = NULL; + + if (buf_size < ws->content_length) { + buf = realloc(buf, ws->content_length); + buf_size = ws->content_length; + } + + req = ws->req; + opcode = ws->header->opcode; + + if (opcode == NXT_WEBSOCKET_OP_PONG) { + nxt_unit_websocket_done(ws); + return; + } + + size = nxt_unit_websocket_read(ws, buf, ws->content_length); + + nxt_unit_websocket_send(req, opcode, ws->header->fin, buf, size); + nxt_unit_websocket_done(ws); + + if (opcode == NXT_WEBSOCKET_OP_CLOSE) { + nxt_unit_request_done(req, NXT_UNIT_OK); + } +} + + +int +main() +{ + nxt_unit_ctx_t *ctx; + nxt_unit_init_t init; + + memset(&init, 0, sizeof(nxt_unit_init_t)); + + init.callbacks.request_handler = ws_echo_request_handler; + init.callbacks.websocket_handler = ws_echo_websocket_handler; + + ctx = nxt_unit_init(&init); + if (ctx == NULL) { + return 1; + } + + nxt_unit_run(ctx); + nxt_unit_done(ctx); + + return 0; +} |