diff options
author | ArminBTVS <98586621+ArminBTVS@users.noreply.github.com> | 2022-03-14 10:53:16 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-14 10:53:16 +0100 |
commit | 1a5f2f40c6a75d42c5c5935efc73f79644cd5b73 (patch) | |
tree | 96fcff0fa6f774b124b7ffb23e422731377f15b4 /client_unix_test.go | |
parent | Update github.com/klauspost/compress (#1237) (diff) | |
download | fasthttp-1a5f2f40c6a75d42c5c5935efc73f79644cd5b73.tar.gz fasthttp-1a5f2f40c6a75d42c5c5935efc73f79644cd5b73.tar.bz2 fasthttp-1a5f2f40c6a75d42c5c5935efc73f79644cd5b73.zip |
* Read response when client closes connection #1232
* Fix edge case were client responds with invalid header
* Follow linter suggestions for tests
* Changes after review
* Reafactor error check after review
* Handle connection reset on windows
* Remove format string from test where not needed
* Run connection reset tests not on Windows
Diffstat (limited to 'client_unix_test.go')
-rw-r--r-- | client_unix_test.go | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/client_unix_test.go b/client_unix_test.go new file mode 100644 index 0000000..f369111 --- /dev/null +++ b/client_unix_test.go @@ -0,0 +1,136 @@ +//go:build !windows +// +build !windows + +package fasthttp + +import ( + "io" + "io/ioutil" + "net" + "net/http" + "strings" + "testing" +) + +// See issue #1232 +func TestRstConnResponseWhileSending(t *testing.T) { + const expectedStatus = http.StatusTeapot + const payload = "payload" + + srv, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + defer srv.Close() + + go func() { + for { + conn, err := srv.Accept() + if err != nil { + return + } + + // Read at least one byte of the header + // Otherwise we would have an unsolicited response + _, err = ioutil.ReadAll(io.LimitReader(conn, 1)) + if err != nil { + t.Error(err) + } + + // Respond + _, err = conn.Write([]byte("HTTP/1.1 418 Teapot\r\n\r\n")) + if err != nil { + t.Error(err) + } + + // Forcefully close connection + err = conn.(*net.TCPConn).SetLinger(0) + if err != nil { + t.Error(err) + } + conn.Close() + } + }() + + svrUrl := "http://" + srv.Addr().String() + client := HostClient{Addr: srv.Addr().String()} + + for i := 0; i < 100; i++ { + req := AcquireRequest() + defer ReleaseRequest(req) + resp := AcquireResponse() + defer ReleaseResponse(resp) + + req.Header.SetMethod("POST") + req.SetBodyStream(strings.NewReader(payload), len(payload)) + req.SetRequestURI(svrUrl) + + err = client.Do(req, resp) + if err != nil { + t.Fatal(err) + } + if expectedStatus != resp.StatusCode() { + t.Fatalf("Expected %d status code, but got %d", expectedStatus, resp.StatusCode()) + } + } +} + +// See issue #1232 +func TestRstConnClosedWithoutResponse(t *testing.T) { + const payload = "payload" + + srv, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + defer srv.Close() + + go func() { + for { + conn, err := srv.Accept() + if err != nil { + return + } + + // Read at least one byte of the header + // Otherwise we would have an unsolicited response + _, err = ioutil.ReadAll(io.LimitReader(conn, 1)) + if err != nil { + t.Error(err) + } + + // Respond with incomplete header + _, err = conn.Write([]byte("Http")) + if err != nil { + t.Error(err) + } + + // Forcefully close connection + err = conn.(*net.TCPConn).SetLinger(0) + if err != nil { + t.Error(err) + } + conn.Close() + } + }() + + svrUrl := "http://" + srv.Addr().String() + client := HostClient{Addr: srv.Addr().String()} + + for i := 0; i < 100; i++ { + req := AcquireRequest() + defer ReleaseRequest(req) + resp := AcquireResponse() + defer ReleaseResponse(resp) + + req.Header.SetMethod("POST") + req.SetBodyStream(strings.NewReader(payload), len(payload)) + req.SetRequestURI(svrUrl) + + err = client.Do(req, resp) + + if !isConnectionReset(err) { + t.Fatal("Expected connection reset error") + } + } +} |