1*1316Smax.romanov@nginx.com 2*1316Smax.romanov@nginx.com /* 3*1316Smax.romanov@nginx.com * Copyright (C) Max Romanov 4*1316Smax.romanov@nginx.com * Copyright (C) NGINX, Inc. 5*1316Smax.romanov@nginx.com */ 6*1316Smax.romanov@nginx.com 7*1316Smax.romanov@nginx.com #include "_cgo_export.h" 8*1316Smax.romanov@nginx.com 9*1316Smax.romanov@nginx.com #include <nxt_unit.h> 10*1316Smax.romanov@nginx.com #include <nxt_unit_request.h> 11*1316Smax.romanov@nginx.com 12*1316Smax.romanov@nginx.com 13*1316Smax.romanov@nginx.com static void nxt_cgo_request_handler(nxt_unit_request_info_t *req); 14*1316Smax.romanov@nginx.com static nxt_cgo_str_t *nxt_cgo_str_init(nxt_cgo_str_t *dst, 15*1316Smax.romanov@nginx.com nxt_unit_sptr_t *sptr, uint32_t length); 16*1316Smax.romanov@nginx.com static int nxt_cgo_add_port(nxt_unit_ctx_t *, nxt_unit_port_t *port); 17*1316Smax.romanov@nginx.com static void nxt_cgo_remove_port(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id); 18*1316Smax.romanov@nginx.com static ssize_t nxt_cgo_port_send(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id, 19*1316Smax.romanov@nginx.com const void *buf, size_t buf_size, const void *oob, size_t oob_size); 20*1316Smax.romanov@nginx.com static ssize_t nxt_cgo_port_recv(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id, 21*1316Smax.romanov@nginx.com void *buf, size_t buf_size, void *oob, size_t oob_size); 22*1316Smax.romanov@nginx.com 23*1316Smax.romanov@nginx.com int 24*1316Smax.romanov@nginx.com nxt_cgo_run(uintptr_t handler) 25*1316Smax.romanov@nginx.com { 26*1316Smax.romanov@nginx.com int rc; 27*1316Smax.romanov@nginx.com nxt_unit_ctx_t *ctx; 28*1316Smax.romanov@nginx.com nxt_unit_init_t init; 29*1316Smax.romanov@nginx.com 30*1316Smax.romanov@nginx.com memset(&init, 0, sizeof(init)); 31*1316Smax.romanov@nginx.com 32*1316Smax.romanov@nginx.com init.callbacks.request_handler = nxt_cgo_request_handler; 33*1316Smax.romanov@nginx.com init.callbacks.add_port = nxt_cgo_add_port; 34*1316Smax.romanov@nginx.com init.callbacks.remove_port = nxt_cgo_remove_port; 35*1316Smax.romanov@nginx.com init.callbacks.port_send = nxt_cgo_port_send; 36*1316Smax.romanov@nginx.com init.callbacks.port_recv = nxt_cgo_port_recv; 37*1316Smax.romanov@nginx.com 38*1316Smax.romanov@nginx.com init.data = (void *) handler; 39*1316Smax.romanov@nginx.com 40*1316Smax.romanov@nginx.com ctx = nxt_unit_init(&init); 41*1316Smax.romanov@nginx.com if (ctx == NULL) { 42*1316Smax.romanov@nginx.com return NXT_UNIT_ERROR; 43*1316Smax.romanov@nginx.com } 44*1316Smax.romanov@nginx.com 45*1316Smax.romanov@nginx.com rc = nxt_unit_run(ctx); 46*1316Smax.romanov@nginx.com 47*1316Smax.romanov@nginx.com nxt_unit_done(ctx); 48*1316Smax.romanov@nginx.com 49*1316Smax.romanov@nginx.com return rc; 50*1316Smax.romanov@nginx.com } 51*1316Smax.romanov@nginx.com 52*1316Smax.romanov@nginx.com 53*1316Smax.romanov@nginx.com static void 54*1316Smax.romanov@nginx.com nxt_cgo_request_handler(nxt_unit_request_info_t *req) 55*1316Smax.romanov@nginx.com { 56*1316Smax.romanov@nginx.com uint32_t i; 57*1316Smax.romanov@nginx.com uintptr_t go_req; 58*1316Smax.romanov@nginx.com nxt_cgo_str_t method, uri, name, value, proto, host, remote_addr; 59*1316Smax.romanov@nginx.com nxt_unit_field_t *f; 60*1316Smax.romanov@nginx.com nxt_unit_request_t *r; 61*1316Smax.romanov@nginx.com 62*1316Smax.romanov@nginx.com r = req->request; 63*1316Smax.romanov@nginx.com 64*1316Smax.romanov@nginx.com go_req = nxt_go_request_create((uintptr_t) req, 65*1316Smax.romanov@nginx.com nxt_cgo_str_init(&method, &r->method, r->method_length), 66*1316Smax.romanov@nginx.com nxt_cgo_str_init(&uri, &r->target, r->target_length)); 67*1316Smax.romanov@nginx.com 68*1316Smax.romanov@nginx.com nxt_go_request_set_proto(go_req, 69*1316Smax.romanov@nginx.com nxt_cgo_str_init(&proto, &r->version, r->version_length), 1, 1); 70*1316Smax.romanov@nginx.com 71*1316Smax.romanov@nginx.com for (i = 0; i < r->fields_count; i++) { 72*1316Smax.romanov@nginx.com f = &r->fields[i]; 73*1316Smax.romanov@nginx.com 74*1316Smax.romanov@nginx.com nxt_go_request_add_header(go_req, 75*1316Smax.romanov@nginx.com nxt_cgo_str_init(&name, &f->name, f->name_length), 76*1316Smax.romanov@nginx.com nxt_cgo_str_init(&value, &f->value, f->value_length)); 77*1316Smax.romanov@nginx.com } 78*1316Smax.romanov@nginx.com 79*1316Smax.romanov@nginx.com nxt_go_request_set_content_length(go_req, r->content_length); 80*1316Smax.romanov@nginx.com nxt_go_request_set_host(go_req, 81*1316Smax.romanov@nginx.com nxt_cgo_str_init(&host, &r->server_name, r->server_name_length)); 82*1316Smax.romanov@nginx.com nxt_go_request_set_remote_addr(go_req, 83*1316Smax.romanov@nginx.com nxt_cgo_str_init(&remote_addr, &r->remote, r->remote_length)); 84*1316Smax.romanov@nginx.com 85*1316Smax.romanov@nginx.com if (r->tls) { 86*1316Smax.romanov@nginx.com nxt_go_request_set_tls(go_req); 87*1316Smax.romanov@nginx.com } 88*1316Smax.romanov@nginx.com 89*1316Smax.romanov@nginx.com nxt_go_request_handler(go_req, (uintptr_t) req->unit->data); 90*1316Smax.romanov@nginx.com } 91*1316Smax.romanov@nginx.com 92*1316Smax.romanov@nginx.com 93*1316Smax.romanov@nginx.com static nxt_cgo_str_t * 94*1316Smax.romanov@nginx.com nxt_cgo_str_init(nxt_cgo_str_t *dst, nxt_unit_sptr_t *sptr, uint32_t length) 95*1316Smax.romanov@nginx.com { 96*1316Smax.romanov@nginx.com dst->length = length; 97*1316Smax.romanov@nginx.com dst->start = nxt_unit_sptr_get(sptr); 98*1316Smax.romanov@nginx.com 99*1316Smax.romanov@nginx.com return dst; 100*1316Smax.romanov@nginx.com } 101*1316Smax.romanov@nginx.com 102*1316Smax.romanov@nginx.com 103*1316Smax.romanov@nginx.com static int 104*1316Smax.romanov@nginx.com nxt_cgo_add_port(nxt_unit_ctx_t *ctx, nxt_unit_port_t *port) 105*1316Smax.romanov@nginx.com { 106*1316Smax.romanov@nginx.com nxt_go_add_port(port->id.pid, port->id.id, 107*1316Smax.romanov@nginx.com port->in_fd, port->out_fd); 108*1316Smax.romanov@nginx.com 109*1316Smax.romanov@nginx.com return nxt_unit_add_port(ctx, port); 110*1316Smax.romanov@nginx.com } 111*1316Smax.romanov@nginx.com 112*1316Smax.romanov@nginx.com 113*1316Smax.romanov@nginx.com static void 114*1316Smax.romanov@nginx.com nxt_cgo_remove_port(nxt_unit_ctx_t *ctx, nxt_unit_port_id_t *port_id) 115*1316Smax.romanov@nginx.com { 116*1316Smax.romanov@nginx.com nxt_go_remove_port(port_id->pid, port_id->id); 117*1316Smax.romanov@nginx.com 118*1316Smax.romanov@nginx.com nxt_unit_remove_port(ctx, port_id); 119*1316Smax.romanov@nginx.com } 120*1316Smax.romanov@nginx.com 121*1316Smax.romanov@nginx.com 122*1316Smax.romanov@nginx.com static ssize_t 123*1316Smax.romanov@nginx.com nxt_cgo_port_send(nxt_unit_ctx_t *ctx, nxt_unit_port_id_t *port_id, 124*1316Smax.romanov@nginx.com const void *buf, size_t buf_size, const void *oob, size_t oob_size) 125*1316Smax.romanov@nginx.com { 126*1316Smax.romanov@nginx.com return nxt_go_port_send(port_id->pid, port_id->id, 127*1316Smax.romanov@nginx.com (void *) buf, buf_size, (void *) oob, oob_size); 128*1316Smax.romanov@nginx.com } 129*1316Smax.romanov@nginx.com 130*1316Smax.romanov@nginx.com 131*1316Smax.romanov@nginx.com static ssize_t 132*1316Smax.romanov@nginx.com nxt_cgo_port_recv(nxt_unit_ctx_t *ctx, nxt_unit_port_id_t *port_id, 133*1316Smax.romanov@nginx.com void *buf, size_t buf_size, void *oob, size_t oob_size) 134*1316Smax.romanov@nginx.com { 135*1316Smax.romanov@nginx.com return nxt_go_port_recv(port_id->pid, port_id->id, 136*1316Smax.romanov@nginx.com buf, buf_size, oob, oob_size); 137*1316Smax.romanov@nginx.com } 138*1316Smax.romanov@nginx.com 139*1316Smax.romanov@nginx.com 140*1316Smax.romanov@nginx.com int 141*1316Smax.romanov@nginx.com nxt_cgo_response_create(uintptr_t req, int status, int fields, 142*1316Smax.romanov@nginx.com uint32_t fields_size) 143*1316Smax.romanov@nginx.com { 144*1316Smax.romanov@nginx.com return nxt_unit_response_init((nxt_unit_request_info_t *) req, 145*1316Smax.romanov@nginx.com status, fields, fields_size); 146*1316Smax.romanov@nginx.com } 147*1316Smax.romanov@nginx.com 148*1316Smax.romanov@nginx.com 149*1316Smax.romanov@nginx.com int 150*1316Smax.romanov@nginx.com nxt_cgo_response_add_field(uintptr_t req, uintptr_t name, uint8_t name_len, 151*1316Smax.romanov@nginx.com uintptr_t value, uint32_t value_len) 152*1316Smax.romanov@nginx.com { 153*1316Smax.romanov@nginx.com return nxt_unit_response_add_field((nxt_unit_request_info_t *) req, 154*1316Smax.romanov@nginx.com (char *) name, name_len, 155*1316Smax.romanov@nginx.com (char *) value, value_len); 156*1316Smax.romanov@nginx.com } 157*1316Smax.romanov@nginx.com 158*1316Smax.romanov@nginx.com 159*1316Smax.romanov@nginx.com int 160*1316Smax.romanov@nginx.com nxt_cgo_response_send(uintptr_t req) 161*1316Smax.romanov@nginx.com { 162*1316Smax.romanov@nginx.com return nxt_unit_response_send((nxt_unit_request_info_t *) req); 163*1316Smax.romanov@nginx.com } 164*1316Smax.romanov@nginx.com 165*1316Smax.romanov@nginx.com 166*1316Smax.romanov@nginx.com ssize_t 167*1316Smax.romanov@nginx.com nxt_cgo_response_write(uintptr_t req, uintptr_t start, uint32_t len) 168*1316Smax.romanov@nginx.com { 169*1316Smax.romanov@nginx.com int rc; 170*1316Smax.romanov@nginx.com 171*1316Smax.romanov@nginx.com rc = nxt_unit_response_write((nxt_unit_request_info_t *) req, 172*1316Smax.romanov@nginx.com (void *) start, len); 173*1316Smax.romanov@nginx.com if (rc != NXT_UNIT_OK) { 174*1316Smax.romanov@nginx.com return -1; 175*1316Smax.romanov@nginx.com } 176*1316Smax.romanov@nginx.com 177*1316Smax.romanov@nginx.com return len; 178*1316Smax.romanov@nginx.com } 179*1316Smax.romanov@nginx.com 180*1316Smax.romanov@nginx.com 181*1316Smax.romanov@nginx.com ssize_t 182*1316Smax.romanov@nginx.com nxt_cgo_request_read(uintptr_t req, uintptr_t dst, uint32_t dst_len) 183*1316Smax.romanov@nginx.com { 184*1316Smax.romanov@nginx.com return nxt_unit_request_read((nxt_unit_request_info_t *) req, 185*1316Smax.romanov@nginx.com (void *) dst, dst_len); 186*1316Smax.romanov@nginx.com } 187*1316Smax.romanov@nginx.com 188*1316Smax.romanov@nginx.com 189*1316Smax.romanov@nginx.com int 190*1316Smax.romanov@nginx.com nxt_cgo_request_close(uintptr_t req) 191*1316Smax.romanov@nginx.com { 192*1316Smax.romanov@nginx.com return 0; 193*1316Smax.romanov@nginx.com } 194*1316Smax.romanov@nginx.com 195*1316Smax.romanov@nginx.com 196*1316Smax.romanov@nginx.com void 197*1316Smax.romanov@nginx.com nxt_cgo_request_done(uintptr_t req, int res) 198*1316Smax.romanov@nginx.com { 199*1316Smax.romanov@nginx.com nxt_unit_request_done((nxt_unit_request_info_t *) req, res); 200*1316Smax.romanov@nginx.com } 201*1316Smax.romanov@nginx.com 202*1316Smax.romanov@nginx.com 203*1316Smax.romanov@nginx.com void 204*1316Smax.romanov@nginx.com nxt_cgo_warn(uintptr_t msg, uint32_t msg_len) 205*1316Smax.romanov@nginx.com { 206*1316Smax.romanov@nginx.com nxt_unit_warn(NULL, "%.*s", (int) msg_len, (char *) msg); 207*1316Smax.romanov@nginx.com } 208