我有与https://github.com/golang/go/issues/26666相同的问题,因为我为我的http请求编写了一个包装函数。
有时我需要发出请求:
body := new(bytes.Buffer)
json.NewEncoder(body).Encode(h)
req("POST", "http://example.com", body)
有时候,这很简单:
req("GET", "http://example.com", nil)
runtime error: invalid memory address or nil pointer dereference
我最终得到了以下内容:
req("GET", "http://example.com", new(bytes.Buffer))
但我不确定这是否是正确的做法。
该函数:
func req(method string, url string, body *bytes.Buffer) int {
req, err := http.NewRequest(method, url, body)
req.Header.Set("Content-Type", "application/json")
req.SetBasicAuth(user, psw)
resp, err := client.Do(req)
checkErr(err)
if resp.StatusCode > 500 {
time.Sleep(30 * time.Second)
resp, err = client.Do(req)
checkErr(err)
}
defer resp.Body.Close()
return resp.StatusCode
}
更新的功能:
func req(method string, url string, body io.Reader) int {
req, err := http.NewRequest(method, url, body)
req.Header.Set("Content-Type", "application/json")
req.SetBasicAuth(user, psw)
resp, err := client.Do(req)
checkErr(err)
defer resp.Body.Close()
if resp.StatusCode >= 500 {
time.Sleep(30 * time.Second)
req, err := http.NewRequest(method, url, body)
req.Header.Set("Content-Type", "application/json")
req.SetBasicAuth(user, psw)
resp, err := client.Do(req)
checkErr(err)
defer resp.Body.Close()
}
return resp.StatusCode
}
func checkErr(err error) {
if err != nil {
log.Fatal(err)
}
}
>=
?)。 - Peterresp
的StatusCode大于500,你会进行另一个请求并使用结果覆盖原始的resp
值,而没有在原始的resp
上调用Body.Close()
。长时间和足够的500+响应会导致你的程序耗尽文件描述符最终崩溃。你需要关闭两个响应的主体。 - mkopriva