diff options
author | Igor Sysoev <igor@sysoev.ru> | 2017-08-31 00:42:16 +0300 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2017-08-31 00:42:16 +0300 |
commit | f0e9e3ace94c82fab78ab1d4ee8c3042f3e94fdf (patch) | |
tree | 74fab38d3799598febc98aaabb0f5902d7dc5a0e /src/go/unit/nxt_go_port.c | |
parent | 61606835448554a7ee9a4431d732e1f2a9318376 (diff) | |
download | unit-f0e9e3ace94c82fab78ab1d4ee8c3042f3e94fdf.tar.gz unit-f0e9e3ace94c82fab78ab1d4ee8c3042f3e94fdf.tar.bz2 |
nginext has been renamed to unit.
Diffstat (limited to 'src/go/unit/nxt_go_port.c')
-rw-r--r-- | src/go/unit/nxt_go_port.c | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/src/go/unit/nxt_go_port.c b/src/go/unit/nxt_go_port.c new file mode 100644 index 00000000..a46a33d1 --- /dev/null +++ b/src/go/unit/nxt_go_port.c @@ -0,0 +1,210 @@ + +/* + * Copyright (C) Max Romanov + * Copyright (C) NGINX, Inc. + */ + +#ifndef NXT_CONFIGURE + + +#include "nxt_go_port.h" +#include "nxt_go_log.h" +#include "nxt_go_process.h" +#include "nxt_go_run_ctx.h" + +#include <nxt_main.h> +#include <nxt_go_gen.h> + + +#define nxt_go_str(p) ((nxt_go_str_t *)(p)) + +static nxt_go_request_t +nxt_go_data_handler(nxt_port_msg_t *port_msg, size_t size) +{ + size_t s; + nxt_str_t n, v; + nxt_int_t rc; + nxt_uint_t i; + nxt_go_run_ctx_t *ctx; + nxt_go_request_t r; + nxt_app_request_header_t *h; + + r = nxt_go_find_request(port_msg->stream); + if (r != 0) { + return r; + } + + ctx = malloc(sizeof(nxt_go_run_ctx_t)); + nxt_go_ctx_init(ctx, port_msg, size - sizeof(nxt_port_msg_t)); + + r = (nxt_go_request_t)(ctx); + h = &ctx->r.header; + + nxt_go_ctx_read_str(ctx, &h->method); + nxt_go_ctx_read_str(ctx, &h->target); + nxt_go_ctx_read_str(ctx, &h->path); + + nxt_go_ctx_read_size(ctx, &s); + if (s > 0) { + s--; + h->query.start = h->target.start + s; + h->query.length = h->target.length - s; + + if (h->path.start == NULL) { + h->path.start = h->target.start; + h->path.length = s - 1; + } + } + + if (h->path.start == NULL) { + h->path = h->target; + } + + nxt_go_new_request(r, port_msg->stream, nxt_go_str(&h->method), + nxt_go_str(&h->target)); + + nxt_go_ctx_read_str(ctx, &h->version); + + nxt_go_request_set_proto(r, nxt_go_str(&h->version), + h->version.start[5] - '0', + h->version.start[7] - '0'); + + nxt_go_ctx_read_str(ctx, &ctx->r.remote); + if (ctx->r.remote.start != NULL) { + nxt_go_request_set_remote_addr(r, nxt_go_str(&ctx->r.remote)); + } + + nxt_go_ctx_read_str(ctx, &h->host); + nxt_go_ctx_read_str(ctx, &h->cookie); + nxt_go_ctx_read_str(ctx, &h->content_type); + nxt_go_ctx_read_str(ctx, &h->content_length); + + if (h->host.start != NULL) { + nxt_go_request_set_host(r, nxt_go_str(&h->host)); + } + + nxt_go_ctx_read_size(ctx, &s); + h->parsed_content_length = s; + + do { + rc = nxt_go_ctx_read_str(ctx, &n); + + if (n.length == 0) { + break; + } + + rc = nxt_go_ctx_read_str(ctx, &v); + nxt_go_request_add_header(r, nxt_go_str(&n), nxt_go_str(&v)); + } while(1); + + nxt_go_ctx_read_size(ctx, &s); + ctx->r.body.preread_size = s; + + if (h->parsed_content_length > 0) { + nxt_go_request_set_content_length(r, h->parsed_content_length); + } + + if (ctx->r.body.preread_size < h->parsed_content_length) { + nxt_go_request_create_channel(r); + } + + return r; +} + +nxt_go_request_t +nxt_go_port_on_read(void *buf, size_t buf_size, void *oob, size_t oob_size) +{ + void *buf_end; + void *payload; + size_t payload_size; + nxt_fd_t fd; + struct cmsghdr *cm; + nxt_port_msg_t *port_msg; + nxt_port_msg_new_port_t *new_port_msg; + + fd = -1; + nxt_go_debug("on read: %d (%d)", (int)buf_size, (int)oob_size); + + cm = oob; + if (oob_size >= CMSG_SPACE(sizeof(int)) + && cm->cmsg_len == CMSG_LEN(sizeof(int)) + && cm->cmsg_level == SOL_SOCKET + && cm->cmsg_type == SCM_RIGHTS) { + + nxt_memcpy(&fd, CMSG_DATA(cm), sizeof(int)); + nxt_go_debug("fd = %d", fd); + } + + port_msg = buf; + if (buf_size < sizeof(nxt_port_msg_t)) { + nxt_go_warn("message too small (%d bytes)", (int)buf_size); + goto fail; + } + + buf_end = ((char *)buf) + buf_size; + + payload = port_msg + 1; + payload_size = buf_size - sizeof(nxt_port_msg_t); + + if (port_msg->mmap) { + nxt_go_debug("using data in shared memory"); + } + + if (port_msg->type >= NXT_PORT_MSG_MAX) { + nxt_go_warn("unknown message type (%d)", (int)port_msg->type); + goto fail; + } + + switch (port_msg->type) { + case _NXT_PORT_MSG_QUIT: + nxt_go_debug("quit"); + + nxt_go_set_quit(); + break; + + case _NXT_PORT_MSG_NEW_PORT: + nxt_go_debug("new port"); + new_port_msg = payload; + + nxt_go_new_port(new_port_msg->pid, new_port_msg->id, new_port_msg->type, + -1, fd); + break; + + case _NXT_PORT_MSG_CHANGE_FILE: + nxt_go_debug("change file"); + break; + + case _NXT_PORT_MSG_MMAP: + nxt_go_debug("mmap"); + + nxt_go_new_incoming_mmap(port_msg->pid, fd); + break; + + case _NXT_PORT_MSG_DATA: + nxt_go_debug("data"); + + return nxt_go_data_handler(port_msg, buf_size); + + case _NXT_PORT_MSG_REMOVE_PID: + nxt_go_debug("remove pid"); + + /* TODO remove all ports for this pid in Go */ + /* TODO remove incoming & outgoing mmaps for this pid */ + break; + + default: + goto fail; + } + + +fail: + + if (fd != -1) { + close(fd); + } + + return 0; +} + + +#endif /* NXT_CONFIGURE */ |