1*1316Smax.romanov@nginx.com/* 2*1316Smax.romanov@nginx.com * Copyright (C) Max Romanov 3*1316Smax.romanov@nginx.com * Copyright (C) NGINX, Inc. 4*1316Smax.romanov@nginx.com */ 5*1316Smax.romanov@nginx.com 6*1316Smax.romanov@nginx.compackage unit 7*1316Smax.romanov@nginx.com 8*1316Smax.romanov@nginx.com/* 9*1316Smax.romanov@nginx.com#include "nxt_cgo_lib.h" 10*1316Smax.romanov@nginx.com*/ 11*1316Smax.romanov@nginx.comimport "C" 12*1316Smax.romanov@nginx.com 13*1316Smax.romanov@nginx.comimport ( 14*1316Smax.romanov@nginx.com "io" 15*1316Smax.romanov@nginx.com "net/http" 16*1316Smax.romanov@nginx.com "net/url" 17*1316Smax.romanov@nginx.com "crypto/tls" 18*1316Smax.romanov@nginx.com "unsafe" 19*1316Smax.romanov@nginx.com) 20*1316Smax.romanov@nginx.com 21*1316Smax.romanov@nginx.comtype request struct { 22*1316Smax.romanov@nginx.com req http.Request 23*1316Smax.romanov@nginx.com resp *response 24*1316Smax.romanov@nginx.com c_req C.uintptr_t 25*1316Smax.romanov@nginx.com} 26*1316Smax.romanov@nginx.com 27*1316Smax.romanov@nginx.comfunc (r *request) Read(p []byte) (n int, err error) { 28*1316Smax.romanov@nginx.com res := C.nxt_cgo_request_read(r.c_req, buf_ref(p), C.uint32_t(len(p))) 29*1316Smax.romanov@nginx.com 30*1316Smax.romanov@nginx.com if res == 0 && len(p) > 0 { 31*1316Smax.romanov@nginx.com return 0, io.EOF 32*1316Smax.romanov@nginx.com } 33*1316Smax.romanov@nginx.com 34*1316Smax.romanov@nginx.com return int(res), nil 35*1316Smax.romanov@nginx.com} 36*1316Smax.romanov@nginx.com 37*1316Smax.romanov@nginx.comfunc (r *request) Close() error { 38*1316Smax.romanov@nginx.com C.nxt_cgo_request_close(r.c_req) 39*1316Smax.romanov@nginx.com return nil 40*1316Smax.romanov@nginx.com} 41*1316Smax.romanov@nginx.com 42*1316Smax.romanov@nginx.comfunc (r *request) response() *response { 43*1316Smax.romanov@nginx.com if r.resp == nil { 44*1316Smax.romanov@nginx.com r.resp = new_response(r.c_req, &r.req) 45*1316Smax.romanov@nginx.com } 46*1316Smax.romanov@nginx.com 47*1316Smax.romanov@nginx.com return r.resp 48*1316Smax.romanov@nginx.com} 49*1316Smax.romanov@nginx.com 50*1316Smax.romanov@nginx.comfunc (r *request) done() { 51*1316Smax.romanov@nginx.com resp := r.response() 52*1316Smax.romanov@nginx.com if !resp.headerSent { 53*1316Smax.romanov@nginx.com resp.WriteHeader(http.StatusOK) 54*1316Smax.romanov@nginx.com } 55*1316Smax.romanov@nginx.com C.nxt_cgo_request_done(r.c_req, 0) 56*1316Smax.romanov@nginx.com} 57*1316Smax.romanov@nginx.com 58*1316Smax.romanov@nginx.comfunc get_request(go_req uintptr) *request { 59*1316Smax.romanov@nginx.com return (*request)(unsafe.Pointer(go_req)) 60*1316Smax.romanov@nginx.com} 61*1316Smax.romanov@nginx.com 62*1316Smax.romanov@nginx.com//export nxt_go_request_create 63*1316Smax.romanov@nginx.comfunc nxt_go_request_create(c_req C.uintptr_t, 64*1316Smax.romanov@nginx.com c_method *C.nxt_cgo_str_t, c_uri *C.nxt_cgo_str_t) uintptr { 65*1316Smax.romanov@nginx.com 66*1316Smax.romanov@nginx.com uri := C.GoStringN(c_uri.start, c_uri.length) 67*1316Smax.romanov@nginx.com 68*1316Smax.romanov@nginx.com var URL *url.URL 69*1316Smax.romanov@nginx.com var err error 70*1316Smax.romanov@nginx.com if URL, err = url.ParseRequestURI(uri); err != nil { 71*1316Smax.romanov@nginx.com return 0 72*1316Smax.romanov@nginx.com } 73*1316Smax.romanov@nginx.com 74*1316Smax.romanov@nginx.com r := &request{ 75*1316Smax.romanov@nginx.com req: http.Request{ 76*1316Smax.romanov@nginx.com Method: C.GoStringN(c_method.start, c_method.length), 77*1316Smax.romanov@nginx.com URL: URL, 78*1316Smax.romanov@nginx.com Header: http.Header{}, 79*1316Smax.romanov@nginx.com Body: nil, 80*1316Smax.romanov@nginx.com RequestURI: uri, 81*1316Smax.romanov@nginx.com }, 82*1316Smax.romanov@nginx.com c_req: c_req, 83*1316Smax.romanov@nginx.com } 84*1316Smax.romanov@nginx.com r.req.Body = r 85*1316Smax.romanov@nginx.com 86*1316Smax.romanov@nginx.com return uintptr(unsafe.Pointer(r)) 87*1316Smax.romanov@nginx.com} 88*1316Smax.romanov@nginx.com 89*1316Smax.romanov@nginx.com//export nxt_go_request_set_proto 90*1316Smax.romanov@nginx.comfunc nxt_go_request_set_proto(go_req uintptr, proto *C.nxt_cgo_str_t, 91*1316Smax.romanov@nginx.com maj C.int, min C.int) { 92*1316Smax.romanov@nginx.com 93*1316Smax.romanov@nginx.com r := get_request(go_req) 94*1316Smax.romanov@nginx.com r.req.Proto = C.GoStringN(proto.start, proto.length) 95*1316Smax.romanov@nginx.com r.req.ProtoMajor = int(maj) 96*1316Smax.romanov@nginx.com r.req.ProtoMinor = int(min) 97*1316Smax.romanov@nginx.com} 98*1316Smax.romanov@nginx.com 99*1316Smax.romanov@nginx.com//export nxt_go_request_add_header 100*1316Smax.romanov@nginx.comfunc nxt_go_request_add_header(go_req uintptr, name *C.nxt_cgo_str_t, 101*1316Smax.romanov@nginx.com value *C.nxt_cgo_str_t) { 102*1316Smax.romanov@nginx.com 103*1316Smax.romanov@nginx.com r := get_request(go_req) 104*1316Smax.romanov@nginx.com r.req.Header.Add(C.GoStringN(name.start, name.length), 105*1316Smax.romanov@nginx.com C.GoStringN(value.start, value.length)) 106*1316Smax.romanov@nginx.com} 107*1316Smax.romanov@nginx.com 108*1316Smax.romanov@nginx.com//export nxt_go_request_set_content_length 109*1316Smax.romanov@nginx.comfunc nxt_go_request_set_content_length(go_req uintptr, l C.int64_t) { 110*1316Smax.romanov@nginx.com get_request(go_req).req.ContentLength = int64(l) 111*1316Smax.romanov@nginx.com} 112*1316Smax.romanov@nginx.com 113*1316Smax.romanov@nginx.com//export nxt_go_request_set_host 114*1316Smax.romanov@nginx.comfunc nxt_go_request_set_host(go_req uintptr, host *C.nxt_cgo_str_t) { 115*1316Smax.romanov@nginx.com get_request(go_req).req.Host = C.GoStringN(host.start, host.length) 116*1316Smax.romanov@nginx.com} 117*1316Smax.romanov@nginx.com 118*1316Smax.romanov@nginx.com//export nxt_go_request_set_url 119*1316Smax.romanov@nginx.comfunc nxt_go_request_set_url(go_req uintptr, scheme *C.char) { 120*1316Smax.romanov@nginx.com get_request(go_req).req.URL.Scheme = C.GoString(scheme) 121*1316Smax.romanov@nginx.com} 122*1316Smax.romanov@nginx.com 123*1316Smax.romanov@nginx.com//export nxt_go_request_set_remote_addr 124*1316Smax.romanov@nginx.comfunc nxt_go_request_set_remote_addr(go_req uintptr, addr *C.nxt_cgo_str_t) { 125*1316Smax.romanov@nginx.com 126*1316Smax.romanov@nginx.com get_request(go_req).req.RemoteAddr = C.GoStringN(addr.start, addr.length) 127*1316Smax.romanov@nginx.com} 128*1316Smax.romanov@nginx.com 129*1316Smax.romanov@nginx.com//export nxt_go_request_set_tls 130*1316Smax.romanov@nginx.comfunc nxt_go_request_set_tls(go_req uintptr) { 131*1316Smax.romanov@nginx.com 132*1316Smax.romanov@nginx.com get_request(go_req).req.TLS = &tls.ConnectionState{ } 133*1316Smax.romanov@nginx.com} 134*1316Smax.romanov@nginx.com 135*1316Smax.romanov@nginx.com//export nxt_go_request_handler 136*1316Smax.romanov@nginx.comfunc nxt_go_request_handler(go_req uintptr, h uintptr) { 137*1316Smax.romanov@nginx.com r := get_request(go_req) 138*1316Smax.romanov@nginx.com handler := get_handler(h) 139*1316Smax.romanov@nginx.com 140*1316Smax.romanov@nginx.com go func(r *request) { 141*1316Smax.romanov@nginx.com handler.ServeHTTP(r.response(), &r.req) 142*1316Smax.romanov@nginx.com r.done() 143*1316Smax.romanov@nginx.com }(r) 144*1316Smax.romanov@nginx.com} 145