diff --git a/.github/workflows/middlewares.yml b/.github/workflows/middlewares.yml index edec427..8e32760 100644 --- a/.github/workflows/middlewares.yml +++ b/.github/workflows/middlewares.yml @@ -16,7 +16,7 @@ jobs: name: Install Go uses: actions/setup-go@v3 with: - go-version: 1.19 + go-version: 1.22 - name: Checkout code uses: actions/checkout@v3 diff --git a/.github/workflows/non-regression.yml b/.github/workflows/non-regression.yml index 276a958..3e68573 100644 --- a/.github/workflows/non-regression.yml +++ b/.github/workflows/non-regression.yml @@ -20,10 +20,10 @@ jobs: name: install Go uses: actions/setup-go@v3 with: - go-version: 1.19 + go-version: 1.22 - name: golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v6 - name: install xcaddy run: go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5928221..db42a30 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ jobs: name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.19 + go-version: 1.22 - name: Checkout uses: actions/checkout@v2 diff --git a/.golangci.yml b/.golangci.yml index 88ad0e9..49c56bf 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -7,18 +7,16 @@ linters: disable: - bodyclose - cyclop - - exhaustivestruct + - depguard - exhaustruct - forbidigo - gochecknoglobals - gci - - golint - gomnd - - ifshort - ireturn - nestif - nonamedreturns - - nosnakecase + - mnd - revive - testpackage - stylecheck diff --git a/esi/esi.go b/esi/esi.go index c6ce30e..323cbe1 100644 --- a/esi/esi.go +++ b/esi/esi.go @@ -2,6 +2,8 @@ package esi import ( "net/http" + "slices" + "sync" ) func findTagName(b []byte) Tag { @@ -47,14 +49,6 @@ func HasOpenedTags(b []byte) bool { return esi.FindIndex(b) != nil || escapeRg.FindIndex(b) != nil } -func CanProcess(b []byte) bool { - if tag := findTagName(b); tag != nil { - return tag.HasClose(b) - } - - return false -} - func ReadToTag(next []byte, pointer int) (startTagPosition, esiPointer int, t Tag) { var isEscapeTag bool @@ -83,35 +77,86 @@ func ReadToTag(next []byte, pointer int) (startTagPosition, esiPointer int, t Ta func Parse(b []byte, req *http.Request) []byte { pointer := 0 + includes := make(map[int]Tag) for pointer < len(b) { - var escapeTag bool - next := b[pointer:] tagIdx := esi.FindIndex(next) if escIdx := escapeRg.FindIndex(next); escIdx != nil && (tagIdx == nil || escIdx[0] < tagIdx[0]) { tagIdx = escIdx tagIdx[1] = escIdx[0] - escapeTag = true } if tagIdx == nil { break } - esiPointer := tagIdx[1] - t := findTagName(next[esiPointer:]) + t := findTagName(next[tagIdx[1]:]) + + if t != nil { + includes[pointer+tagIdx[0]] = t + } - if escapeTag { - esiPointer += 7 + switch t.(type) { + case *escapeTag: + pointer += tagIdx[1] + 7 + default: + pointer += tagIdx[1] } + } + + if len(includes) == 0 { + return b + } + + return processEsiTags(b, req, includes) +} + +func processEsiTags(b []byte, req *http.Request, includes map[int]Tag) []byte { + type Response struct { + Start int + End int + Res []byte + Tag Tag + } + + var wg sync.WaitGroup + + responses := make(chan Response, len(includes)) + + for start, t := range includes { + wg.Add(1) + + go func(s int, tag Tag) { + defer wg.Done() + + data, length := tag.Process(b[s:], req) + + responses <- Response{ + Start: s, + End: s + length, + Res: data, + Tag: tag, + } + }(start, t) + } + + wg.Wait() + close(responses) + + // we need to replace from the bottom to top + sorted := make([]Response, 0, len(responses)) + for r := range responses { + sorted = append(sorted, r) + } - res, p := t.Process(next[esiPointer:], req) - esiPointer += p + slices.SortFunc(sorted, func(a, b Response) int { + return b.Start - a.Start + }) - b = append(b[:pointer], append(next[:tagIdx[0]], append(res, next[esiPointer:]...)...)...) - pointer += len(res) + tagIdx[0] + for _, r := range sorted { + b = append(b[:r.Start], append(r.Res, b[r.End:]...)...) } return b diff --git a/esi/esi_test.go b/esi/esi_test.go index 24f3b47..204c24b 100644 --- a/esi/esi_test.go +++ b/esi/esi_test.go @@ -1,9 +1,11 @@ package esi_test import ( + "fmt" "net/http" "net/http/httptest" "os" + "strings" "testing" "github.com/darkweak/go-esi/esi" @@ -62,7 +64,13 @@ var expected = map[string]string{ func verify(t *testing.T, fixture string) { t.Helper() - if result := string(esi.Parse(loadFromFixtures(fixture), getRequest())); result != expected[fixture] { + html := loadFromFixtures(fixture) + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, _ = w.Write([]byte("

CHAINED 2

")) + })) + html = []byte(strings.ReplaceAll(string(html), "http://domain.com:9080", server.URL)) + + if result := string(esi.Parse(html, getRequest())); result != expected[fixture] { t.Errorf("ESI parsing mismatch from `%s` expected\nExpected:\n%+v\nGiven:\n%+v\n", fixture, expected[fixture], result) } } @@ -114,10 +122,17 @@ func Test_Parse_fullMock(t *testing.T) { // Benchmarks. func BenchmarkInclude(b *testing.B) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, _ = w.Write([]byte("

CHAINED 2

")) + })) + for i := 0; i < b.N; i++ { esi.Parse( []byte( - ``, + fmt.Sprintf( + ``, + server.URL, + ), ), httptest.NewRequest(http.MethodGet, "http://domain.com:9080", nil), ) @@ -132,9 +147,13 @@ var remove = ` ` func BenchmarkRemove(b *testing.B) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, _ = w.Write([]byte("

CHAINED 2

")) + })) + for i := 0; i < b.N; i++ { esi.Parse( - []byte(remove), + []byte(strings.ReplaceAll(remove, "domain.com:9080", server.URL)), httptest.NewRequest(http.MethodGet, "http://domain.com:9080", nil), ) } @@ -171,9 +190,13 @@ const full = ` ` func BenchmarkFull(b *testing.B) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, _ = w.Write([]byte("

CHAINED 2

")) + })) + for i := 0; i < b.N; i++ { esi.Parse( - []byte(full), + []byte(strings.ReplaceAll(full, "domain.com:9080", server.URL)), httptest.NewRequest(http.MethodGet, "http://domain.com:9080", nil), ) } diff --git a/esi/include.go b/esi/include.go index 09a34bd..6334644 100644 --- a/esi/include.go +++ b/esi/include.go @@ -12,7 +12,7 @@ import ( const include = "include" var ( - closeInclude = regexp.MustCompile("/>") + closeInclude = regexp.MustCompile(">") srcAttribute = regexp.MustCompile(`src="?(.+?)"?( |/>)`) altAttribute = regexp.MustCompile(`alt="?(.+?)"?( |/>)`) onErrorAttribute = regexp.MustCompile(`onerror="?(.+?)"?( |/>)`) diff --git a/esi/type.go b/esi/type.go index 8388015..fc49c85 100644 --- a/esi/type.go +++ b/esi/type.go @@ -6,9 +6,9 @@ import ( type ( Tag interface { - Process([]byte, *http.Request) ([]byte, int) - HasClose([]byte) bool - GetClosePosition([]byte) int + Process(body []byte, request *http.Request) ([]byte, int) + HasClose(body []byte) bool + GetClosePosition(body []byte) int } baseTag struct { diff --git a/esi/vars.go b/esi/vars.go index 2b5f055..f26a342 100644 --- a/esi/vars.go +++ b/esi/vars.go @@ -76,6 +76,8 @@ type varsTag struct { *baseTag } +const varTagLength = len("") + // Input (e.g. comment text="This is a comment." />). func (c *varsTag) Process(b []byte, req *http.Request) ([]byte, int) { found := closeVars.FindIndex(b) @@ -85,7 +87,7 @@ func (c *varsTag) Process(b []byte, req *http.Request) ([]byte, int) { c.length = found[1] - return interpretedVar.ReplaceAllFunc(b[5:found[0]], func(b []byte) []byte { + return interpretedVar.ReplaceAllFunc(b[varTagLength:found[0]], func(b []byte) []byte { return []byte(parseVariables(b, req)) }), c.length } diff --git a/esi/when.go b/esi/when.go index b4573de..e26968d 100644 --- a/esi/when.go +++ b/esi/when.go @@ -23,6 +23,7 @@ func validateTest(b []byte, req *http.Request) bool { } else if r := comparison.FindSubmatch(b); r != nil { r1 := strings.TrimSpace(parseVariables(r[1], req)) r2 := strings.TrimSpace(parseVariables(r[3], req)) + switch string(r[2]) { case "==": return r1 == r2 diff --git a/go.mod b/go.mod index 1524e8d..c074959 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module github.com/darkweak/go-esi -go 1.19 +go 1.22 diff --git a/middleware/caddy/esi.go b/middleware/caddy/esi.go index c643d8f..94900dd 100644 --- a/middleware/caddy/esi.go +++ b/middleware/caddy/esi.go @@ -12,7 +12,7 @@ import ( "github.com/darkweak/go-esi/writer" ) -var bufPool *sync.Pool = &sync.Pool{ +var bufPool = &sync.Pool{ New: func() any { return &bytes.Buffer{} }, diff --git a/middleware/caddy/go.mod b/middleware/caddy/go.mod index 1e5bd77..895b5fc 100644 --- a/middleware/caddy/go.mod +++ b/middleware/caddy/go.mod @@ -1,6 +1,8 @@ module github.com/darkweak/go-esi/middleware/caddy -go 1.19 +go 1.22 + +toolchain go1.23.1 require ( github.com/caddyserver/caddy/v2 v2.6.4 diff --git a/middleware/caddy/go.sum b/middleware/caddy/go.sum index 6d4c763..cf44802 100644 --- a/middleware/caddy/go.sum +++ b/middleware/caddy/go.sum @@ -2,9 +2,13 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/iam v0.12.0 h1:DRtTY29b75ciH6Ov1PHb4/iat2CLCvrOm40Q0a6DFpE= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= cloud.google.com/go/kms v1.9.0 h1:b0votJQa/9DSsxgHwN33/tTLA7ZHVzfWhDCrfiXijSo= +cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= @@ -27,11 +31,13 @@ github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2B github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink= +github.com/alecthomas/assert/v2 v2.2.1/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs= github.com/alecthomas/chroma/v2 v2.5.0 h1:CQCdj1BiBV17sD4Bd32b/Bzuiq/EqoNTrnIhyQAZ+Rk= github.com/alecthomas/chroma/v2 v2.5.0/go.mod h1:yrkMI9807G1ROx13fhe1v6PN2DDeaR73L3d+1nmYQtw= github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= +github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves= github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= @@ -39,7 +45,9 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5 github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b h1:uUXgbcPDK3KpW29o4iy7GtuappbWT0l5NaMo9H9pJDw= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-sdk-go v1.44.220 h1:yAj99qAt0Htjle9Up3DglgHfOP77lmFPrElA4jKnrBo= +github.com/aws/aws-sdk-go v1.44.220/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= @@ -113,6 +121,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= @@ -146,6 +155,7 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/glog v1.1.1 h1:jxpi2eWoU84wbX9iIEyAeeoac3FLuifZpY9tcNUD9kw= github.com/golang/glog v1.1.1/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= @@ -180,6 +190,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20230309165930-d61513b1440d h1:um9/pc7tKMINFfP1eE7Wv6PRGXlcCSJkVajF7KJw3uQ= github.com/google/pprof v0.0.0-20230309165930-d61513b1440d/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= @@ -188,7 +199,9 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A= +github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.4.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/groob/finalizer v0.0.0-20170707115354-4c2ed49aabda/go.mod h1:MyndkAZd5rUMdNogn35MWXBX1UiBigrU8eTj8DoAC2c= @@ -196,6 +209,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= @@ -258,6 +272,7 @@ github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dv github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= @@ -270,10 +285,12 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -320,6 +337,7 @@ github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk= github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= github.com/onsi/gomega v1.27.3 h1:5VwIwnBY3vbBDOJrNtA4rVdiTZCsq9B5F12pvy1Drmk= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -347,6 +365,7 @@ github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= @@ -410,6 +429,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tailscale/tscert v0.0.0-20230124224810-c6dc1f4049b2 h1:TrgfmCXwtWyFw85UkRGXt9qZRzdzt3nWt2Rerdecn0w= github.com/tailscale/tscert v0.0.0-20230124224810-c6dc1f4049b2/go.mod h1:kNGUQ3VESx3VZwRwA9MSCUegIl6+saPL8Noq82ozCaU= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= @@ -433,6 +453,7 @@ go.mozilla.org/pkcs7 v0.0.0-20210730143726-725912489c62/go.mod h1:SNgMg+EgDFwmvS go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 h1:CCriYyAfq1Br1aIYettdHZTy8mBTIPo7We18TuO/bak= go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.39.0 h1:vFEBG7SieZJzvnRWQ81jxpuEqe6J8Ex+hgc9CqOTzHc= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.39.0/go.mod h1:9rgTcOKdIhDOC0IcAu8a+R+FChqSUBihKpM1lVNi6T0= go.opentelemetry.io/otel v1.4.0/go.mod h1:jeAqMFKy2uLIxCtKxoFj0FAL5zAPKQagc3+GtBWakzk= @@ -531,6 +552,7 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -613,9 +635,11 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.112.0 h1:iDmzvZ4C086R3+en4nSyIf07HlQKMOX1Xx2dmia/+KQ= +google.golang.org/api v0.112.0/go.mod h1:737UfWHNsOq4F3REUTmb+GN9pugkgNLCayLTfoIKpPc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -650,6 +674,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= diff --git a/middleware/roadrunner/go.mod b/middleware/roadrunner/go.mod index eab3f98..3baa5f5 100644 --- a/middleware/roadrunner/go.mod +++ b/middleware/roadrunner/go.mod @@ -1,6 +1,8 @@ module github.com/darkweak/go-esi/middleware/roadrunner -go 1.19 +go 1.22 + +toolchain go1.23.1 require ( github.com/darkweak/go-esi v0.0.6 diff --git a/middleware/server/main.go b/middleware/server/main.go index 7b7b9db..26e30ff 100644 --- a/middleware/server/main.go +++ b/middleware/server/main.go @@ -27,14 +27,21 @@ func main() { w.Header().Set("Content-Type", "text/html") w.WriteHeader(http.StatusOK) _, _ = w.Write(respond[0:97]) + if flusher, ok := w.(http.Flusher); ok { flusher.Flush() } + time.Sleep(time.Second) + _, _ = w.Write(respond[97:194]) + time.Sleep(time.Second) + _, _ = w.Write(respond[194:291]) + time.Sleep(time.Second) + _, _ = w.Write(respond[291:]) }) diff --git a/writer/writer.go b/writer/writer.go index 21acef5..36e1674 100644 --- a/writer/writer.go +++ b/writer/writer.go @@ -77,6 +77,7 @@ func (w *Writer) Write(b []byte) (int, error) { go func(tmpBuf []byte, i int, cw *Writer) { cw.AsyncBuf[i] <- tmpBuf }(buf[position:position+startPos], w.Iteration, w) + w.Iteration++ } @@ -101,8 +102,10 @@ func (w *Writer) Write(b []byte) (int, error) { }(t, buf[position:(position-nextPos)+startPos+closePosition], w, w.Iteration) position += startPos + closePosition - nextPos + w.Iteration++ } + w.buf.Write(buf[position:]) return len(b), nil @@ -110,6 +113,7 @@ func (w *Writer) Write(b []byte) (int, error) { w.AsyncBuf = append(w.AsyncBuf, make(chan []byte)) w.AsyncBuf[w.Iteration] <- buf + w.Iteration++ return len(b), nil