-
Notifications
You must be signed in to change notification settings - Fork 2
/
http.go
145 lines (123 loc) · 2.83 KB
/
http.go
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
135
136
137
138
139
140
141
142
143
144
145
package purr
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"strings"
lua "github.com/yuin/gopher-lua"
)
var interlHost string
//SetInternalHost set http request host
func SetInternalHost(host string) {
interlHost = host
}
var httpExports = map[string]lua.LGFunction{
"request": httpRequest,
"get": httpGet,
"post": httpPost,
"put": httpPut,
"head": httpHead,
"delete": httpDelete,
}
func getBody(n int, L *lua.LState) io.Reader {
bodyVal := L.CheckAny(n)
switch bodyVal.Type() {
case lua.LTString:
lstr, _ := bodyVal.(lua.LString)
return strings.NewReader(string(lstr))
case lua.LTTable:
jsonBody, err := valueToJSON(bodyVal)
if err != nil {
L.ArgError(3, "Marshal json error, msg is: "+err.Error())
break
}
return bytes.NewReader(jsonBody)
case lua.LTUserData:
ud := bodyVal.(*lua.LUserData)
reader, ok := ud.Value.(io.Reader)
if !ok {
L.ArgError(3, "io.Reader interface expected.")
break
}
return reader
}
return nil
}
func doRequest(method string, L *lua.LState) int {
method = strings.ToUpper(method)
urlStr := strings.TrimSpace(L.CheckString(1))
urlStr = interlHost + urlStr
fmt.Printf("Request URL is: %s, Method is %s\n", urlStr, method)
var err error
var req *http.Request
if L.GetTop() == 3 {
body := getBody(3, L)
req, err = http.NewRequest(method, urlStr, body)
} else {
req, err = http.NewRequest(method, urlStr, nil)
}
if L.GetTop() >= 2 {
tb := L.CheckTable(2)
tb.ForEach(func(k lua.LValue, val lua.LValue) {
req.Header.Add(k.String(), val.String())
})
}
if err != nil {
L.RaiseError("Call http.NewRequest error, msg is %s", err.Error())
return 0
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
L.RaiseError("Call Do request error, msg is %s", err.Error())
return 0
}
defer resp.Body.Close()
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
L.RaiseError("Call ioutil.ReadAll error, msg is %s", err.Error())
return 0
}
//return status code
L.Push(lua.LNumber(resp.StatusCode))
//return response header
var responseHeader = new(lua.LTable)
for k, vs := range resp.Header {
str := k + ": "
for i, v := range vs {
if i != 0 {
str += "; " + v
} else {
str += v
}
}
responseHeader.RawSetString(k, lua.LString(str))
}
L.Push(responseHeader)
ud := L.NewUserData()
ud.Value = bytes.NewBuffer(respBody)
//resturn response body
L.Push(ud)
return 3
}
func httpRequest(L *lua.LState) int {
method := L.CheckString(1)
L.Remove(1)
return doRequest(method, L)
}
func httpGet(L *lua.LState) int {
return doRequest("GET", L)
}
func httpPost(L *lua.LState) int {
return doRequest("POST", L)
}
func httpPut(L *lua.LState) int {
return doRequest("PUT", L)
}
func httpHead(L *lua.LState) int {
return doRequest("HEAD", L)
}
func httpDelete(L *lua.LState) int {
return doRequest("DELETE", L)
}