11316Smax.romanov@nginx.com 21316Smax.romanov@nginx.com /* 31316Smax.romanov@nginx.com * Copyright (C) Max Romanov 41316Smax.romanov@nginx.com * Copyright (C) NGINX, Inc. 51316Smax.romanov@nginx.com */ 61316Smax.romanov@nginx.com 71316Smax.romanov@nginx.com #include "_cgo_export.h" 81316Smax.romanov@nginx.com 91316Smax.romanov@nginx.com #include <nxt_unit.h> 101316Smax.romanov@nginx.com #include <nxt_unit_request.h> 111316Smax.romanov@nginx.com 121316Smax.romanov@nginx.com 131316Smax.romanov@nginx.com static void nxt_cgo_request_handler(nxt_unit_request_info_t *req); 141316Smax.romanov@nginx.com static nxt_cgo_str_t *nxt_cgo_str_init(nxt_cgo_str_t *dst, 151316Smax.romanov@nginx.com nxt_unit_sptr_t *sptr, uint32_t length); 161316Smax.romanov@nginx.com static int nxt_cgo_add_port(nxt_unit_ctx_t *, nxt_unit_port_t *port); 171543Smax.romanov@nginx.com static void nxt_cgo_remove_port(nxt_unit_t *, nxt_unit_port_t *port); 18*1544Smax.romanov@nginx.com static ssize_t nxt_cgo_port_send(nxt_unit_ctx_t *, nxt_unit_port_t *port, 191316Smax.romanov@nginx.com const void *buf, size_t buf_size, const void *oob, size_t oob_size); 20*1544Smax.romanov@nginx.com static ssize_t nxt_cgo_port_recv(nxt_unit_ctx_t *, nxt_unit_port_t *port, 211316Smax.romanov@nginx.com void *buf, size_t buf_size, void *oob, size_t oob_size); 221323Smax.romanov@nginx.com static void nxt_cgo_shm_ack_handler(nxt_unit_ctx_t *ctx); 231316Smax.romanov@nginx.com 241316Smax.romanov@nginx.com int 251316Smax.romanov@nginx.com nxt_cgo_run(uintptr_t handler) 261316Smax.romanov@nginx.com { 271316Smax.romanov@nginx.com int rc; 281316Smax.romanov@nginx.com nxt_unit_ctx_t *ctx; 291316Smax.romanov@nginx.com nxt_unit_init_t init; 301316Smax.romanov@nginx.com 311316Smax.romanov@nginx.com memset(&init, 0, sizeof(init)); 321316Smax.romanov@nginx.com 331316Smax.romanov@nginx.com init.callbacks.request_handler = nxt_cgo_request_handler; 341316Smax.romanov@nginx.com init.callbacks.add_port = nxt_cgo_add_port; 351316Smax.romanov@nginx.com init.callbacks.remove_port = nxt_cgo_remove_port; 361316Smax.romanov@nginx.com init.callbacks.port_send = nxt_cgo_port_send; 371316Smax.romanov@nginx.com init.callbacks.port_recv = nxt_cgo_port_recv; 381323Smax.romanov@nginx.com init.callbacks.shm_ack_handler = nxt_cgo_shm_ack_handler; 391316Smax.romanov@nginx.com 401316Smax.romanov@nginx.com init.data = (void *) handler; 411316Smax.romanov@nginx.com 421316Smax.romanov@nginx.com ctx = nxt_unit_init(&init); 431316Smax.romanov@nginx.com if (ctx == NULL) { 441316Smax.romanov@nginx.com return NXT_UNIT_ERROR; 451316Smax.romanov@nginx.com } 461316Smax.romanov@nginx.com 471316Smax.romanov@nginx.com rc = nxt_unit_run(ctx); 481316Smax.romanov@nginx.com 491316Smax.romanov@nginx.com nxt_unit_done(ctx); 501316Smax.romanov@nginx.com 511316Smax.romanov@nginx.com return rc; 521316Smax.romanov@nginx.com } 531316Smax.romanov@nginx.com 541316Smax.romanov@nginx.com 551316Smax.romanov@nginx.com static void 561316Smax.romanov@nginx.com nxt_cgo_request_handler(nxt_unit_request_info_t *req) 571316Smax.romanov@nginx.com { 581316Smax.romanov@nginx.com uint32_t i; 591316Smax.romanov@nginx.com uintptr_t go_req; 601316Smax.romanov@nginx.com nxt_cgo_str_t method, uri, name, value, proto, host, remote_addr; 611316Smax.romanov@nginx.com nxt_unit_field_t *f; 621316Smax.romanov@nginx.com nxt_unit_request_t *r; 631316Smax.romanov@nginx.com 641316Smax.romanov@nginx.com r = req->request; 651316Smax.romanov@nginx.com 661316Smax.romanov@nginx.com go_req = nxt_go_request_create((uintptr_t) req, 671316Smax.romanov@nginx.com nxt_cgo_str_init(&method, &r->method, r->method_length), 681316Smax.romanov@nginx.com nxt_cgo_str_init(&uri, &r->target, r->target_length)); 691316Smax.romanov@nginx.com 701316Smax.romanov@nginx.com nxt_go_request_set_proto(go_req, 711316Smax.romanov@nginx.com nxt_cgo_str_init(&proto, &r->version, r->version_length), 1, 1); 721316Smax.romanov@nginx.com 731316Smax.romanov@nginx.com for (i = 0; i < r->fields_count; i++) { 741316Smax.romanov@nginx.com f = &r->fields[i]; 751316Smax.romanov@nginx.com 761316Smax.romanov@nginx.com nxt_go_request_add_header(go_req, 771316Smax.romanov@nginx.com nxt_cgo_str_init(&name, &f->name, f->name_length), 781316Smax.romanov@nginx.com nxt_cgo_str_init(&value, &f->value, f->value_length)); 791316Smax.romanov@nginx.com } 801316Smax.romanov@nginx.com 811316Smax.romanov@nginx.com nxt_go_request_set_content_length(go_req, r->content_length); 821316Smax.romanov@nginx.com nxt_go_request_set_host(go_req, 831316Smax.romanov@nginx.com nxt_cgo_str_init(&host, &r->server_name, r->server_name_length)); 841316Smax.romanov@nginx.com nxt_go_request_set_remote_addr(go_req, 851316Smax.romanov@nginx.com nxt_cgo_str_init(&remote_addr, &r->remote, r->remote_length)); 861316Smax.romanov@nginx.com 871316Smax.romanov@nginx.com if (r->tls) { 881316Smax.romanov@nginx.com nxt_go_request_set_tls(go_req); 891316Smax.romanov@nginx.com } 901316Smax.romanov@nginx.com 911316Smax.romanov@nginx.com nxt_go_request_handler(go_req, (uintptr_t) req->unit->data); 921316Smax.romanov@nginx.com } 931316Smax.romanov@nginx.com 941316Smax.romanov@nginx.com 951316Smax.romanov@nginx.com static nxt_cgo_str_t * 961316Smax.romanov@nginx.com nxt_cgo_str_init(nxt_cgo_str_t *dst, nxt_unit_sptr_t *sptr, uint32_t length) 971316Smax.romanov@nginx.com { 981316Smax.romanov@nginx.com dst->length = length; 991316Smax.romanov@nginx.com dst->start = nxt_unit_sptr_get(sptr); 1001316Smax.romanov@nginx.com 1011316Smax.romanov@nginx.com return dst; 1021316Smax.romanov@nginx.com } 1031316Smax.romanov@nginx.com 1041316Smax.romanov@nginx.com 1051316Smax.romanov@nginx.com static int 1061316Smax.romanov@nginx.com nxt_cgo_add_port(nxt_unit_ctx_t *ctx, nxt_unit_port_t *port) 1071316Smax.romanov@nginx.com { 1081316Smax.romanov@nginx.com nxt_go_add_port(port->id.pid, port->id.id, 1091316Smax.romanov@nginx.com port->in_fd, port->out_fd); 1101316Smax.romanov@nginx.com 1111543Smax.romanov@nginx.com port->in_fd = -1; 1121543Smax.romanov@nginx.com port->out_fd = -1; 1131543Smax.romanov@nginx.com 1141543Smax.romanov@nginx.com return NXT_UNIT_OK; 1151316Smax.romanov@nginx.com } 1161316Smax.romanov@nginx.com 1171316Smax.romanov@nginx.com 1181316Smax.romanov@nginx.com static void 1191543Smax.romanov@nginx.com nxt_cgo_remove_port(nxt_unit_t *unit, nxt_unit_port_t *port) 1201316Smax.romanov@nginx.com { 1211543Smax.romanov@nginx.com nxt_go_remove_port(port->id.pid, port->id.id); 1221316Smax.romanov@nginx.com } 1231316Smax.romanov@nginx.com 1241316Smax.romanov@nginx.com 1251316Smax.romanov@nginx.com static ssize_t 126*1544Smax.romanov@nginx.com nxt_cgo_port_send(nxt_unit_ctx_t *ctx, nxt_unit_port_t *port, 1271316Smax.romanov@nginx.com const void *buf, size_t buf_size, const void *oob, size_t oob_size) 1281316Smax.romanov@nginx.com { 129*1544Smax.romanov@nginx.com return nxt_go_port_send(port->id.pid, port->id.id, 1301316Smax.romanov@nginx.com (void *) buf, buf_size, (void *) oob, oob_size); 1311316Smax.romanov@nginx.com } 1321316Smax.romanov@nginx.com 1331316Smax.romanov@nginx.com 1341316Smax.romanov@nginx.com static ssize_t 135*1544Smax.romanov@nginx.com nxt_cgo_port_recv(nxt_unit_ctx_t *ctx, nxt_unit_port_t *port, 1361316Smax.romanov@nginx.com void *buf, size_t buf_size, void *oob, size_t oob_size) 1371316Smax.romanov@nginx.com { 138*1544Smax.romanov@nginx.com return nxt_go_port_recv(port->id.pid, port->id.id, 1391316Smax.romanov@nginx.com buf, buf_size, oob, oob_size); 1401316Smax.romanov@nginx.com } 1411316Smax.romanov@nginx.com 1421316Smax.romanov@nginx.com 1431323Smax.romanov@nginx.com static void 1441323Smax.romanov@nginx.com nxt_cgo_shm_ack_handler(nxt_unit_ctx_t *ctx) 1451323Smax.romanov@nginx.com { 1461323Smax.romanov@nginx.com return nxt_go_shm_ack_handler(); 1471323Smax.romanov@nginx.com } 1481323Smax.romanov@nginx.com 1491323Smax.romanov@nginx.com 1501316Smax.romanov@nginx.com int 1511316Smax.romanov@nginx.com nxt_cgo_response_create(uintptr_t req, int status, int fields, 1521316Smax.romanov@nginx.com uint32_t fields_size) 1531316Smax.romanov@nginx.com { 1541316Smax.romanov@nginx.com return nxt_unit_response_init((nxt_unit_request_info_t *) req, 1551316Smax.romanov@nginx.com status, fields, fields_size); 1561316Smax.romanov@nginx.com } 1571316Smax.romanov@nginx.com 1581316Smax.romanov@nginx.com 1591316Smax.romanov@nginx.com int 1601316Smax.romanov@nginx.com nxt_cgo_response_add_field(uintptr_t req, uintptr_t name, uint8_t name_len, 1611316Smax.romanov@nginx.com uintptr_t value, uint32_t value_len) 1621316Smax.romanov@nginx.com { 1631316Smax.romanov@nginx.com return nxt_unit_response_add_field((nxt_unit_request_info_t *) req, 1641316Smax.romanov@nginx.com (char *) name, name_len, 1651316Smax.romanov@nginx.com (char *) value, value_len); 1661316Smax.romanov@nginx.com } 1671316Smax.romanov@nginx.com 1681316Smax.romanov@nginx.com 1691316Smax.romanov@nginx.com int 1701316Smax.romanov@nginx.com nxt_cgo_response_send(uintptr_t req) 1711316Smax.romanov@nginx.com { 1721316Smax.romanov@nginx.com return nxt_unit_response_send((nxt_unit_request_info_t *) req); 1731316Smax.romanov@nginx.com } 1741316Smax.romanov@nginx.com 1751316Smax.romanov@nginx.com 1761316Smax.romanov@nginx.com ssize_t 1771316Smax.romanov@nginx.com nxt_cgo_response_write(uintptr_t req, uintptr_t start, uint32_t len) 1781316Smax.romanov@nginx.com { 1791323Smax.romanov@nginx.com return nxt_unit_response_write_nb((nxt_unit_request_info_t *) req, 1801323Smax.romanov@nginx.com (void *) start, len, 0); 1811316Smax.romanov@nginx.com } 1821316Smax.romanov@nginx.com 1831316Smax.romanov@nginx.com 1841316Smax.romanov@nginx.com ssize_t 1851316Smax.romanov@nginx.com nxt_cgo_request_read(uintptr_t req, uintptr_t dst, uint32_t dst_len) 1861316Smax.romanov@nginx.com { 1871316Smax.romanov@nginx.com return nxt_unit_request_read((nxt_unit_request_info_t *) req, 1881316Smax.romanov@nginx.com (void *) dst, dst_len); 1891316Smax.romanov@nginx.com } 1901316Smax.romanov@nginx.com 1911316Smax.romanov@nginx.com 1921316Smax.romanov@nginx.com int 1931316Smax.romanov@nginx.com nxt_cgo_request_close(uintptr_t req) 1941316Smax.romanov@nginx.com { 1951316Smax.romanov@nginx.com return 0; 1961316Smax.romanov@nginx.com } 1971316Smax.romanov@nginx.com 1981316Smax.romanov@nginx.com 1991316Smax.romanov@nginx.com void 2001316Smax.romanov@nginx.com nxt_cgo_request_done(uintptr_t req, int res) 2011316Smax.romanov@nginx.com { 2021316Smax.romanov@nginx.com nxt_unit_request_done((nxt_unit_request_info_t *) req, res); 2031316Smax.romanov@nginx.com } 2041316Smax.romanov@nginx.com 2051316Smax.romanov@nginx.com 2061316Smax.romanov@nginx.com void 2071316Smax.romanov@nginx.com nxt_cgo_warn(uintptr_t msg, uint32_t msg_len) 2081316Smax.romanov@nginx.com { 2091316Smax.romanov@nginx.com nxt_unit_warn(NULL, "%.*s", (int) msg_len, (char *) msg); 2101316Smax.romanov@nginx.com } 211