# #http #go #cancellation #go-context
Вопрос:
мой код такой:
package main
import (
"context"
"fmt"
"io"
"net/http"
"os"
)
var (
client = http.DefaultClient
)
func do(pctx context.Context, req *http.Request) (*http.Response, error) {
// in order to not capture the pctx.Done. the caller may capture the pctx.Done().
ctx, cancel := context.WithCancel(pctx)
defer cancel()
req = req.WithContext(ctx)
resp, err := client.Do(req)
if err != nil {
select {
case <-ctx.Done():
return nil, ctx.Err()
}
}
return resp, err
}
func main() {
req, err := http.NewRequest(http.MethodGet, "http://www.google.com", nil)
if err != nil {
panic(err)
}
resp, err := do(context.Background(), req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
_, err = io.Copy(os.Stdout, resp.Body)
fmt.Println()
fmt.Println()
fmt.Println(err)
}
Это выводит
$ go run .
<!doctype html><ht[...... removed for conciseness]
context canceled
Этот код неверен. контекст будет отменен, когда я прочитаю данные из соотв.тела, Как я могу отменить контекст, будет ли контекст автоматически отменен во время обработки http-запроса ?
Спасибо.
Комментарии:
1. Если вы позвоните
cancel
(в отдельном режиме), покаclient.Do
активны, запрос будет прерван. В чем, собственно, вопрос?2. Поскольку, в моем понимании, я создал контекст, я должен закрыть его сам. Это правильно? или, если я не отменю контекст, он не сможет вызвать утечку памяти.
3. Проблема в том, что вы отменили функцию context (
defer cancel
) до того, как тело ответа было полностью прочитано. Вы должны отменить контекст только после того, как отправили запрос, и полностью прочитать его ответ.