httplib:support file upload
Showing
3 changed files
with
69 additions
and
7 deletions
| ... | @@ -60,3 +60,16 @@ some http request need setcookie. So set it like this: | ... | @@ -60,3 +60,16 @@ some http request need setcookie. So set it like this: |
| 60 | cookie.Value = "astaxie" | 60 | cookie.Value = "astaxie" |
| 61 | httplib.Get("http://beego.me/").SetCookie(cookie) | 61 | httplib.Get("http://beego.me/").SetCookie(cookie) |
| 62 | 62 | ||
| 63 | ## upload file | ||
| 64 | httplib support mutil file upload, use `b.PostFile()` | ||
| 65 | |||
| 66 | b:=httplib.Post("http://beego.me/") | ||
| 67 | b.Param("username","astaxie") | ||
| 68 | b.Param("password","123456") | ||
| 69 | b.PostFile("uploadfile1", "httplib.pdf") | ||
| 70 | b.PostFile("uploadfile2", "httplib.txt") | ||
| 71 | str, err := b.String() | ||
| 72 | if err != nil { | ||
| 73 | t.Fatal(err) | ||
| 74 | } | ||
| 75 | fmt.Println(str) | ... | ... |
| ... | @@ -13,6 +13,7 @@ import ( | ... | @@ -13,6 +13,7 @@ import ( |
| 13 | "encoding/xml" | 13 | "encoding/xml" |
| 14 | "io" | 14 | "io" |
| 15 | "io/ioutil" | 15 | "io/ioutil" |
| 16 | "mime/multipart" | ||
| 16 | "net" | 17 | "net" |
| 17 | "net/http" | 18 | "net/http" |
| 18 | "net/http/httputil" | 19 | "net/http/httputil" |
| ... | @@ -30,7 +31,7 @@ func Get(url string) *BeegoHttpRequest { | ... | @@ -30,7 +31,7 @@ func Get(url string) *BeegoHttpRequest { |
| 30 | req.Method = "GET" | 31 | req.Method = "GET" |
| 31 | req.Header = http.Header{} | 32 | req.Header = http.Header{} |
| 32 | req.Header.Set("User-Agent", defaultUserAgent) | 33 | req.Header.Set("User-Agent", defaultUserAgent) |
| 33 | return &BeegoHttpRequest{url, &req, map[string]string{}, false, 60 * time.Second, 60 * time.Second, nil, nil, nil} | 34 | return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, false, 60 * time.Second, 60 * time.Second, nil, nil, nil} |
| 34 | } | 35 | } |
| 35 | 36 | ||
| 36 | // Post returns *BeegoHttpRequest with POST method. | 37 | // Post returns *BeegoHttpRequest with POST method. |
| ... | @@ -39,7 +40,7 @@ func Post(url string) *BeegoHttpRequest { | ... | @@ -39,7 +40,7 @@ func Post(url string) *BeegoHttpRequest { |
| 39 | req.Method = "POST" | 40 | req.Method = "POST" |
| 40 | req.Header = http.Header{} | 41 | req.Header = http.Header{} |
| 41 | req.Header.Set("User-Agent", defaultUserAgent) | 42 | req.Header.Set("User-Agent", defaultUserAgent) |
| 42 | return &BeegoHttpRequest{url, &req, map[string]string{}, false, 60 * time.Second, 60 * time.Second, nil, nil, nil} | 43 | return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, false, 60 * time.Second, 60 * time.Second, nil, nil, nil} |
| 43 | } | 44 | } |
| 44 | 45 | ||
| 45 | // Put returns *BeegoHttpRequest with PUT method. | 46 | // Put returns *BeegoHttpRequest with PUT method. |
| ... | @@ -48,7 +49,7 @@ func Put(url string) *BeegoHttpRequest { | ... | @@ -48,7 +49,7 @@ func Put(url string) *BeegoHttpRequest { |
| 48 | req.Method = "PUT" | 49 | req.Method = "PUT" |
| 49 | req.Header = http.Header{} | 50 | req.Header = http.Header{} |
| 50 | req.Header.Set("User-Agent", defaultUserAgent) | 51 | req.Header.Set("User-Agent", defaultUserAgent) |
| 51 | return &BeegoHttpRequest{url, &req, map[string]string{}, false, 60 * time.Second, 60 * time.Second, nil, nil, nil} | 52 | return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, false, 60 * time.Second, 60 * time.Second, nil, nil, nil} |
| 52 | } | 53 | } |
| 53 | 54 | ||
| 54 | // Delete returns *BeegoHttpRequest DELETE GET method. | 55 | // Delete returns *BeegoHttpRequest DELETE GET method. |
| ... | @@ -57,7 +58,7 @@ func Delete(url string) *BeegoHttpRequest { | ... | @@ -57,7 +58,7 @@ func Delete(url string) *BeegoHttpRequest { |
| 57 | req.Method = "DELETE" | 58 | req.Method = "DELETE" |
| 58 | req.Header = http.Header{} | 59 | req.Header = http.Header{} |
| 59 | req.Header.Set("User-Agent", defaultUserAgent) | 60 | req.Header.Set("User-Agent", defaultUserAgent) |
| 60 | return &BeegoHttpRequest{url, &req, map[string]string{}, false, 60 * time.Second, 60 * time.Second, nil, nil, nil} | 61 | return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, false, 60 * time.Second, 60 * time.Second, nil, nil, nil} |
| 61 | } | 62 | } |
| 62 | 63 | ||
| 63 | // Head returns *BeegoHttpRequest with HEAD method. | 64 | // Head returns *BeegoHttpRequest with HEAD method. |
| ... | @@ -66,7 +67,7 @@ func Head(url string) *BeegoHttpRequest { | ... | @@ -66,7 +67,7 @@ func Head(url string) *BeegoHttpRequest { |
| 66 | req.Method = "HEAD" | 67 | req.Method = "HEAD" |
| 67 | req.Header = http.Header{} | 68 | req.Header = http.Header{} |
| 68 | req.Header.Set("User-Agent", defaultUserAgent) | 69 | req.Header.Set("User-Agent", defaultUserAgent) |
| 69 | return &BeegoHttpRequest{url, &req, map[string]string{}, false, 60 * time.Second, 60 * time.Second, nil, nil, nil} | 70 | return &BeegoHttpRequest{url, &req, map[string]string{}, map[string]string{}, false, 60 * time.Second, 60 * time.Second, nil, nil, nil} |
| 70 | } | 71 | } |
| 71 | 72 | ||
| 72 | // BeegoHttpRequest provides more useful methods for requesting one url than http.Request. | 73 | // BeegoHttpRequest provides more useful methods for requesting one url than http.Request. |
| ... | @@ -74,6 +75,7 @@ type BeegoHttpRequest struct { | ... | @@ -74,6 +75,7 @@ type BeegoHttpRequest struct { |
| 74 | url string | 75 | url string |
| 75 | req *http.Request | 76 | req *http.Request |
| 76 | params map[string]string | 77 | params map[string]string |
| 78 | files map[string]string | ||
| 77 | showdebug bool | 79 | showdebug bool |
| 78 | connectTimeout time.Duration | 80 | connectTimeout time.Duration |
| 79 | readWriteTimeout time.Duration | 81 | readWriteTimeout time.Duration |
| ... | @@ -138,6 +140,11 @@ func (b *BeegoHttpRequest) Param(key, value string) *BeegoHttpRequest { | ... | @@ -138,6 +140,11 @@ func (b *BeegoHttpRequest) Param(key, value string) *BeegoHttpRequest { |
| 138 | return b | 140 | return b |
| 139 | } | 141 | } |
| 140 | 142 | ||
| 143 | func (b *BeegoHttpRequest) PostFile(formname, filename string) *BeegoHttpRequest { | ||
| 144 | b.files[formname] = filename | ||
| 145 | return b | ||
| 146 | } | ||
| 147 | |||
| 141 | // Body adds request raw body. | 148 | // Body adds request raw body. |
| 142 | // it supports string and []byte. | 149 | // it supports string and []byte. |
| 143 | func (b *BeegoHttpRequest) Body(data interface{}) *BeegoHttpRequest { | 150 | func (b *BeegoHttpRequest) Body(data interface{}) *BeegoHttpRequest { |
| ... | @@ -175,8 +182,37 @@ func (b *BeegoHttpRequest) getResponse() (*http.Response, error) { | ... | @@ -175,8 +182,37 @@ func (b *BeegoHttpRequest) getResponse() (*http.Response, error) { |
| 175 | b.url = b.url + "?" + paramBody | 182 | b.url = b.url + "?" + paramBody |
| 176 | } | 183 | } |
| 177 | } else if b.req.Method == "POST" && b.req.Body == nil && len(paramBody) > 0 { | 184 | } else if b.req.Method == "POST" && b.req.Body == nil && len(paramBody) > 0 { |
| 178 | b.Header("Content-Type", "application/x-www-form-urlencoded") | 185 | if len(b.files) > 0 { |
| 179 | b.Body(paramBody) | 186 | bodyBuf := &bytes.Buffer{} |
| 187 | bodyWriter := multipart.NewWriter(bodyBuf) | ||
| 188 | for formname, filename := range b.files { | ||
| 189 | fileWriter, err := bodyWriter.CreateFormFile(formname, filename) | ||
| 190 | if err != nil { | ||
| 191 | return nil, err | ||
| 192 | } | ||
| 193 | fh, err := os.Open(filename) | ||
| 194 | if err != nil { | ||
| 195 | return nil, err | ||
| 196 | } | ||
| 197 | //iocopy | ||
| 198 | _, err = io.Copy(fileWriter, fh) | ||
| 199 | fh.Close() | ||
| 200 | if err != nil { | ||
| 201 | return nil, err | ||
| 202 | } | ||
| 203 | } | ||
| 204 | for k, v := range b.params { | ||
| 205 | bodyWriter.WriteField(k, v) | ||
| 206 | } | ||
| 207 | contentType := bodyWriter.FormDataContentType() | ||
| 208 | bodyWriter.Close() | ||
| 209 | b.Header("Content-Type", contentType) | ||
| 210 | b.req.Body = ioutil.NopCloser(bodyBuf) | ||
| 211 | b.req.ContentLength = int64(bodyBuf.Len()) | ||
| 212 | } else { | ||
| 213 | b.Header("Content-Type", "application/x-www-form-urlencoded") | ||
| 214 | b.Body(paramBody) | ||
| 215 | } | ||
| 180 | } | 216 | } |
| 181 | 217 | ||
| 182 | url, err := url.Parse(b.url) | 218 | url, err := url.Parse(b.url) | ... | ... |
| ... | @@ -7,6 +7,7 @@ | ... | @@ -7,6 +7,7 @@ |
| 7 | package httplib | 7 | package httplib |
| 8 | 8 | ||
| 9 | import ( | 9 | import ( |
| 10 | "fmt" | ||
| 10 | "io/ioutil" | 11 | "io/ioutil" |
| 11 | "testing" | 12 | "testing" |
| 12 | ) | 13 | ) |
| ... | @@ -36,3 +37,15 @@ func TestGetUrl(t *testing.T) { | ... | @@ -36,3 +37,15 @@ func TestGetUrl(t *testing.T) { |
| 36 | t.Fatal("has no info") | 37 | t.Fatal("has no info") |
| 37 | } | 38 | } |
| 38 | } | 39 | } |
| 40 | |||
| 41 | func TestPost(t *testing.T) { | ||
| 42 | b := Post("http://beego.me/").Debug(true) | ||
| 43 | b.Param("username", "astaxie") | ||
| 44 | b.Param("password", "hello") | ||
| 45 | b.PostFile("uploadfile", "httplib.go") | ||
| 46 | str, err := b.String() | ||
| 47 | if err != nil { | ||
| 48 | t.Fatal(err) | ||
| 49 | } | ||
| 50 | fmt.Println(str) | ||
| 51 | } | ... | ... |
-
Please register or sign in to post a comment