body-request.go 8.1 KB
Newer Older
E
eoLinker API Management 已提交
1 2 3 4
package common

import (
	"bytes"
Y
Your Name 已提交
5 6
	"encoding/json"
	"encoding/xml"
E
eoLinker API Management 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20
	"errors"

	goku_plugin "github.com/eolinker/goku-plugin"

	"io/ioutil"
	"net/http"

	"mime"
	"mime/multipart"
	"net/url"
)

const defaultMultipartMemory = 32 << 20 // 32 MB
var (
Y
Your Name 已提交
21 22 23
	errorNotForm      = errors.New("contentType is not Form")
	errorNotMultipart = errors.New("contentType is not Multipart")
	errorNotAllowRaw  = errors.New("contentType is not allow Raw")
E
eoLinker API Management 已提交
24 25
)

Y
Your Name 已提交
26
//BodyRequestHandler body请求处理器
E
eoLinker API Management 已提交
27 28
type BodyRequestHandler struct {
	form            url.Values
Y
Your Name 已提交
29
	rawBody         []byte
E
eoLinker API Management 已提交
30 31 32 33 34 35
	orgContentParam map[string]string
	contentType     string
	files           map[string]*goku_plugin.FileHeader

	isInit     bool
	isWriteRaw bool
Y
Your Name 已提交
36 37

	object interface{}
E
eoLinker API Management 已提交
38 39
}

Y
Your Name 已提交
40
//Files 获取文件参数
E
eoLinker API Management 已提交
41 42 43 44 45 46 47 48 49 50
func (b *BodyRequestHandler) Files() (map[string]*goku_plugin.FileHeader, error) {

	err := b.Parse()

	if err != nil {
		return nil, err
	}
	return b.files, nil

}
Y
Your Name 已提交
51

Y
Your Name 已提交
52
//Parse 解析
E
eoLinker API Management 已提交
53 54 55 56 57 58 59 60 61
func (b *BodyRequestHandler) Parse() error {

	if b.isInit {
		return nil
	}

	contentType, _, _ := mime.ParseMediaType(b.contentType)

	switch contentType {
Y
Your Name 已提交
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
	case goku_plugin.JSON:
		{
			e := json.Unmarshal(b.rawBody, &b.object)
			if e != nil {
				return e
			}
		}
	case goku_plugin.AppLicationXML, goku_plugin.TextXML:
		{
			e := xml.Unmarshal(b.rawBody, &b.object)
			if e != nil {
				return e
			}

		}

E
eoLinker API Management 已提交
78 79
	case goku_plugin.MultipartForm:
		{
Y
Your Name 已提交
80
			r, err := multipartReader(b.contentType, false, b.rawBody)
E
eoLinker API Management 已提交
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
			if err != nil {
				return err
			}
			form, err := r.ReadForm(defaultMultipartMemory)
			if err != nil {
				return err
			}

			if b.form == nil {
				b.form = make(url.Values)
			}
			for k, v := range form.Value {
				b.form[k] = append(b.form[k], v...)
			}

			b.files = make(map[string]*goku_plugin.FileHeader)
			for k, fs := range form.File {

				if len(fs) > 0 {
					file, err := fs[0].Open()
					if err != nil {
						return err
					}
					fileData, err := ioutil.ReadAll(file)
					if err != nil {
						return err
					}

					b.files[k] = &goku_plugin.FileHeader{
						FileName: fs[0].Filename,
						Data:     fileData,
						Header:   fs[0].Header,
					}
				}
			}
Y
Your Name 已提交
116 117

			b.object = b.form
E
eoLinker API Management 已提交
118 119 120
		}
	case goku_plugin.FormData:
		{
Y
Your Name 已提交
121
			form, err := url.ParseQuery(string(b.rawBody))
E
eoLinker API Management 已提交
122 123 124 125
			if err != nil {
				return err
			}
			if b.form == nil {
Y
Your Name 已提交
126 127

				b.object = form
E
eoLinker API Management 已提交
128 129 130 131
			} else {
				for k, v := range form {
					b.form[k] = append(b.form[k], v...)
				}
Y
Your Name 已提交
132

E
eoLinker API Management 已提交
133
			}
Y
Your Name 已提交
134
			b.object = b.form
E
eoLinker API Management 已提交
135 136 137 138 139 140

		}
	}
	b.isInit = true
	return nil
}
Y
Your Name 已提交
141

Y
Your Name 已提交
142
//GetForm 获取表单参数
E
eoLinker API Management 已提交
143 144 145 146 147 148 149 150 151 152 153 154 155 156
func (b *BodyRequestHandler) GetForm(key string) string {

	contentType, _, _ := mime.ParseMediaType(b.contentType)
	if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
		return ""
	}
	b.Parse()

	if !b.isInit || b.form == nil {
		return ""
	}
	return b.form.Get(key)
}

Y
Your Name 已提交
157
//GetFile 获取文件参数
E
eoLinker API Management 已提交
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
func (b *BodyRequestHandler) GetFile(key string) (file *goku_plugin.FileHeader, has bool) {

	contentType, _, _ := mime.ParseMediaType(b.contentType)
	if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
		return nil, false
	}

	err := b.Parse()
	if err != nil {
		return nil, false
	}

	if !b.isInit || b.files == nil {
		return nil, false
	}
	f, has := b.files[key]
	return f, has
}

Y
Your Name 已提交
177
//SetToForm 设置表单参数
E
eoLinker API Management 已提交
178 179 180 181
func (b *BodyRequestHandler) SetToForm(key, value string) error {

	contentType, _, _ := mime.ParseMediaType(b.contentType)
	if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
Y
Your Name 已提交
182
		return errorNotForm
E
eoLinker API Management 已提交
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
	}

	err := b.Parse()
	if err != nil {
		return err
	}
	b.isWriteRaw = false

	if b.form == nil {
		b.form = make(url.Values)
	}
	b.form.Set(key, value)
	b.isWriteRaw = false

	return nil
}

Y
Your Name 已提交
200
//AddForm 新增表单参数
E
eoLinker API Management 已提交
201 202 203
func (b *BodyRequestHandler) AddForm(key, value string) error {
	contentType, _, _ := mime.ParseMediaType(b.contentType)
	if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
Y
Your Name 已提交
204
		return errorNotForm
E
eoLinker API Management 已提交
205 206 207 208 209 210 211 212 213 214 215 216 217 218
	}
	err := b.Parse()
	if err != nil {
		return err
	}
	b.isWriteRaw = false

	if b.form == nil {
		b.form = make(url.Values)
	}
	b.form.Add(key, value)
	return nil
}

Y
Your Name 已提交
219
//AddFile 新增文件参数
E
eoLinker API Management 已提交
220 221 222 223
func (b *BodyRequestHandler) AddFile(key string, file *goku_plugin.FileHeader) error {

	contentType, _, _ := mime.ParseMediaType(b.contentType)
	if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
Y
Your Name 已提交
224
		return errorNotMultipart
E
eoLinker API Management 已提交
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
	}
	err := b.Parse()
	if err != nil {
		return err
	}
	b.isWriteRaw = false
	if file == nil && b.files != nil {
		delete(b.files, key)
		return nil
	}
	if b.files == nil {
		b.files = make(map[string]*goku_plugin.FileHeader)
	}
	b.files[key] = file

	return nil
}

Y
Your Name 已提交
243
//Clone 克隆body
E
eoLinker API Management 已提交
244 245 246 247 248
func (b *BodyRequestHandler) Clone() *BodyRequestHandler {
	rawbody, _ := b.RawBody()
	return NewBodyRequestHandler(b.contentType, rawbody)

}
Y
Your Name 已提交
249

Y
Your Name 已提交
250
//ContentType 获取contentType
E
eoLinker API Management 已提交
251 252 253 254
func (b *BodyRequestHandler) ContentType() string {
	return b.contentType
}

Y
Your Name 已提交
255
//BodyForm 获取表单参数
E
eoLinker API Management 已提交
256 257 258 259 260 261 262 263 264
func (b *BodyRequestHandler) BodyForm() (url.Values, error) {

	err := b.Parse()
	if err != nil {
		return nil, err
	}
	return b.form, nil
}

Y
Your Name 已提交
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
//BodyInterface 获取请求体对象
func (b *BodyRequestHandler) BodyInterface() (interface{}, error) {
	err := b.Parse()
	if err != nil {
		return nil, err
	}

	return b.object, nil
}

//RawBody 获取raw数据
func (b *BodyRequestHandler) RawBody() ([]byte, error) {

	err := b.Encode()
	if err != nil {
		return nil, err
	}
	return b.rawBody, nil

}

Y
Your Name 已提交
286
//Encode encode
E
eoLinker API Management 已提交
287 288 289 290
func (b *BodyRequestHandler) Encode() error {
	if b.isWriteRaw {
		return nil
	}
Y
Your Name 已提交
291

E
eoLinker API Management 已提交
292 293 294 295 296 297 298 299 300 301
	contentType, _, _ := mime.ParseMediaType(b.contentType)
	if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
		b.isWriteRaw = true
		return nil
	}

	if len(b.files) > 0 {
		body := new(bytes.Buffer)
		writer := multipart.NewWriter(body)

Y
Your Name 已提交
302 303
		for name, file := range b.files {
			part, err := writer.CreateFormFile(name, file.FileName)
E
eoLinker API Management 已提交
304 305 306 307 308 309 310 311 312
			if err != nil {
				return err
			}
			_, err = part.Write(file.Data)
			if err != nil {
				return err
			}
		}

Y
Your Name 已提交
313
		for key, values := range b.form {
E
eoLinker API Management 已提交
314
			temp := make(url.Values)
Y
Your Name 已提交
315
			temp[key] = values
E
eoLinker API Management 已提交
316
			value := temp.Encode()
Y
Your Name 已提交
317
			err := writer.WriteField(key, value)
E
eoLinker API Management 已提交
318 319 320 321 322 323 324 325 326
			if err != nil {
				return err
			}
		}
		err := writer.Close()
		if err != nil {
			return err
		}
		b.contentType = writer.FormDataContentType()
Y
Your Name 已提交
327
		b.rawBody = body.Bytes()
E
eoLinker API Management 已提交
328 329 330
		b.isWriteRaw = true
	} else {
		if b.form != nil {
Y
Your Name 已提交
331
			b.rawBody = []byte(b.form.Encode())
E
eoLinker API Management 已提交
332
		} else {
Y
Your Name 已提交
333
			b.rawBody = make([]byte, 0, 0)
E
eoLinker API Management 已提交
334 335 336 337 338
		}
	}
	return nil
}

Y
Your Name 已提交
339
//SetForm 设置表单参数
E
eoLinker API Management 已提交
340 341 342 343
func (b *BodyRequestHandler) SetForm(values url.Values) error {

	contentType, _, _ := mime.ParseMediaType(b.contentType)
	if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
Y
Your Name 已提交
344
		return errorNotForm
E
eoLinker API Management 已提交
345 346 347 348 349 350 351 352
	}
	b.Parse()
	b.form = values
	b.isWriteRaw = false

	return nil
}

Y
Your Name 已提交
353
//SetFile 设置文件参数
E
eoLinker API Management 已提交
354 355 356 357
func (b *BodyRequestHandler) SetFile(files map[string]*goku_plugin.FileHeader) error {

	contentType, _, _ := mime.ParseMediaType(b.contentType)
	if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
Y
Your Name 已提交
358
		return errorNotForm
E
eoLinker API Management 已提交
359 360 361 362 363 364 365 366 367
	}
	b.Parse()
	b.files = files
	// b.form = values
	b.isWriteRaw = false

	return nil
}

Y
Your Name 已提交
368
//SetRaw 设置raw数据
E
eoLinker API Management 已提交
369 370
func (b *BodyRequestHandler) SetRaw(contentType string, body []byte) {

Y
Your Name 已提交
371
	b.rawBody, b.contentType, b.isInit, b.isWriteRaw = body, contentType, false, true
E
eoLinker API Management 已提交
372 373 374 375 376
	_, b.orgContentParam, _ = mime.ParseMediaType(contentType)
	return

}

Y
Your Name 已提交
377
//NewBodyRequestHandler 创建body请求处理器
E
eoLinker API Management 已提交
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399
func NewBodyRequestHandler(contentType string, body []byte) *BodyRequestHandler {
	b := new(BodyRequestHandler)
	b.SetRaw(contentType, body)
	return b
}

func multipartReader(contentType string, allowMixed bool, raw []byte) (*multipart.Reader, error) {

	if contentType == "" {
		return nil, http.ErrNotMultipart
	}
	d, params, err := mime.ParseMediaType(contentType)
	if err != nil || !(d == "multipart/form-data" || allowMixed && d == "multipart/mixed") {
		return nil, http.ErrNotMultipart
	}
	boundary, ok := params["boundary"]
	if !ok {
		return nil, http.ErrMissingBoundary
	}
	body := ioutil.NopCloser(bytes.NewBuffer(raw))
	return multipart.NewReader(body, boundary), nil
}