golang 표준 라 이브 러 리 http 의 client 는 왜 resp. Body 를 수 동 으로 닫 아야 합 니까?
3109 단어 golang
resp, err := http.Get(...)
if err != nil {
..
}
defer resp.Body.Close()
왜 꼭
resp.Body.Close()
해 야 합 니까?이 질문 에 대답 하려 면 사실 두 가지 질문 에 대답 해 야 한다.resp.Body.Close()
뭐 했 어 요?1
resp.Body.Close()
뭐 했 어 요?Close 방법 이 무엇 을 했 는 지 확인 하기 위해 서 는
resp.Body
구체 적 으로 어떻게 이 루어 졌 는 지 확인 해 야 한다.http client 가 timeout 을 설정 할 지 여 부 는 resp.Body
의 두 가지 실현 을 결정 합 니 다. 첫째, timeout 을 설정 합 니 다.cli := http.Client{Timeout: time.Second}
resp, _ := cli.Get(...)
이 경우
resp.Body
는 cancelTimerBody
두 번 째 로 timeout 을 설치 하지 않 는 경우 resp.Body
는 bodyEOFSignal
그런 경우 에 도 불구 하고 이 두 가지 body 는 결국 봉 인 된 이 body 입 니 다.// body turns a Reader into a ReadCloser.
// Close ensures that the body has been fully read
// and then reads the trailer if necessary.
type body struct {
src io.Reader
hdr interface{} // non-nil (Response or Request) value means read trailer
r *bufio.Reader // underlying wire-format reader for the trailer
closing bool // is the connection to be closed after reading body?
doEarlyClose bool // whether Close should stop early
mu sync.Mutex // guards following, and calls to Read and Close
sawEOF bool
closed bool
earlyClose bool // Close called and we didn't read to the end of src
onHitEOF func() // if non-nil, func to call when EOF is Read
}
그래서 최종 close 방법 은 이 논 리 를 수행 합 니 다.
func (b *body) Close() error {
b.mu.Lock()
defer b.mu.Unlock()
if b.closed {
return nil
}
var err error
switch {
case b.sawEOF:
// Already saw EOF, so no need going to look for it.
case b.hdr == nil && b.closing:
// no trailer and closing the connection next.
// no point in reading to EOF.
case b.doEarlyClose:
// Read up to maxPostHandlerReadBytes bytes of the body, looking
// for EOF (and trailers), so we can re-use this connection.
if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > maxPostHandlerReadBytes {
// There was a declared Content-Length, and we have more bytes remaining
// than our maxPostHandlerReadBytes tolerance. So, give up.
b.earlyClose = true
} else {
var n int64
// Consume the body, or, which will also lead to us reading
// the trailer headers after the body, if present.
n, err = io.CopyN(ioutil.Discard, bodyLocked{b}, maxPostHandlerReadBytes)
if err == io.EOF {
err = nil
}
if n == maxPostHandlerReadBytes {
b.earlyClose = true
}
}
default:
// Fully consume the body, which will also lead to us reading
// the trailer headers after the body, if present.
_, err = io.Copy(ioutil.Discard, bodyLocked{b})
}
b.closed = true
return err
}
위의 코드 주석 에서 말 한 바 와 같이
Close ensures that the body has been fully read
바디 가 깨끗하게 읽 을 수 있 도록 하 는 데 쓰 인 다.2. 왜 그 랬 어 요?
간단 하 다:
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
set containerThere is no built-in set container in Go How to implement Set struct{} => type struct{}{} => 0bytes How to create set :=...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.