GetRequestStream (또는 BeginGetRequestStream)을 호출하기 전에 ContentLength 속성을 설정 한 다음 해당 스트림에 더 적은 바이트를 씁니다. 요청 스트림을받은 후에 ContentLength를 설정하려고하면 ContentLength가 발생합니다. ContentLength를 설정하지 않으면 스트림이 닫힐 때까지 HttpWebRequest가 헤더를 버퍼링하여 적절하게 ContentLength를 설정할 수 있습니다 (또는 SendChunked를 사용할 수 있지만 여기서는 사용할 수 없습니다). 이 것을 최대한 제어하려면 악의적 인 요청을 한두 씩 작성한 다음 서버의 포트 80에 대한 소켓을 열고 TCP 스트림에 요청을 작성한 다음 응답을 읽고 연결을 확인하여 닫혀 있는지 확인하십시오 .
그러나이 테스트가 좋은 생각이라고 생각하지 않습니다. 문제는 다음과 같습니다.
클라이언트가 서버에 요청을 보냅니다. 내용이 100 바이트라고 주장합니다. 그런 다음 90 바이트를 전송 한 다음 전송을 중지하고 연결을 열린 상태로 둡니다. 서버는 90 바이트를 읽은 다음 클라이언트가 100 바이트를 전송한다고 말한 이후로 나머지를 기다립니다. 이제 클라이언트는 두 번째 요청을 보냅니다. 서버가 새로운 요청의 처음 10 바이트를 어떻게 처리합니까?
대답은 서버가 그 바이트가 이전 요청의 일부라고 가정하고이를 처리 한 다음 시작 후 10 바이트가되는 "새로운"요청 읽기를 시작하므로 분명히 잘못된 헤더가 생성됩니다. 서버가 그것을 좋아하지 않으므로 4xx 오류를 보내고 연결을 닫습니다. 연결을 닫는 이유는 데이터가 전송되는 의미와 복구 할 수없는 방법을 알 수 없기 때문입니다. 또한 연결이 닫히는 것은 적절하지 않을 것입니다. 갑자기 두 번째 요청을 제출하는 상대방의 HttpWebRequest (또는 큐에 대기중인 경우 세 번째 또는 네 번째)가 WebException을 throw합니다. 기본 연결이 닫히고 왜 그런지 짐작할 수 있습니다.
동일한 동작으로 인해 Expect 100-continue 헤더로 연결이 닫히고 서 버는 인증이 필요할 때와 같이 100-continue와 4xx를 반환합니다. 요청을 거부하더라도 다음 바이트가 100-continue를 전송하여 해당 바이트를 수신하기로 약속 했으므로 다음 바이트가 동일한 요청의 일부라고 가정해야합니다.요청을 처리하지 못하거나 클라이언트가 요청을 취소하고 새 인증을 제출하려는 경우 (아마도 인증 자격 증명을 사용하여) 연결을 닫고 새 인증서를 열어야합니다.
마지막으로 TCP를 사용하여 네트워크 스트림에서 EndOfStreamException을 테스트하는 것은 전혀 의미가 없습니다. TCP는 스트림의 "끝"을 표시하지 않고 소켓에 기록 된대로 데이터를 계속 전송합니다. 데이터에 대한 "EOF"가 없으며 예상 데이터 양을 알지 못하면 데이터가 모두 전송되었는지 여부를 감지 할 수 없습니다. 연결이 닫히지 않는 한 TCP는 실제로 스트림의 "끝"을 갖지 않습니다.이 경우 스택에서 어디서 작동하는지에 따라 WebException 또는 SocketException이 발생합니다. 프로토콜의 모든 전송 오류는 winsock에서 처리됩니다. 데이터가 더 이상 전송되지 않으면 연결의 한쪽 끝에서 다른 쪽 연결에 키를 보내 결국 연결이 실제로 열려 있는지 그리고 한 호스트가 연결을 끊어 버리지 않았는지 확인합니다. keepalive가 시간 초과되면 연결이 닫히고 다음 번에 연결을 읽으려고 할 때 WebException이 발생할 수 있습니다. 이 모든 것이 어떻게 작동하는지 감안할 때, 나는이 테스트에서 어떤 가치를 얻을 수 있는지 보지 못합니다. 잘못된 요청을 보내고 그에 따라 오류가 처리되고 적절한 4xx 메시지가 클라이언트로 보내지고 연결이 제대로 닫히고 있는지 확인하는 것이 훨씬 낫습니다.
통합 테스트는 클라이언트를 시뮬레이션합니다. 테스트를 용이하게하기 위해 수신 측을 변경할 수 없습니다. – cfeduke