提交 661fb0a4 作者: Tor Arne Vestbø 提交者: Tor Arne Vestbø

Teach http client to cancel request on context cancellation

The context may be cancelled while a request is in flight. We need to
handle this and cancel the request. The code is based on the ideas
from https://blog.golang.org/context
上级 3d057642
......@@ -82,25 +82,44 @@ func (c *client) Send(req cmds.Request) (cmds.Response, error) {
version := config.CurrentVersionNumber
httpReq.Header.Set("User-Agent", fmt.Sprintf("/go-ipfs/%s/", version))
httpRes, err := http.DefaultClient.Do(httpReq)
if err != nil {
return nil, err
}
// using the overridden JSON encoding in request
res, err := getResponse(httpRes, req)
if err != nil {
return nil, err
}
ec := make(chan error, 1)
rc := make(chan cmds.Response, 1)
dc := req.Context().Context.Done()
if found && len(previousUserProvidedEncoding) > 0 {
// reset to user provided encoding after sending request
// NB: if user has provided an encoding but it is the empty string,
// still leave it as JSON.
req.SetOption(cmds.EncShort, previousUserProvidedEncoding)
go func() {
httpRes, err := http.DefaultClient.Do(httpReq)
if err != nil {
ec <- err
return
}
// using the overridden JSON encoding in request
res, err := getResponse(httpRes, req)
if err != nil {
ec <- err
return
}
rc <- res
}()
for {
select {
case <-dc:
log.Debug("Context cancelled, cancelling HTTP request...")
tr := http.DefaultTransport.(*http.Transport)
tr.CancelRequest(httpReq)
dc = nil // Wait for ec or rc
case err := <-ec:
return nil, err
case res := <-rc:
if found && len(previousUserProvidedEncoding) > 0 {
// reset to user provided encoding after sending request
// NB: if user has provided an encoding but it is the empty string,
// still leave it as JSON.
req.SetOption(cmds.EncShort, previousUserProvidedEncoding)
}
return res, nil
}
}
return res, nil
}
func getQuery(req cmds.Request) (string, error) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论