diff options
Diffstat (limited to 'go/request.go')
-rw-r--r-- | go/request.go | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/go/request.go b/go/request.go new file mode 100644 index 00000000..1d8c6702 --- /dev/null +++ b/go/request.go @@ -0,0 +1,144 @@ +/* + * Copyright (C) Max Romanov + * Copyright (C) NGINX, Inc. + */ + +package unit + +/* +#include "nxt_cgo_lib.h" +*/ +import "C" + +import ( + "io" + "net/http" + "net/url" + "crypto/tls" + "unsafe" +) + +type request struct { + req http.Request + resp *response + c_req C.uintptr_t +} + +func (r *request) Read(p []byte) (n int, err error) { + res := C.nxt_cgo_request_read(r.c_req, buf_ref(p), C.uint32_t(len(p))) + + if res == 0 && len(p) > 0 { + return 0, io.EOF + } + + return int(res), nil +} + +func (r *request) Close() error { + C.nxt_cgo_request_close(r.c_req) + return nil +} + +func (r *request) response() *response { + if r.resp == nil { + r.resp = new_response(r.c_req, &r.req) + } + + return r.resp +} + +func (r *request) done() { + resp := r.response() + if !resp.headerSent { + resp.WriteHeader(http.StatusOK) + } + C.nxt_cgo_request_done(r.c_req, 0) +} + +func get_request(go_req uintptr) *request { + return (*request)(unsafe.Pointer(go_req)) +} + +//export nxt_go_request_create +func nxt_go_request_create(c_req C.uintptr_t, + c_method *C.nxt_cgo_str_t, c_uri *C.nxt_cgo_str_t) uintptr { + + uri := C.GoStringN(c_uri.start, c_uri.length) + + var URL *url.URL + var err error + if URL, err = url.ParseRequestURI(uri); err != nil { + return 0 + } + + r := &request{ + req: http.Request{ + Method: C.GoStringN(c_method.start, c_method.length), + URL: URL, + Header: http.Header{}, + Body: nil, + RequestURI: uri, + }, + c_req: c_req, + } + r.req.Body = r + + return uintptr(unsafe.Pointer(r)) +} + +//export nxt_go_request_set_proto +func nxt_go_request_set_proto(go_req uintptr, proto *C.nxt_cgo_str_t, + maj C.int, min C.int) { + + r := get_request(go_req) + r.req.Proto = C.GoStringN(proto.start, proto.length) + r.req.ProtoMajor = int(maj) + r.req.ProtoMinor = int(min) +} + +//export nxt_go_request_add_header +func nxt_go_request_add_header(go_req uintptr, name *C.nxt_cgo_str_t, + value *C.nxt_cgo_str_t) { + + r := get_request(go_req) + r.req.Header.Add(C.GoStringN(name.start, name.length), + C.GoStringN(value.start, value.length)) +} + +//export nxt_go_request_set_content_length +func nxt_go_request_set_content_length(go_req uintptr, l C.int64_t) { + get_request(go_req).req.ContentLength = int64(l) +} + +//export nxt_go_request_set_host +func nxt_go_request_set_host(go_req uintptr, host *C.nxt_cgo_str_t) { + get_request(go_req).req.Host = C.GoStringN(host.start, host.length) +} + +//export nxt_go_request_set_url +func nxt_go_request_set_url(go_req uintptr, scheme *C.char) { + get_request(go_req).req.URL.Scheme = C.GoString(scheme) +} + +//export nxt_go_request_set_remote_addr +func nxt_go_request_set_remote_addr(go_req uintptr, addr *C.nxt_cgo_str_t) { + + get_request(go_req).req.RemoteAddr = C.GoStringN(addr.start, addr.length) +} + +//export nxt_go_request_set_tls +func nxt_go_request_set_tls(go_req uintptr) { + + get_request(go_req).req.TLS = &tls.ConnectionState{ } +} + +//export nxt_go_request_handler +func nxt_go_request_handler(go_req uintptr, h uintptr) { + r := get_request(go_req) + handler := get_handler(h) + + go func(r *request) { + handler.ServeHTTP(r.response(), &r.req) + r.done() + }(r) +} |