NetworkStream.DataAvailable는 HTTP 응답의 끝을 표시하지 않는다
종료 조건으로 NetworkStream.DataAvailable 대신 메시지 프레이밍을 사용하여 잘린 HTTP 다운로드를 막으십시오.
NetworkStream.DataAvailable == false는 즉시 읽을 수 있는 바이트가 없다는 뜻이다. HTTP 응답이 완료되었다는 뜻은 아니다. 여기서 멈추는 루프는 패킷 사이의 간격에서 지극히 정상적인 SOCKS 다운로드를 잘라낼 수 있다.
SOCKS가 TCP 연결을 맺은 뒤에도 완료 규칙은 여전히 HTTP 프레이밍이 제공한다:
- Content-Length 본문은 선언된 콘텐츠 바이트 뒤에 끝난다.
- chunked 응답에는 종료 chunk와 해당 trailer가 필요하다.
- 연결로 구분되는 응답은 연결과 함께 끝난다.
- 일부 상태와 HEAD에 대한 응답에는 본문이 없다.
적용되는 규칙을 정하려면 상태와 헤더를 읽어야 한다. 종료만 기다리는 것은 일반적인 해결책이 아니다. 완전한 HTTP 응답도 연결을 열어 둘 수 있기 때문이다. 버퍼 하나의 용량도 응답 길이와 무관하다.
선택한 프록시 전송을 HTTP 클라이언트의 프레이밍 구현이 지원하면 그것을 사용하십시오. 호환되는 최신 .NET 런타임에서는 HttpClient의 기본 SOCKS 지원을 고려하십시오. 직접 구현은 부분 헤더와 본문 읽기 전반에 걸쳐 파싱 상태를 유지해야 하며, 성공적 완료를 취소, 시간 초과, 예기치 않은 EOF와 구분해야 한다. 비어 있지 않은 읽기 요청에서 0바이트를 읽었다는 것은 스트림이 끝났다는 뜻이다. 이는 지금 대기열에 바이트가 없다는 것과 다르다.
프록시는 타이밍 간격을 눈에 띄게 만들 수 있지만, 빈 수신 대기열을 메시지 끝 표시로 바꾸지는 않는다.