From 0e637d901d14e1ca14a5850cf0fc1309a592cd2f Mon Sep 17 00:00:00 2001 From: a very fake floordiv Date: Tue, 16 Jan 2024 12:10:27 +0100 Subject: [PATCH 1/4] minor optimisations. According to benchmarks, practically nothing changed --- internal/initialize/initializers.go | 4 ++-- internal/stash/reader.go | 15 +++++++-------- internal/stash/reader_test.go | 8 ++------ internal/transport/http1/body.go | 8 +++++--- internal/transport/http1/parser.go | 16 ++++++++-------- internal/transport/http1/parser_test.go | 4 ++-- internal/transport/http1/transport.go | 4 ++-- 7 files changed, 28 insertions(+), 31 deletions(-) diff --git a/internal/initialize/initializers.go b/internal/initialize/initializers.go index a9b03c0c..6160ba60 100644 --- a/internal/initialize/initializers.go +++ b/internal/initialize/initializers.go @@ -61,8 +61,8 @@ func NewTransport(s settings.Settings, req *http.Request) transport.Transport { return http1.New( req, - *keyBuff, *valBuff, *startLineBuff, - *objPool, + keyBuff, valBuff, startLineBuff, + objPool, s.Headers, respBuff, s.HTTP.FileBuffSize, diff --git a/internal/stash/reader.go b/internal/stash/reader.go index 4d358ef8..d600559e 100644 --- a/internal/stash/reader.go +++ b/internal/stash/reader.go @@ -1,8 +1,6 @@ package stash -type Retriever interface { - Retrieve() ([]byte, error) -} +type Retriever func() ([]byte, error) // Reader covers Source function in the manner, so it implements the io.Reader type Reader struct { @@ -11,8 +9,10 @@ type Reader struct { error error } -func New() *Reader { - return new(Reader) +func New(source Retriever) *Reader { + return &Reader{ + source: source, + } } func (r *Reader) Read(b []byte) (n int, err error) { @@ -31,11 +31,10 @@ func (r *Reader) Read(b []byte) (n int, err error) { } func (r *Reader) refill() { - r.pending, r.error = r.source.Retrieve() + r.pending, r.error = r.source() } -func (r *Reader) Reset(src Retriever) { - r.source = src +func (r *Reader) Reset() { r.pending = nil r.error = nil } diff --git a/internal/stash/reader_test.go b/internal/stash/reader_test.go index b106161c..918af065 100644 --- a/internal/stash/reader_test.go +++ b/internal/stash/reader_test.go @@ -16,9 +16,7 @@ func (r retriever) Retrieve() ([]byte, error) { func TestReader(t *testing.T) { t.Run("both data and error simultaneously", func(t *testing.T) { - r := New() - r.Reset(retriever{"hello, world"}) - + r := New(retriever{"hello, world"}.Retrieve) buff := make([]byte, 64) n, err := r.Read(buff) require.Equal(t, 12, n) @@ -27,9 +25,7 @@ func TestReader(t *testing.T) { }) t.Run("multiple reads", func(t *testing.T) { - r := New() - r.Reset(retriever{"hello, world"}) - + r := New(retriever{"hello, world"}.Retrieve) buff := make([]byte, 2) data, err := readfull(r, buff) require.NoError(t, err) diff --git a/internal/transport/http1/body.go b/internal/transport/http1/body.go index 1890b072..9c5cb33b 100644 --- a/internal/transport/http1/body.go +++ b/internal/transport/http1/body.go @@ -27,11 +27,13 @@ type Body struct { func NewBody( client tcp.Client, chunkedParser *chunkedbody.Parser, s settings.Body, ) *Body { - return &Body{ - Reader: stash.New(), + body := &Body{ plain: newPlainBodyReader(client, s.MaxSize), chunked: newChunkedBodyReader(client, s.MaxSize, chunkedParser), } + body.Reader = stash.New(body.Retrieve) + + return body } func (b *Body) Init(request *http.Request) { @@ -44,7 +46,7 @@ func (b *Body) Init(request *http.Request) { } b.eof = false - b.Reader.Reset(b) + b.Reader.Reset() } func (b *Body) String() (string, error) { diff --git a/internal/transport/http1/parser.go b/internal/transport/http1/parser.go index dae7b178..4e2c1aab 100644 --- a/internal/transport/http1/parser.go +++ b/internal/transport/http1/parser.go @@ -37,14 +37,14 @@ const ( // the pending data as an extra. Body must be processed separately type Parser struct { request *http.Request - startLineBuff buffer.Buffer + startLineBuff *buffer.Buffer encToksBuff []string contEncToksBuff []string headerKey string - headersValuesPool pool.ObjectPool[[]string] - headerKeyBuff buffer.Buffer - headerValueBuff buffer.Buffer - headersSettings settings.Headers + headersValuesPool *pool.ObjectPool[[]string] + headerKeyBuff *buffer.Buffer + headerValueBuff *buffer.Buffer + headersSettings *settings.Headers headersNumber int contentLength int urlEncodedChar uint8 @@ -52,13 +52,13 @@ type Parser struct { } func NewParser( - request *http.Request, keyBuff, valBuff, startLineBuff buffer.Buffer, - valuesPool pool.ObjectPool[[]string], headersSettings settings.Headers, + request *http.Request, keyBuff, valBuff, startLineBuff *buffer.Buffer, + valuesPool *pool.ObjectPool[[]string], headersSettings settings.Headers, ) *Parser { return &Parser{ state: eMethod, request: request, - headersSettings: headersSettings, + headersSettings: &headersSettings, startLineBuff: startLineBuff, encToksBuff: make([]string, 0, headersSettings.MaxEncodingTokens), contEncToksBuff: make([]string, 0, headersSettings.MaxEncodingTokens), diff --git a/internal/transport/http1/parser_test.go b/internal/transport/http1/parser_test.go index ffb97e89..b0399ea7 100644 --- a/internal/transport/http1/parser_test.go +++ b/internal/transport/http1/parser_test.go @@ -46,8 +46,8 @@ func getParser() (*Parser, *http.Request) { respBuff := make([]byte, 0, s.HTTP.ResponseBuffSize) parser := New( request, - *keyBuff, *valBuff, *startLineBuff, - *objPool, + keyBuff, valBuff, startLineBuff, + objPool, s.Headers, respBuff, s.HTTP.FileBuffSize, diff --git a/internal/transport/http1/transport.go b/internal/transport/http1/transport.go index 5f208e83..78c9d0de 100644 --- a/internal/transport/http1/transport.go +++ b/internal/transport/http1/transport.go @@ -17,8 +17,8 @@ type Transport struct { func New( request *http.Request, - keyBuff, valBuff, startLineBuff buffer.Buffer, - valuesPool pool.ObjectPool[[]string], + keyBuff, valBuff, startLineBuff *buffer.Buffer, + valuesPool *pool.ObjectPool[[]string], headersSettings settings.Headers, respBuff []byte, respFileBuffSize int, From 6322a6b70697ba5d66e9cfe880f9d800a13c5a6c Mon Sep 17 00:00:00 2001 From: fakefloordiv Date: Tue, 16 Jan 2024 16:05:32 +0100 Subject: [PATCH 2/4] removed unused error --- http/status/errors.go | 1 - 1 file changed, 1 deletion(-) diff --git a/http/status/errors.go b/http/status/errors.go index 0dda9b9f..9d2d32f3 100644 --- a/http/status/errors.go +++ b/http/status/errors.go @@ -24,7 +24,6 @@ var ( ErrBadRequest = NewError(BadRequest, "bad request") ErrTooLongRequestLine = NewError(BadRequest, "request line is too long") - ErrTooLongResponseLine = NewError(BadRequest, "response line is too long") ErrURIDecoding = NewError(BadRequest, "invalid URI encoding") ErrBadQuery = NewError(BadRequest, "bad URL query") ErrNotFound = NewError(NotFound, "not found") From 8c1ef85a93d0041e3c8004dffa6a5a60fb91150c Mon Sep 17 00:00:00 2001 From: fakefloordiv Date: Tue, 16 Jan 2024 16:05:53 +0100 Subject: [PATCH 3/4] fixed calling mutators twice on errors --- router/inbuilt/inbuilt.go | 6 +++--- router/inbuilt/inbuilt_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/router/inbuilt/inbuilt.go b/router/inbuilt/inbuilt.go index 7649c17a..20ee2c04 100644 --- a/router/inbuilt/inbuilt.go +++ b/router/inbuilt/inbuilt.go @@ -83,7 +83,7 @@ func (r *Router) onRequest(request *http.Request) *http.Response { if r.isStatic { endpoint, found := r.routesMap[request.Path] if !found { - return r.OnError(request, status.ErrNotFound) + return r.onError(request, status.ErrNotFound) } methodsMap = endpoint.methodsMap @@ -91,7 +91,7 @@ func (r *Router) onRequest(request *http.Request) *http.Response { } else { endpoint := r.tree.Match(request.Path, request.Params) if endpoint == nil { - return r.OnError(request, status.ErrNotFound) + return r.onError(request, status.ErrNotFound) } methodsMap = endpoint.MethodsMap @@ -100,7 +100,7 @@ func (r *Router) onRequest(request *http.Request) *http.Response { handler := getHandler(request.Method, methodsMap) if handler == nil { - return r.OnError(request, status.ErrMethodNotAllowed) + return r.onError(request, status.ErrMethodNotAllowed) } return handler(request) diff --git a/router/inbuilt/inbuilt_test.go b/router/inbuilt/inbuilt_test.go index 46f065ec..f22fdc4a 100644 --- a/router/inbuilt/inbuilt_test.go +++ b/router/inbuilt/inbuilt_test.go @@ -2,6 +2,9 @@ package inbuilt import ( "errors" + "github.com/indigo-web/indigo/internal/initialize" + "github.com/indigo-web/indigo/internal/server/tcp/dummy" + "github.com/indigo-web/indigo/settings" "github.com/stretchr/testify/assert" "testing" @@ -351,3 +354,32 @@ func TestCatchers(t *testing.T) { require.Equal(t, "double magic", string(resp.Reveal().Body)) }) } + +func TestMutators(t *testing.T) { + var timesCalled int + + r := New(). + Get("/", http.Respond). + Mutator(func(request *http.Request) { + timesCalled++ + }) + + require.NoError(t, r.OnStart()) + request := initialize.NewRequest(settings.Default(), dummy.NewNopConn(), nil) + request.Method = method.GET + request.Path = "/" + resp := r.OnRequest(request) + require.Equal(t, status.OK, resp.Reveal().Code) + + request.Method = method.POST + request.Path = "/" + resp = r.OnRequest(request) + require.Equal(t, status.MethodNotAllowed, resp.Reveal().Code) + + request.Method = method.GET + request.Path = "/foo" + resp = r.OnRequest(request) + require.Equal(t, status.NotFound, resp.Reveal().Code) + + require.Equal(t, 3, timesCalled) +} From 24b74a361468a2fb7a1da4147c9d6afb4c578946 Mon Sep 17 00:00:00 2001 From: fakefloordiv Date: Tue, 16 Jan 2024 16:06:13 +0100 Subject: [PATCH 4/4] fixed calling mutators twice --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index aa34a6a6..d36c4986 100644 --- a/version +++ b/version @@ -1 +1 @@ -0.15.5 \ No newline at end of file +0.15.6 \ No newline at end of file