merge bat/httplib to httplib
Showing
1 changed file
with
84 additions
and
43 deletions
| ... | @@ -36,7 +36,6 @@ import ( | ... | @@ -36,7 +36,6 @@ import ( |
| 36 | "crypto/tls" | 36 | "crypto/tls" |
| 37 | "encoding/json" | 37 | "encoding/json" |
| 38 | "encoding/xml" | 38 | "encoding/xml" |
| 39 | "fmt" | ||
| 40 | "io" | 39 | "io" |
| 41 | "io/ioutil" | 40 | "io/ioutil" |
| 42 | "log" | 41 | "log" |
| ... | @@ -48,26 +47,50 @@ import ( | ... | @@ -48,26 +47,50 @@ import ( |
| 48 | "net/url" | 47 | "net/url" |
| 49 | "os" | 48 | "os" |
| 50 | "strings" | 49 | "strings" |
| 50 | "sync" | ||
| 51 | "time" | 51 | "time" |
| 52 | ) | 52 | ) |
| 53 | 53 | ||
| 54 | var defaultSetting = BeegoHttpSettings{UserAgent: "beegoServer", ConnectTimeout: 60 * time.Second, ReadWriteTimeout: 60 * time.Second, Gzip: true} | 54 | var defaultSetting = BeegoHttpSettings{ |
| 55 | UserAgent: "beegoServer", | ||
| 56 | ConnectTimeout: 60 * time.Second, | ||
| 57 | ReadWriteTimeout: 60 * time.Second, | ||
| 58 | Gzip: true, | ||
| 59 | DumpBody: true, | ||
| 60 | } | ||
| 61 | |||
| 55 | var defaultCookieJar http.CookieJar | 62 | var defaultCookieJar http.CookieJar |
| 63 | var settingMutex sync.Mutex | ||
| 56 | 64 | ||
| 57 | // createDefaultCookie creates a global cookiejar to store cookies. | 65 | // createDefaultCookie creates a global cookiejar to store cookies. |
| 58 | func createDefaultCookie() { | 66 | func createDefaultCookie() { |
| 67 | settingMutex.Lock() | ||
| 68 | defer settingMutex.Unlock() | ||
| 59 | defaultCookieJar, _ = cookiejar.New(nil) | 69 | defaultCookieJar, _ = cookiejar.New(nil) |
| 60 | } | 70 | } |
| 61 | 71 | ||
| 62 | // Overwrite default settings | 72 | // Overwrite default settings |
| 63 | func SetDefaultSetting(setting BeegoHttpSettings) { | 73 | func SetDefaultSetting(setting BeegoHttpSettings) { |
| 74 | settingMutex.Lock() | ||
| 75 | defer settingMutex.Unlock() | ||
| 64 | defaultSetting = setting | 76 | defaultSetting = setting |
| 77 | if defaultSetting.ConnectTimeout == 0 { | ||
| 78 | defaultSetting.ConnectTimeout = 60 * time.Second | ||
| 79 | } | ||
| 80 | if defaultSetting.ReadWriteTimeout == 0 { | ||
| 81 | defaultSetting.ReadWriteTimeout = 60 * time.Second | ||
| 82 | } | ||
| 65 | } | 83 | } |
| 66 | 84 | ||
| 67 | // return *BeegoHttpRequest with specific method | 85 | // return *BeegoHttpRequest with specific method |
| 68 | func newBeegoRequest(url, method string) *BeegoHttpRequest { | 86 | func NewBeegoRequest(rawurl, method string) *BeegoHttpRequest { |
| 69 | var resp http.Response | 87 | var resp http.Response |
| 88 | u, err := url.Parse(rawurl) | ||
| 89 | if err != nil { | ||
| 90 | log.Fatal(err) | ||
| 91 | } | ||
| 70 | req := http.Request{ | 92 | req := http.Request{ |
| 93 | URL: u, | ||
| 71 | Method: method, | 94 | Method: method, |
| 72 | Header: make(http.Header), | 95 | Header: make(http.Header), |
| 73 | Proto: "HTTP/1.1", | 96 | Proto: "HTTP/1.1", |
| ... | @@ -75,7 +98,7 @@ func newBeegoRequest(url, method string) *BeegoHttpRequest { | ... | @@ -75,7 +98,7 @@ func newBeegoRequest(url, method string) *BeegoHttpRequest { |
| 75 | ProtoMinor: 1, | 98 | ProtoMinor: 1, |
| 76 | } | 99 | } |
| 77 | return &BeegoHttpRequest{ | 100 | return &BeegoHttpRequest{ |
| 78 | url: url, | 101 | url: rawurl, |
| 79 | req: &req, | 102 | req: &req, |
| 80 | params: map[string]string{}, | 103 | params: map[string]string{}, |
| 81 | files: map[string]string{}, | 104 | files: map[string]string{}, |
| ... | @@ -86,27 +109,27 @@ func newBeegoRequest(url, method string) *BeegoHttpRequest { | ... | @@ -86,27 +109,27 @@ func newBeegoRequest(url, method string) *BeegoHttpRequest { |
| 86 | 109 | ||
| 87 | // Get returns *BeegoHttpRequest with GET method. | 110 | // Get returns *BeegoHttpRequest with GET method. |
| 88 | func Get(url string) *BeegoHttpRequest { | 111 | func Get(url string) *BeegoHttpRequest { |
| 89 | return newBeegoRequest(url, "GET") | 112 | return NewBeegoRequest(url, "GET") |
| 90 | } | 113 | } |
| 91 | 114 | ||
| 92 | // Post returns *BeegoHttpRequest with POST method. | 115 | // Post returns *BeegoHttpRequest with POST method. |
| 93 | func Post(url string) *BeegoHttpRequest { | 116 | func Post(url string) *BeegoHttpRequest { |
| 94 | return newBeegoRequest(url, "POST") | 117 | return NewBeegoRequest(url, "POST") |
| 95 | } | 118 | } |
| 96 | 119 | ||
| 97 | // Put returns *BeegoHttpRequest with PUT method. | 120 | // Put returns *BeegoHttpRequest with PUT method. |
| 98 | func Put(url string) *BeegoHttpRequest { | 121 | func Put(url string) *BeegoHttpRequest { |
| 99 | return newBeegoRequest(url, "PUT") | 122 | return NewBeegoRequest(url, "PUT") |
| 100 | } | 123 | } |
| 101 | 124 | ||
| 102 | // Delete returns *BeegoHttpRequest DELETE method. | 125 | // Delete returns *BeegoHttpRequest DELETE method. |
| 103 | func Delete(url string) *BeegoHttpRequest { | 126 | func Delete(url string) *BeegoHttpRequest { |
| 104 | return newBeegoRequest(url, "DELETE") | 127 | return NewBeegoRequest(url, "DELETE") |
| 105 | } | 128 | } |
| 106 | 129 | ||
| 107 | // Head returns *BeegoHttpRequest with HEAD method. | 130 | // Head returns *BeegoHttpRequest with HEAD method. |
| 108 | func Head(url string) *BeegoHttpRequest { | 131 | func Head(url string) *BeegoHttpRequest { |
| 109 | return newBeegoRequest(url, "HEAD") | 132 | return NewBeegoRequest(url, "HEAD") |
| 110 | } | 133 | } |
| 111 | 134 | ||
| 112 | // BeegoHttpSettings | 135 | // BeegoHttpSettings |
| ... | @@ -120,6 +143,7 @@ type BeegoHttpSettings struct { | ... | @@ -120,6 +143,7 @@ type BeegoHttpSettings struct { |
| 120 | Transport http.RoundTripper | 143 | Transport http.RoundTripper |
| 121 | EnableCookie bool | 144 | EnableCookie bool |
| 122 | Gzip bool | 145 | Gzip bool |
| 146 | DumpBody bool | ||
| 123 | } | 147 | } |
| 124 | 148 | ||
| 125 | // BeegoHttpRequest provides more useful methods for requesting one url than http.Request. | 149 | // BeegoHttpRequest provides more useful methods for requesting one url than http.Request. |
| ... | @@ -134,6 +158,11 @@ type BeegoHttpRequest struct { | ... | @@ -134,6 +158,11 @@ type BeegoHttpRequest struct { |
| 134 | dump []byte | 158 | dump []byte |
| 135 | } | 159 | } |
| 136 | 160 | ||
| 161 | // get request | ||
| 162 | func (b *BeegoHttpRequest) GetRequest() *http.Request { | ||
| 163 | return b.req | ||
| 164 | } | ||
| 165 | |||
| 137 | // Change request settings | 166 | // Change request settings |
| 138 | func (b *BeegoHttpRequest) Setting(setting BeegoHttpSettings) *BeegoHttpRequest { | 167 | func (b *BeegoHttpRequest) Setting(setting BeegoHttpSettings) *BeegoHttpRequest { |
| 139 | b.setting = setting | 168 | b.setting = setting |
| ... | @@ -153,14 +182,20 @@ func (b *BeegoHttpRequest) SetEnableCookie(enable bool) *BeegoHttpRequest { | ... | @@ -153,14 +182,20 @@ func (b *BeegoHttpRequest) SetEnableCookie(enable bool) *BeegoHttpRequest { |
| 153 | } | 182 | } |
| 154 | 183 | ||
| 155 | // SetUserAgent sets User-Agent header field | 184 | // SetUserAgent sets User-Agent header field |
| 156 | func (b *BeegoHttpRequest) SetUserAgent(userAgent string) *BeegoHttpRequest { | 185 | func (b *BeegoHttpRequest) SetUserAgent(useragent string) *BeegoHttpRequest { |
| 157 | b.setting.UserAgent = userAgent | 186 | b.setting.UserAgent = useragent |
| 158 | return b | 187 | return b |
| 159 | } | 188 | } |
| 160 | 189 | ||
| 161 | // Debug sets show debug or not when executing request. | 190 | // Debug sets show debug or not when executing request. |
| 162 | func (b *BeegoHttpRequest) Debug(isDebug bool) *BeegoHttpRequest { | 191 | func (b *BeegoHttpRequest) Debug(isdebug bool) *BeegoHttpRequest { |
| 163 | b.setting.ShowDebug = isDebug | 192 | b.setting.ShowDebug = isdebug |
| 193 | return b | ||
| 194 | } | ||
| 195 | |||
| 196 | // Dump Body. | ||
| 197 | func (b *BeegoHttpRequest) DumpBody(isdump bool) *BeegoHttpRequest { | ||
| 198 | b.setting.DumpBody = isdump | ||
| 164 | return b | 199 | return b |
| 165 | } | 200 | } |
| 166 | 201 | ||
| ... | @@ -279,21 +314,18 @@ func (b *BeegoHttpRequest) JsonBody(obj interface{}) (*BeegoHttpRequest, error) | ... | @@ -279,21 +314,18 @@ func (b *BeegoHttpRequest) JsonBody(obj interface{}) (*BeegoHttpRequest, error) |
| 279 | } | 314 | } |
| 280 | 315 | ||
| 281 | func (b *BeegoHttpRequest) buildUrl(paramBody string) { | 316 | func (b *BeegoHttpRequest) buildUrl(paramBody string) { |
| 282 | if paramBody == "" { | ||
| 283 | return | ||
| 284 | } | ||
| 285 | // build GET url with query string | 317 | // build GET url with query string |
| 286 | if b.req.Method == "GET" { | 318 | if b.req.Method == "GET" && len(paramBody) > 0 { |
| 287 | if strings.Index(b.url, "?") == -1 { | 319 | if strings.Index(b.url, "?") != -1 { |
| 288 | b.url = b.url + "?" + paramBody | ||
| 289 | } else { | ||
| 290 | b.url += "&" + paramBody | 320 | b.url += "&" + paramBody |
| 321 | } else { | ||
| 322 | b.url = b.url + "?" + paramBody | ||
| 291 | } | 323 | } |
| 292 | return | 324 | return |
| 293 | } | 325 | } |
| 294 | 326 | ||
| 295 | // build POST url and body | 327 | // build POST/PUT/PATCH url and body |
| 296 | if b.req.Method == "POST" && b.req.Body == nil { | 328 | if (b.req.Method == "POST" || b.req.Method == "PUT" || b.req.Method == "PATCH") && b.req.Body == nil { |
| 297 | // with files | 329 | // with files |
| 298 | if len(b.files) > 0 { | 330 | if len(b.files) > 0 { |
| 299 | pr, pw := io.Pipe() | 331 | pr, pw := io.Pipe() |
| ... | @@ -338,16 +370,29 @@ func (b *BeegoHttpRequest) getResponse() (*http.Response, error) { | ... | @@ -338,16 +370,29 @@ func (b *BeegoHttpRequest) getResponse() (*http.Response, error) { |
| 338 | if b.resp.StatusCode != 0 { | 370 | if b.resp.StatusCode != 0 { |
| 339 | return b.resp, nil | 371 | return b.resp, nil |
| 340 | } | 372 | } |
| 373 | resp, err := b.SendOut() | ||
| 374 | if err != nil { | ||
| 375 | return nil, err | ||
| 376 | } | ||
| 377 | b.resp = resp | ||
| 378 | return resp, nil | ||
| 379 | } | ||
| 380 | |||
| 381 | func (b *BeegoHttpRequest) SendOut() (*http.Response, error) { | ||
| 341 | var paramBody string | 382 | var paramBody string |
| 342 | if len(b.params) > 0 { | 383 | if len(b.params) > 0 { |
| 384 | var buf bytes.Buffer | ||
| 343 | for k, v := range b.params { | 385 | for k, v := range b.params { |
| 344 | paramBody += fmt.Sprintf("&%s=%v", url.QueryEscape(k), url.QueryEscape(v)) | 386 | buf.WriteString(url.QueryEscape(k)) |
| 387 | buf.WriteByte('=') | ||
| 388 | buf.WriteString(url.QueryEscape(v)) | ||
| 389 | buf.WriteByte('&') | ||
| 345 | } | 390 | } |
| 346 | paramBody = paramBody[1:] | 391 | paramBody = buf.String() |
| 392 | paramBody = paramBody[0 : len(paramBody)-1] | ||
| 347 | } | 393 | } |
| 348 | 394 | ||
| 349 | b.buildUrl(paramBody) | 395 | b.buildUrl(paramBody) |
| 350 | |||
| 351 | url, err := url.Parse(b.url) | 396 | url, err := url.Parse(b.url) |
| 352 | if err != nil { | 397 | if err != nil { |
| 353 | return nil, err | 398 | return nil, err |
| ... | @@ -357,13 +402,6 @@ func (b *BeegoHttpRequest) getResponse() (*http.Response, error) { | ... | @@ -357,13 +402,6 @@ func (b *BeegoHttpRequest) getResponse() (*http.Response, error) { |
| 357 | 402 | ||
| 358 | trans := b.setting.Transport | 403 | trans := b.setting.Transport |
| 359 | 404 | ||
| 360 | if b.setting.ConnectTimeout == 0 { | ||
| 361 | b.setting.ConnectTimeout = 60 * time.Second | ||
| 362 | } | ||
| 363 | if b.setting.ReadWriteTimeout == 0 { | ||
| 364 | b.setting.ReadWriteTimeout = 60 * time.Second | ||
| 365 | } | ||
| 366 | |||
| 367 | if trans == nil { | 405 | if trans == nil { |
| 368 | // create default transport | 406 | // create default transport |
| 369 | trans = &http.Transport{ | 407 | trans = &http.Transport{ |
| ... | @@ -404,15 +442,13 @@ func (b *BeegoHttpRequest) getResponse() (*http.Response, error) { | ... | @@ -404,15 +442,13 @@ func (b *BeegoHttpRequest) getResponse() (*http.Response, error) { |
| 404 | } | 442 | } |
| 405 | 443 | ||
| 406 | if b.setting.ShowDebug { | 444 | if b.setting.ShowDebug { |
| 407 | dump, err := httputil.DumpRequest(b.req, true) | 445 | dump, err := httputil.DumpRequest(b.req, b.setting.DumpBody) |
| 408 | if err != nil { | 446 | if err != nil { |
| 409 | log.Println(err.Error()) | 447 | log.Println(err.Error()) |
| 410 | } | 448 | } |
| 411 | b.dump = dump | 449 | b.dump = dump |
| 412 | } | 450 | } |
| 413 | 451 | return client.Do(b.req) | |
| 414 | b.resp, err = client.Do(b.req) | ||
| 415 | return b.resp, err | ||
| 416 | } | 452 | } |
| 417 | 453 | ||
| 418 | // String returns the body string in response. | 454 | // String returns the body string in response. |
| ... | @@ -433,9 +469,12 @@ func (b *BeegoHttpRequest) Bytes() ([]byte, error) { | ... | @@ -433,9 +469,12 @@ func (b *BeegoHttpRequest) Bytes() ([]byte, error) { |
| 433 | return b.body, nil | 469 | return b.body, nil |
| 434 | } | 470 | } |
| 435 | resp, err := b.getResponse() | 471 | resp, err := b.getResponse() |
| 436 | if resp == nil || resp.Body == nil { | 472 | if err != nil { |
| 437 | return nil, err | 473 | return nil, err |
| 438 | } | 474 | } |
| 475 | if resp.Body == nil { | ||
| 476 | return nil, nil | ||
| 477 | } | ||
| 439 | defer resp.Body.Close() | 478 | defer resp.Body.Close() |
| 440 | if b.setting.Gzip && resp.Header.Get("Content-Encoding") == "gzip" { | 479 | if b.setting.Gzip && resp.Header.Get("Content-Encoding") == "gzip" { |
| 441 | reader, err := gzip.NewReader(resp.Body) | 480 | reader, err := gzip.NewReader(resp.Body) |
| ... | @@ -452,18 +491,20 @@ func (b *BeegoHttpRequest) Bytes() ([]byte, error) { | ... | @@ -452,18 +491,20 @@ func (b *BeegoHttpRequest) Bytes() ([]byte, error) { |
| 452 | // ToFile saves the body data in response to one file. | 491 | // ToFile saves the body data in response to one file. |
| 453 | // it calls Response inner. | 492 | // it calls Response inner. |
| 454 | func (b *BeegoHttpRequest) ToFile(filename string) error { | 493 | func (b *BeegoHttpRequest) ToFile(filename string) error { |
| 455 | resp, err := b.getResponse() | ||
| 456 | if resp == nil || resp.Body == nil { | ||
| 457 | return err | ||
| 458 | } | ||
| 459 | defer resp.Body.Close() | ||
| 460 | |||
| 461 | f, err := os.Create(filename) | 494 | f, err := os.Create(filename) |
| 462 | if err != nil { | 495 | if err != nil { |
| 463 | return err | 496 | return err |
| 464 | } | 497 | } |
| 465 | defer f.Close() | 498 | defer f.Close() |
| 466 | 499 | ||
| 500 | resp, err := b.getResponse() | ||
| 501 | if err != nil { | ||
| 502 | return err | ||
| 503 | } | ||
| 504 | if resp.Body == nil { | ||
| 505 | return nil | ||
| 506 | } | ||
| 507 | defer resp.Body.Close() | ||
| 467 | _, err = io.Copy(f, resp.Body) | 508 | _, err = io.Copy(f, resp.Body) |
| 468 | return err | 509 | return err |
| 469 | } | 510 | } | ... | ... |
-
Please register or sign in to post a comment