diff --git a/proxy/http/server.go b/proxy/http/server.go index b89c67c0ed43..349ba7dde647 100644 --- a/proxy/http/server.go +++ b/proxy/http/server.go @@ -312,8 +312,9 @@ func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, wri // Sometimes, server might send 1xx response to client // it should not be processed by http proxy handler, just forward it to client func readResponseAndHandle100Continue(r *bufio.Reader, req *http.Request, writer io.Writer) (*http.Response, error) { - // have a little look of response - peekBytes, err := r.Peek(56) + // Wait for the HTTP/1.x status prefix before inspecting the buffered response. + r.Peek(12) + peekBytes, err := r.Peek(min(56, r.Buffered())) if err == nil || err == bufio.ErrBufferFull { str := string(peekBytes) ResponseLine := strings.Split(str, "\r\n")[0] diff --git a/proxy/http/server_test.go b/proxy/http/server_test.go index 2578d5315e97..5b3563315de8 100644 --- a/proxy/http/server_test.go +++ b/proxy/http/server_test.go @@ -7,6 +7,7 @@ import ( "net/http" "strings" "testing" + "testing/iotest" ) // A malformed upstream response containing a bare '\n' before the real @@ -29,7 +30,7 @@ func TestReadResponseAndHandle100ContinueDoesNotPanicOnEarlyNewline(t *testing.T func TestReadResponseAndHandle100ContinueForwardsAndParsesFinalResponse(t *testing.T) { payload := "HTTP/1.1 100 Continue\r\n\r\n" + "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nhello" - r := bufio.NewReader(bytes.NewReader([]byte(payload))) + r := bufio.NewReader(iotest.OneByteReader(bytes.NewReader([]byte(payload)))) req, err := http.NewRequest("GET", "http://example.com/", nil) if err != nil { t.Fatal(err)