xref: /unit/go/nxt_cgo_lib.c (revision 1544)
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