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