/*
* Copyright (C) Max Romanov
* Copyright (C) NGINX, Inc.
*/
package unit
/*
#include "nxt_go_lib.h"
*/
import "C"
import (
"io"
"net/http"
"net/url"
"unsafe"
)
type request struct {
req http.Request
resp *response
c_req C.nxt_go_request_t
id C.uint32_t
}
func (r *request) Read(p []byte) (n int, err error) {
c := C.size_t(len(p))
b := C.uintptr_t(uintptr(unsafe.Pointer(&p[0])))
res := C.nxt_go_request_read(r.c_req, b, c)
if res == 0 && len(p) > 0 {
return 0, io.EOF
}
return int(res), nil
}
func (r *request) Close() error {
C.nxt_go_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_go_request_done(r.c_req)
}
func get_request(go_req C.nxt_go_request_t) *request {
return (*request)(unsafe.Pointer(uintptr(go_req)))
}
//export nxt_go_new_request
func nxt_go_new_request(c_req C.nxt_go_request_t, id C.uint32_t,
c_method *C.nxt_go_str_t, c_uri *C.nxt_go_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,
id: id,
}
r.req.Body = r
return uintptr(unsafe.Pointer(r))
}
//export nxt_go_request_set_proto
func nxt_go_request_set_proto(go_req C.nxt_go_request_t, proto *C.nxt_go_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 C.nxt_go_request_t, name *C.nxt_go_str_t,
value *C.nxt_go_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 C.nxt_go_request_t, 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 C.nxt_go_request_t, host *C.nxt_go_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 C.nxt_go_request_t, 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 C.nxt_go_request_t,
addr *C.nxt_go_str_t) {
get_request(go_req).req.RemoteAddr = C.GoStringN(addr.start, addr.length)
}