2014-09-25 5 views
4

은 우리가 HTTP 요청을 처리하는 기능, 같은 있다고 가정 :HTTP ResponseWriter의 쓰기 함수 버퍼가 Go에 있습니까?

func handler(w http.ResponseWriter, r *http.Request) { 
    w.Write([]byte("first piece of data")) 
    // do something 
    w.Write([]byte("second piece of data")) 
} 

내가 궁금하네요을 w.Write()에 대한 첫 번째 호출은 클라이언트에 플러시인지 아닌지가?

플러시되면 클라이언트에 실제로 두 번 응답합니다. 두 번째 호출하기 전에 Content-Length을 어떻게 결정할 수 있습니까?

플러시되지 않으면 (데이터가 로컬로 버퍼 됨) 첫 번째 호출에서 방대한 양의 데이터를 쓰면 어떻게 될까요? (스택 오버플로가됩니까?)

모든 설명을 이해할 수 있습니다! :)

답변

5

w.Write()에 대한 첫 번째 호출이 클라이언트로 플러시되는지 여부가 궁금합니다.

net/http의 기본 ResonseWriter는에 기록하는 net.Conn 위에 (현재 4킬로바이트) 큰 출력 버퍼를 갖는다. 또한 OS는 일반적으로 소켓에 쓰기를 버퍼링합니다. 그래서 대부분의 경우 어떤 종류의 버퍼링이 발생합니다.

플러시되면 클라이언트에 실제로 두 번 응답합니다. 두 번째 호출 전에 Content-Length를 어떻게 결정할 수 있습니까?

그럼 영구 연결을 허용하는 HTTP 1.1이 있습니다. 이러한 응답에는 대개 Content-Length 헤더가 포함되지 않습니다. 또한 HTTP 예고편이 있습니다.

클라이언트가 HTTP 1.1 및 영구 연결을 지원하지 않으면 몇 가지 종류의 읽기 시간 초과가 발생합니다.이 시간 동안 원하는만큼 연결에 쓸 수 있습니다. 그것은 하나의 응답입니다.

이것은 Go보다 TCP 소켓 및 HTTP 구현의 특성과 관련이 있습니다.

플러시되지 않으면 (데이터가 로컬로 버퍼 됨) 첫 번째 호출에서 방대한 양의 데이터를 쓰면 어떻게 될까요? (스택 오버플로가됩니까?)

아니요, 스택에 버퍼를 할당하면 버퍼 몸체가 힙에 살게됩니다. –. 프로세스 당 메모리 제한에 도달하면 응용 프로그램이 "메모리 부족"을 당황하게됩니다.

은 참조 :

편집 코멘트에있는 당신의 질문에 대답 :

Chunked Transfer Encoding는 HTTP 1.1 사양의 일부이며 HTTP에서 지원되지 않습니다 1.0.

편집 명확히 :

만큼이 고객의 시간 읽어 초과하지 않는 응답의 두 부분을 쓰기로 이동, 당신은 당신이 방금 편지 Content-Length 헤더를 지정하지 않은 총 시간로 응답을 누른 다음 연결을 닫습니다. 그건 완전히 정상이며 "해킹"이 아닙니다.

+0

HTTP 트레일러는 Go의'net/http' 서버와 클라이언트 구현에서 모두 지원됩니다. 그리고 아니요, 읽기 시간 제한이없는 클라이언트는 하루 종일 지속되지 않습니다. HTTP의 서버 출력 버퍼링 전략은 HTTP 및 예와 전혀 관련이 없습니다. OS 버퍼는 HTTP에 TCP 소켓 인 소켓에 버퍼링합니다. 당신은 다른 사람들의 대답을 강타하려고 너무 열심히 노력하고 있습니다. – thwd

+2

[예 그들은 있습니다] (https://golang.org/src/pkg/net/http/transfer.go#L32), 앞으로 귀하의 의견을 무시하겠습니다. – thwd

+1

[주석 ​​달기를 중단하십시오.] (https://golang.org/src/pkg/net/http/response.go#L253) – thwd