xref: /unit/go/request.go (revision 1316)
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