forked from imroc/req
-
Notifications
You must be signed in to change notification settings - Fork 0
/
req.go
128 lines (113 loc) · 2.74 KB
/
req.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
package req
import (
"bytes"
"fmt"
"net/http"
"net/url"
)
type kv struct {
Key string
Value string
}
// ContentDisposition represents parameters in `Content-Disposition`
// MIME header of multipart request.
type ContentDisposition struct {
kv []kv
}
// Add adds a new key-value pair of Content-Disposition
func (c *ContentDisposition) Add(key, value string) *ContentDisposition {
c.kv = append(c.kv, kv{Key: key, Value: value})
return c
}
func (c *ContentDisposition) string() string {
if c == nil {
return ""
}
s := ""
for _, kv := range c.kv {
s += fmt.Sprintf("; %s=%q", kv.Key, kv.Value)
}
return s
}
// FileUpload represents a "form-data" multipart
type FileUpload struct {
// "name" parameter in `Content-Disposition`
ParamName string
// "filename" parameter in `Content-Disposition`
FileName string
// The file to be uploaded.
GetFileContent GetContentFunc
// Optional file length in bytes.
FileSize int64
// Optional Content-Type
ContentType string
// Optional extra ContentDisposition parameters.
// According to the HTTP specification, this should be nil,
// but some servers may not follow the specification and
// requires `Content-Disposition` parameters more than just
// "name" and "filename".
ExtraContentDisposition *ContentDisposition
}
// UploadInfo is the information for each UploadCallback call.
type UploadInfo struct {
// parameter name in multipart upload
ParamName string
// filename in multipart upload
FileName string
// total file length in bytes.
FileSize int64
// uploaded file length in bytes.
UploadedSize int64
}
// UploadCallback is the callback which will be invoked during
// multipart upload.
type UploadCallback func(info UploadInfo)
// DownloadInfo is the information for each DownloadCallback call.
type DownloadInfo struct {
// Response is the corresponding Response during download.
Response *Response
// downloaded body length in bytes.
DownloadedSize int64
}
// DownloadCallback is the callback which will be invoked during
// response body download.
type DownloadCallback func(info DownloadInfo)
func cloneSlice[T any](s []T) []T {
if len(s) == 0 {
return nil
}
ss := make([]T, len(s))
copy(ss, s)
return ss
}
func cloneUrlValues(v url.Values) url.Values {
if v == nil {
return nil
}
vv := make(url.Values)
for key, values := range v {
for _, value := range values {
vv.Add(key, value)
}
}
return vv
}
func cloneMap(h map[string]string) map[string]string {
if h == nil {
return nil
}
m := make(map[string]string)
for k, v := range h {
m[k] = v
}
return m
}
// convertHeaderToString converts http header to a string.
func convertHeaderToString(h http.Header) string {
if h == nil {
return ""
}
buf := new(bytes.Buffer)
h.Write(buf)
return buf.String()
}