-
Notifications
You must be signed in to change notification settings - Fork 0
/
request.go
260 lines (226 loc) · 8.09 KB
/
request.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
package rider
import (
"errors"
"io/ioutil"
"net"
"net/http"
"net/url"
"path/filepath"
"strings"
"github.com/hypwxm/rider/utils/cryptos"
)
type Requester interface {
NewRequest(r *http.Request) *Request //用传入的request生成一个Request
load(r *http.Request) *Request //初始化一个requset
release() //重制Request,销毁变量,放入pool
RequestID() string //获取请求的id
query() url.Values //获取请求url里面的参数部分(单个值查询请用QueryString)
RawQuery() string //获取请求的原始字符串 a=1&b=2
FormFile(key string) (*UploadFile, error) //请求头为multipart/form-data时获取key字段域的第一个文件
FormFiles(key string) ([]*UploadFile, error) //请求头为multipart/form-data时获取key字段域的文件列表
StoreFormFile(file *UploadFile, fileName string) (int64, error) //FormFile返回一个文件,然后传入这里的第一个参数,保存到fileName文件
StoreFormFiles(files []*UploadFile, path string) ([]string, error) //FormFile返回文件列表,传入第一个参数,保存的文件名是随机的字符串,后缀名取文件上传时的本身后缀名
form() url.Values //获取url和body里面的参数。同名参数,body的值会排在前名
body() url.Values //获取请求体的参数,不包括文件,不包括url参数
ContentType() string //获取请求体的content-type
Header(key string) http.Header //获取请求头信息
ClientIP() string //获取远程请求者的ip地址,会获取源地址(非代理地址)
Path() string //获取请求的url路径
IsAJAX() bool //验证请求是否为ajax请求
Url() string //获取完整的请求路径 /x/x/a?a=x&c=s
Method() string //获取请求的方法
Params() map[string]string //获取请求的路径参数
Param(key string) string //获取某个请求路径参数的值(参数定义时的字段请勿重复,后面的直接覆盖之前的值)
}
type Request struct {
request *http.Request
requestID string
params map[string]string
pathParams []string
}
func NewRequest(r *http.Request) *Request {
request := basePool.request.Get().(*Request)
return request.load(r)
}
//装载request的参数
func (req *Request) load(r *http.Request) *Request {
req.request = r
req.params = make(map[string]string, 4)
req.requestID = cryptos.RandString()
return req
}
func (req *Request) release() {
req.request = nil
req.params = nil
req.requestID = ""
req.pathParams = []string{}
}
func (req *Request) Req() *http.Request {
return req.request
}
// RequestID get unique ID with current request
func (req *Request) RequestID() string {
return req.requestID
}
// QueryStrings 返回查询字符串map表示
func (req *Request) query() url.Values {
return req.request.URL.Query()
}
//获取完整uri
func (req *Request) RequestURI() string {
return req.request.RequestURI
}
/*
* 获取原始查询字符串 a=b&c=d
*/
func (req *Request) RawQuery() string {
return req.request.URL.RawQuery
}
//当客户端的请求头的content-type为multipart/form-data时获取请求体内的文件
//要获取请求传过来的文件,必须先调用r.parseMultipartForm(调用r.FormFile时会自动调用r.parseMultipartForm所以无需调用,只能获取第一个文件)
//只会返回第一个文件
func (req *Request) FormFile(key string) (*UploadFile, error) {
file, header, err := req.request.FormFile(key)
if err != nil {
return nil, err
}
defer file.Close()
return NewUploadFile(file, header), nil
}
//根据key返回key的文件列表
func (req *Request) FormFiles(key string) ([]*UploadFile, error) {
if req.request.MultipartForm == nil {
err := req.request.ParseMultipartForm(defaultMultipartBodySze)
if err != nil {
return nil, err
}
}
files := req.request.MultipartForm.File[key]
rFiles := []*UploadFile{}
for i, fileHeader := range files {
//for each fileheader, get a handle to the actual file
file, err := files[i].Open()
defer file.Close()
if err != nil {
return nil, err
}
rFiles = append(rFiles, NewUploadFile(file, fileHeader))
}
return rFiles, nil
}
//获取客户端传过来的文件,并且指定保存路径进行保存
func (req *Request) StoreFormFile(file *UploadFile, fileName string) (int64, error) {
return file.StoreFile(fileName)
}
//文件名会根据用生成的随机字符串,加上源文件后缀名,path为文件保存的路径
//返回文件名列表
func (req *Request) StoreFormFiles(files []*UploadFile, path string) ([]string, error) {
fileNames := []string{}
if path == "" {
return fileNames, errors.New("path is not allowed empty")
}
for _, file := range files {
fileName := cryptos.RandString() + "." + file.Ext
_, err := req.StoreFormFile(file, filepath.Join(path, fileName))
if err != nil {
return fileNames, err
}
fileNames = append(fileNames, fileName)
}
return fileNames, nil
}
/*
* 获取包括post、put和get内的值
*/
func (req *Request) form() url.Values {
req.parseForm()
return req.request.Form
}
func (req *Request) parseForm() error {
if strings.HasPrefix(req.HeaderValue("Content-Type"), "multipart/form-data") {
if err := req.request.ParseMultipartForm(defaultMultipartBodySze); err != nil {
return err
}
} else {
if err := req.request.ParseForm(); err != nil {
return err
}
}
return nil
}
func (req *Request) CType() string {
return req.request.Header.Get("Content-Type")
}
func (req *Request) Header() http.Header {
return req.request.Header
}
func (req *Request) HeaderValue(key string) string {
return req.request.Header.Get(key)
}
// 获取application/x-www-form-urlencoded的post请求参数
func (req *Request) postForm() url.Values {
req.parseForm()
return req.request.PostForm
}
//获取请求体body内容 application/json
func (req *Request) body() []byte {
var body []byte
body, _ = ioutil.ReadAll(req.request.Body)
return body
}
//RemoteAddr to an "IP" address
func (req *Request) ClientIP() string {
cip := req.request.RemoteAddr
if ip := req.request.Header.Get("X-Forwarded-For"); ip != "" {
cip = strings.Split(ip, ", ")[0]
} else if ip := req.request.Header.Get("X-Real-IP"); ip != "" {
cip = ip
} else {
cip, _, _ = net.SplitHostPort(cip)
}
return cip
}
// Path returns requested path.
//
// The path is valid until returning from RequestHandler.
func (req *Request) Path() string {
return req.request.URL.Path
}
// IsAJAX returns if it is a ajax request
func (req *Request) IsAJAX() bool {
return req.request.Header.Get("X-Requested-With") == "XMLHttpRequest"
}
func (req *Request) Url() string {
return req.request.URL.String()
}
//获取请求的httpMethod
func (req *Request) Method() string {
return req.request.Method
}
//获取请求的路由参数
func (req *Request) Params() map[string]string {
return req.params
}
//根据参数名称获取路由参数
func (req *Request) Param(key string) string {
if param, ok := req.params[key]; ok {
return param
}
return ""
}
//获取cookies
func (req *Request) Cookies() []*http.Cookie {
return req.request.Cookies()
}
//获取某一字段的cookie
func (req *Request) CookieValue(key string) (string, error) {
cookieObj, err := req.request.Cookie(key)
if err != nil {
return "", err
}
return url.PathUnescape(cookieObj.Value)
}
//给请求体添加cookie
func (req *Request) AddReqCookie(cookie http.Cookie) {
req.request.AddCookie(&cookie)
}