forked from mystiq/dex
141 lines
2.9 KiB
Go
141 lines
2.9 KiB
Go
package simplehttp
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"mime/multipart"
|
|
"net/url"
|
|
"os"
|
|
"path"
|
|
)
|
|
|
|
type keyValuePair struct {
|
|
key string
|
|
value string
|
|
}
|
|
|
|
type keyNameRC struct {
|
|
key string
|
|
name string
|
|
value io.ReadCloser
|
|
}
|
|
|
|
type Payload interface {
|
|
GetPayloadBuffer() (*bytes.Buffer, error)
|
|
GetContentType() string
|
|
}
|
|
|
|
type RawPayload struct {
|
|
Data []byte
|
|
}
|
|
|
|
type FormDataPayload struct {
|
|
contentType string
|
|
Values []keyValuePair
|
|
Files []keyValuePair
|
|
ReadClosers []keyNameRC
|
|
}
|
|
|
|
type UrlEncodedPayload struct {
|
|
Values []keyValuePair
|
|
}
|
|
|
|
func NewRawPayload(data []byte) *RawPayload {
|
|
return &RawPayload{Data: data}
|
|
}
|
|
|
|
func (r *RawPayload) GetPayloadBuffer() (*bytes.Buffer, error) {
|
|
data := &bytes.Buffer{}
|
|
c, err := data.Write(r.Data)
|
|
if c != len(r.Data) || err != nil {
|
|
return data, err
|
|
}
|
|
return data, nil
|
|
}
|
|
|
|
func (r *RawPayload) GetContentType() string {
|
|
return ""
|
|
}
|
|
|
|
func NewFormDataPayload() *FormDataPayload {
|
|
return &FormDataPayload{}
|
|
}
|
|
|
|
func (f *FormDataPayload) AddValue(key, value string) {
|
|
f.Values = append(f.Values, keyValuePair{key: key, value: value})
|
|
}
|
|
|
|
func (f *FormDataPayload) AddFile(key, file string) {
|
|
f.Files = append(f.Files, keyValuePair{key: key, value: file})
|
|
}
|
|
|
|
func (f *FormDataPayload) AddReadCloser(key, name string, rc io.ReadCloser) {
|
|
f.ReadClosers = append(f.ReadClosers, keyNameRC{key: key, name: name, value: rc})
|
|
}
|
|
|
|
func (f *FormDataPayload) GetPayloadBuffer() (*bytes.Buffer, error) {
|
|
data := &bytes.Buffer{}
|
|
writer := multipart.NewWriter(data)
|
|
defer writer.Close()
|
|
|
|
for _, keyVal := range f.Values {
|
|
if tmp, err := writer.CreateFormField(keyVal.key); err == nil {
|
|
tmp.Write([]byte(keyVal.value))
|
|
} else {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
for _, file := range f.Files {
|
|
if tmp, err := writer.CreateFormFile(file.key, path.Base(file.value)); err == nil {
|
|
if fp, err := os.Open(file.value); err == nil {
|
|
defer fp.Close()
|
|
io.Copy(tmp, fp)
|
|
} else {
|
|
return nil, err
|
|
}
|
|
} else {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
for _, file := range f.ReadClosers {
|
|
if tmp, err := writer.CreateFormFile(file.key, file.name); err == nil {
|
|
defer file.value.Close()
|
|
io.Copy(tmp, file.value)
|
|
} else {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
f.contentType = writer.FormDataContentType()
|
|
|
|
return data, nil
|
|
}
|
|
|
|
func (f *FormDataPayload) GetContentType() string {
|
|
if f.contentType == "" {
|
|
f.GetPayloadBuffer()
|
|
}
|
|
return f.contentType
|
|
}
|
|
|
|
func NewUrlEncodedPayload() *UrlEncodedPayload {
|
|
return &UrlEncodedPayload{}
|
|
}
|
|
|
|
func (f *UrlEncodedPayload) AddValue(key, value string) {
|
|
f.Values = append(f.Values, keyValuePair{key: key, value: value})
|
|
}
|
|
|
|
func (f *UrlEncodedPayload) GetPayloadBuffer() (*bytes.Buffer, error) {
|
|
data := url.Values{}
|
|
for _, keyVal := range f.Values {
|
|
data.Add(keyVal.key, keyVal.value)
|
|
}
|
|
return bytes.NewBufferString(data.Encode()), nil
|
|
}
|
|
|
|
func (f *UrlEncodedPayload) GetContentType() string {
|
|
return "application/x-www-form-urlencoded"
|
|
}
|