问题描述:
使用client.do(....)循环发送http 消息的时候,会报http: ContentLength=27 with Body length 0 错误。
原因是:
client.do(...)函数中发送完一次req之后,会将req中的body清空导致的。
func (c *Client) do(req *Request) (retres *Response, reterr error) {
....
req.closeBody()
....
}
问题复现例子:
package main
import (
"fmt"
"net/http"
"time"
"bytes"
)
func main() {
tr := &http.Transport{
MaxIdleConns: 10,
IdleConnTimeout: 30 * time.Second,
DisableCompression: true,
}
client := &http.Client{Transport: tr}
str := "hello world, I am http body"
// 这里的req是全局的,所有的发送消息都会使用这个req
req, err := http.NewRequest("GET", "http://127.0.0.1/", bytes.NewReader([]byte(str)))
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("If-None-Match", `W/"wyzzy"`)
for i:=0;i<5;i++ {
resp, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%s \n", resp)
}
}
输出结果:
$ ./client //第一次发送成功,后面发送都会失败。
&{200 OK %!s(int=200) HTTP/1.1 %!s(int=1) %!s(int=1) map[Content-Length:[23] Content-Type:[text/plain; charset=utf-8] Date:[Tue, 22 Dec 2020 09:19:43 GMT]] %!s(*http.bodyEOFSignal=&{0xc000090040 {0 0} false <nil> 0x12348c0 0x1234850}) %!s(int64=23) [] %!s(bool=false) %!s(bool=false) map[] %!s(*http.Request=&{GET 0xc000132000 HTTP/1.1 1 1 map[If-None-Match:[W/"wyzzy"]] {0xc000066c30} 0x1233870 27 [] false 127.0.0.1 map[] map[] <nil> map[] <nil> <nil> <nil> 0xc000016088}) %!s(*tls.ConnectionState=<nil>)}
Get "http://127.0.0.1/": http: ContentLength=27 with Body length 0
%!s(*http.Response=<nil>)
Get "http://127.0.0.1/": http: ContentLength=27 with Body length 0
%!s(*http.Response=<nil>)
Get "http://127.0.0.1/": http: ContentLength=27 with Body length 0
%!s(*http.Response=<nil>)
Get "http://127.0.0.1/": http: ContentLength=27 with Body length 0
%!s(*http.Response=<nil>)
代码修复例子:
package main
import (
"fmt"
"net/http"
"time"
"bytes"
)
func main() {
tr := &http.Transport{
MaxIdleConns: 10,
IdleConnTimeout: 30 * time.Second,
DisableCompression: true,
}
client := &http.Client{Transport: tr}
str := "hello world, I am http body"
for i:=0;i<5;i++ {
req, err := http.NewRequest("GET", "http://127.0.0.1/", bytes.NewReader([]byte(str)))
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%s \n", resp)
}
}
修复后的执行结果:
$ ./client
&{200 OK %!s(int=200) HTTP/1.1 %!s(int=1) %!s(int=1) map[Content-Length:[23] Content-Type:[text/plain; charset=utf-8] Date:[Tue, 22 Dec 2020 09:23:42 GMT]] %!s(*http.bodyEOFSignal=&{0xc0001462c0 {0 0} false <nil> 0x12348c0 0x1234850}) %!s(int64=23) [] %!s(bool=false) %!s(bool=false) map[] %!s(*http.Request=&{GET 0xc00016a000 HTTP/1.1 1 1 map[If-None-Match:[W/"wyzzy"]] {0xc000114c30} 0x1233870 27 [] false 127.0.0.1 map[] map[] <nil> map[] <nil> <nil> <nil> 0xc00012e008}) %!s(*tls.ConnectionState=<nil>)}
&{200 OK %!s(int=200) HTTP/1.1 %!s(int=1) %!s(int=1) map[Content-Length:[23] Content-Type:[text/plain; charset=utf-8] Date:[Tue, 22 Dec 2020 09:23:42 GMT]] %!s(*http.bodyEOFSignal=&{0xc00009c000 {0 0} false <nil> 0x12348c0 0x1234850}) %!s(int64=23) [] %!s(bool=false) %!s(bool=false) map[] %!s(*http.Request=&{GET 0xc00016a200 HTTP/1.1 1 1 map[If-None-Match:[W/"wyzzy"]] {0xc0001150e0} 0x1233870 27 [] false 127.0.0.1 map[] map[] <nil> map[] <nil> <nil> <nil> 0xc00012e008}) %!s(*tls.ConnectionState=<nil>)}
&{200 OK %!s(int=200) HTTP/1.1 %!s(int=1) %!s(int=1) map[Content-Length:[23] Content-Type:[text/plain; charset=utf-8] Date:[Tue, 22 Dec 2020 09:23:42 GMT]] %!s(*http.bodyEOFSignal=&{0xc0001a4000 {0 0} false <nil> 0x12348c0 0x1234850}) %!s(int64=23) [] %!s(bool=false) %!s(bool=false) map[] %!s(*http.Request=&{GET 0xc0000ae000 HTTP/1.1 1 1 map[If-None-Match:[W/"wyzzy"]] {0xc000096180} 0x1233870 27 [] false 127.0.0.1 map[] map[] <nil> map[] <nil> <nil> <nil> 0xc00012e008}) %!s(*tls.ConnectionState=<nil>)}
&{200 OK %!s(int=200) HTTP/1.1 %!s(int=1) %!s(int=1) map[Content-Length:[23] Content-Type:[text/plain; charset=utf-8] Date:[Tue, 22 Dec 2020 09:23:42 GMT]] %!s(*http.bodyEOFSignal=&{0xc00009c100 {0 0} false <nil> 0x12348c0 0x1234850}) %!s(int64=23) [] %!s(bool=false) %!s(bool=false) map[] %!s(*http.Request=&{GET 0xc00016a380 HTTP/1.1 1 1 map[If-None-Match:[W/"wyzzy"]] {0xc000115440} 0x1233870 27 [] false 127.0.0.1 map[] map[] <nil> map[] <nil> <nil> <nil> 0xc00012e008}) %!s(*tls.ConnectionState=<nil>)}
&{200 OK %!s(int=200) HTTP/1.1 %!s(int=1) %!s(int=1) map[Content-Length:[23] Content-Type:[text/plain; charset=utf-8] Date:[Tue, 22 Dec 2020 09:23:42 GMT]] %!s(*http.bodyEOFSignal=&{0xc0001a4080 {0 0} false <nil> 0x12348c0 0x1234850}) %!s(int64=23) [] %!s(bool=false) %!s(bool=false) map[] %!s(*http.Request=&{GET 0xc0000ae180 HTTP/1.1 1 1 map[If-None-Match:[W/"wyzzy"]] {0xc000096510} 0x1233870 27 [] false 127.0.0.1 map[] map[] <nil> map[] <nil> <nil> <nil> 0xc00012e008}) %!s(*tls.ConnectionState=<nil>)}