1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
/*
* Copyright (C) Max Romanov
* Copyright (C) NGINX, Inc.
*/
package nginext
/*
#include "nxt_go_lib.h"
*/
import "C"
import (
"fmt"
"net/http"
"os"
"strconv"
"strings"
"unsafe"
)
type cbuf struct {
b unsafe.Pointer
s C.size_t
f bool
}
func new_cbuf(buf []byte) *cbuf {
if len(buf) == 0 {
return nil
}
return &cbuf{
getCBytes(buf), C.size_t(len(buf)), true,
}
}
func (buf *cbuf) Close() {
if buf == nil {
return
}
if buf.f && buf.s > 0 {
C.free(buf.b)
buf.f = false
buf.b = nil
buf.s = 0
}
}
func (buf *cbuf) GoBytes() []byte {
if buf == nil {
var b [0]byte
return b[:0]
}
return C.GoBytes(buf.b, C.int(buf.s))
}
type cmsg struct {
buf cbuf
oob cbuf
}
func new_cmsg(buf []byte, oob []byte) *cmsg {
return &cmsg{
buf: cbuf{getCBytes(buf), C.size_t(len(buf)), true},
oob: cbuf{getCBytes(oob), C.size_t(len(oob)), true},
}
}
func (msg *cmsg) Close() {
msg.buf.Close()
msg.oob.Close()
}
var nxt_go_quit bool = false
//export nxt_go_set_quit
func nxt_go_set_quit() {
nxt_go_quit = true
}
func ListenAndServe(addr string, handler http.Handler) error {
var read_port *port
go_ports_env := os.Getenv("NXT_GO_PORTS")
ports := strings.Split(go_ports_env, ";")
pid := os.Getpid()
for _, port_str := range ports {
if len(port_str) <= 0 {
continue
}
attrs := strings.Split(port_str, ",")
var attrsN [5]int
var err error
for i, attr := range attrs {
attrsN[i], err = strconv.Atoi(attr)
if err != nil {
fmt.Printf("err %s\n", err)
break
}
}
if err != nil {
continue
}
p := new_port(attrsN[0], attrsN[1], attrsN[2], attrsN[3], attrsN[4])
if attrsN[0] == pid {
read_port = p
}
}
if read_port != nil {
C.nxt_go_ready()
for !nxt_go_quit {
err := read_port.read(handler)
if err != nil {
return err
}
}
} else {
return http.ListenAndServe(addr, handler)
}
return nil
}
|