Skip to content

Commit

Permalink
Only peek 1 byte
Browse files Browse the repository at this point in the history
Make sure old clients that send bogus \r\n still work.
See: golang/go@bf5e19f
  • Loading branch information
erikdubbelboer committed Jun 25, 2021
1 parent 7c0d205 commit 643b0aa
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 1 deletion.
2 changes: 1 addition & 1 deletion server.go
Expand Up @@ -2056,7 +2056,7 @@ func (s *Server) serveConn(c net.Conn) (err error) {
// within the idle time.
if connRequestNum > 1 {
var b []byte
b, err = br.Peek(4)
b, err = br.Peek(1)
if len(b) == 0 {
// If reading from a keep-alive connection returns nothing it means
// the connection was closed (either timeout or from the other side).
Expand Down
88 changes: 88 additions & 0 deletions server_test.go
Expand Up @@ -23,6 +23,94 @@ import (
// Make sure RequestCtx implements context.Context
var _ context.Context = &RequestCtx{}

func TestServerCRNLAfterPost_Pipeline(t *testing.T) {
t.Parallel()

s := &Server{
Handler: func(ctx *RequestCtx) {
},
Logger: &testLogger{},
}

ln := fasthttputil.NewInmemoryListener()
defer ln.Close()

go func() {
if err := s.Serve(ln); err != nil {
t.Errorf("unexpected error: %s", err)
}
}()

c, err := ln.Dial()
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
defer c.Close()
if _, err = c.Write([]byte("POST / HTTP/1.1\r\nHost: golang.org\r\nContent-Length: 3\r\n\r\nABC" +
"\r\n\r\n" + // <-- this stuff is bogus, but we'll ignore it
"GET / HTTP/1.1\r\nHost: golang.org\r\n\r\n")); err != nil {
t.Fatal(err)
}

br := bufio.NewReader(c)
var resp Response
if err := resp.Read(br); err != nil {
t.Fatalf("unexpected error: %s", err)
}
if resp.StatusCode() != StatusOK {
t.Fatalf("unexpected status code: %d. Expecting %d", resp.StatusCode(), StatusOK)
}
if err := resp.Read(br); err != nil {
t.Fatalf("unexpected error: %s", err)
}
if resp.StatusCode() != StatusOK {
t.Fatalf("unexpected status code: %d. Expecting %d", resp.StatusCode(), StatusOK)
}
}

func TestServerCRNLAfterPost(t *testing.T) {
t.Parallel()

s := &Server{
Handler: func(ctx *RequestCtx) {
},
Logger: &testLogger{},
ReadTimeout: time.Millisecond * 1,
}

ln := fasthttputil.NewInmemoryListener()
defer ln.Close()

go func() {
if err := s.Serve(ln); err != nil {
t.Errorf("unexpected error: %s", err)
}
}()

c, err := ln.Dial()
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
defer c.Close()
if _, err = c.Write([]byte("POST / HTTP/1.1\r\nHost: golang.org\r\nContent-Length: 3\r\n\r\nABC" +
"\r\n\r\n", // <-- this stuff is bogus, but we'll ignore it
)); err != nil {
t.Fatal(err)
}

br := bufio.NewReader(c)
var resp Response
if err := resp.Read(br); err != nil {
t.Fatalf("unexpected error: %s", err)
}
if resp.StatusCode() != StatusOK {
t.Fatalf("unexpected status code: %d. Expecting %d", resp.StatusCode(), StatusOK)
}
if err := resp.Read(br); err == nil {
t.Fatal("expected error") // We didn't send a request so we should get an error here.
}
}

func TestServerPipelineFlush(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit 643b0aa

Please sign in to comment.