mirror of https://github.com/dexidp/dex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
141 lines
2.9 KiB
141 lines
2.9 KiB
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" |
|
}
|
|
|