Skip to content

Commit

Permalink
Merge pull request #127 from fakefloordiv/master
Browse files Browse the repository at this point in the history
Optimized HTTP parser by approx. 0.5gb/s
  • Loading branch information
flrdv authored Jan 16, 2024
2 parents 0fa40ca + 067c718 commit ca6cf36
Show file tree
Hide file tree
Showing 14 changed files with 192 additions and 146 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ import (
)

func HelloWorld(request *http.Request) *http.Response {
return request.Respond().String("Hello, world!")
return http.String(request, "Hello, world!")
}

func Log(request *http.Request) *http.Response {
text, err := request.Body.String()
if err != nil {
return request.Respond().Error(err)
return http.Error(request, err)
}

log.Printf("%s says: %s", request.Remote, text)
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ github.com/indigo-web/chunkedbody v0.1.0 h1:fZerB4rS9aufemrNTPPKOMSWsgnImfuW4g1l
github.com/indigo-web/chunkedbody v0.1.0/go.mod h1:E3IVH0uH1ePqQO4n76M2EVPplGyqZTP88MpR3kRj/mE=
github.com/indigo-web/iter v0.1.0 h1:3LJG319EytEULerDX6meT4xW/lqncIqTnZewsMtiPT4=
github.com/indigo-web/iter v0.1.0/go.mod h1:hftmhzfi4hpWc715PmXsfMjE1K0FLwznr+iyLxM7wyQ=
github.com/indigo-web/utils v0.6.0 h1:rmVWFkCLMiw9sCBAvBdxTHtPCm54tOsCf+hmvuY9zxQ=
github.com/indigo-web/utils v0.6.0/go.mod h1:Q+voOJjIRN7DV+ifWozy6RY6cDF10Ev0NPDjsuOAXfQ=
github.com/indigo-web/utils v0.6.1 h1:WWvqTchkwQU/RdOyEeSuEf6Cy/XMItllftbnCQM1Z/g=
github.com/indigo-web/utils v0.6.1/go.mod h1:Q+voOJjIRN7DV+ifWozy6RY6cDF10Ev0NPDjsuOAXfQ=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
Expand Down
66 changes: 66 additions & 0 deletions http/method/method.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package method

//go:generate stringer -type=Method
type Method uint8

const (
Unknown Method = iota
GET
HEAD
POST
PUT
DELETE
CONNECT
OPTIONS
TRACE
PATCH

// Count is the last one enum, so contains the greatest integer value of all the
// methods. So real number of methods is lower by 1
Count = iota - 1
)

func Parse(str string) Method {
switch len(str) {
case 3:
if str == "GET" {
return GET
} else if str == "PUT" {
return PUT
}

return Unknown
case 4:
if str == "POST" {
return POST
} else if str == "HEAD" {
return HEAD
}

return Unknown
case 5:
if str == "PATCH" {
return PATCH
} else if str == "TRACE" {
return TRACE
}

return Unknown
case 6:
if str == "DELETE" {
return DELETE
}

return Unknown
case 7:
if str == "CONNECT" {
return CONNECT
} else if str == "OPTIONS" {
return OPTIONS
}

return Unknown
}

return Unknown
}
23 changes: 23 additions & 0 deletions http/method/method_bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package method

import "testing"

func BenchmarkMethod(b *testing.B) {
var parsed Method

for i := Unknown; i <= Count; i++ {
b.Run(i.String(), func(b *testing.B) {
m := i.String()
b.SetBytes(int64(len(m)))
b.ResetTimer()

for j := 0; j < b.N; j++ {
parsed = Parse(m)
}
})
}

keepalive(parsed)
}

func keepalive(Method) {}
5 changes: 2 additions & 3 deletions http/method/method_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 0 additions & 49 deletions http/method/methods.go

This file was deleted.

32 changes: 13 additions & 19 deletions http/proto/proto.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
package proto

import (
"github.com/indigo-web/utils/strcomp"
"github.com/indigo-web/utils/uf"
)

//go:generate stringer -type=Proto
type Proto uint8

Expand All @@ -27,32 +22,31 @@ var (
)

const (
minimalProtoStringVersion = len("HTTP/x.x")
httpProtoPrefix = "HTTP/"
majorVersionOffset = len("HTTP/x") - 1
minorVersionOffset = len("HTTP/x.x") - 1
protoTokenLength = len("HTTP/x.x")
majorVersionOffset = len("HTTP/x") - 1
minorVersionOffset = len("HTTP/x.x") - 1
)

var majorMinorVersionLUT = [10][10]Proto{
0: {9: HTTP09},
1: {0: HTTP10, 1: HTTP11},
}

func FromBytes(raw []byte) Proto {
if len(raw) != minimalProtoStringVersion ||
!strcomp.EqualFold(uf.B2S(raw[:len(httpProtoPrefix)]), httpProtoPrefix) {
if len(raw) != protoTokenLength ||
!(raw[0]|0x20 == 'h' && raw[1]|0x20 == 't' && raw[2]|0x20 == 't' && raw[3]|0x20 == 'p' && raw[4] == '/') {
return Unknown
}

return Parse(raw[majorVersionOffset]-'0', raw[minorVersionOffset]-'0')
}

func Parse(major, minor uint8) Proto {
switch {
case major == 1 && minor == 1:
return HTTP11
case major == 1 && minor == 0:
return HTTP10
case major == 0 && minor == 9:
return HTTP09
if major > 9 || minor > 9 {
return Unknown
}

return Unknown
return majorMinorVersionLUT[major][minor]
}

func ToBytes(proto Proto) []byte {
Expand Down
3 changes: 0 additions & 3 deletions internal/initialize/initializers.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/indigo-web/indigo/internal/transport/http1"
"github.com/indigo-web/indigo/settings"
"github.com/indigo-web/utils/buffer"
"github.com/indigo-web/utils/pool"
"net"
)

Expand Down Expand Up @@ -52,7 +51,6 @@ func NewRequest(s settings.Settings, conn net.Conn, body http.Body) *http.Reques

func NewTransport(s settings.Settings, req *http.Request) transport.Transport {
keyBuff, valBuff := NewKeyValueBuffs(s.Headers)
objPool := pool.NewObjectPool[[]string](s.Headers.MaxValuesObjectPoolSize)
startLineBuff := buffer.New(
s.URL.BufferSize.Default,
s.URL.BufferSize.Maximal,
Expand All @@ -62,7 +60,6 @@ func NewTransport(s settings.Settings, req *http.Request) transport.Transport {
return http1.New(
req,
keyBuff, valBuff, startLineBuff,
objPool,
s.Headers,
respBuff,
s.HTTP.FileBuffSize,
Expand Down
Loading

0 comments on commit ca6cf36

Please sign in to comment.