Skip to content

Commit

Permalink
feat(middleware): roadrunner support & performance update (#11)
Browse files Browse the repository at this point in the history
* feat(middlewares): implement roadrunner

* update golangci-lint

* update tests

* feat: improve performances and refacto with rr support

* feat: finish roadrunner

* fix: github actions tests setup

* fix: run detached caddy on the 8080 HTTP port

* fix: middleware caddy unit tests

* feat: documentation update to include roadrunner

* temporary downgrade to be able to build

* feat: bump version
  • Loading branch information
darkweak authored Mar 23, 2023
1 parent 9298fae commit dfdfaa8
Show file tree
Hide file tree
Showing 45 changed files with 2,890 additions and 1,678 deletions.
22 changes: 19 additions & 3 deletions .github/workflows/middlewares.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ jobs:
sudo echo "127.0.0.1 domain.com" | sudo tee -a /etc/hosts
-
name: Install Go
uses: actions/setup-go@v2
uses: actions/setup-go@v3
with:
go-version: 1.18
go-version: 1.19
-
name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
-
name: Install xcaddy
run: go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
Expand All @@ -32,3 +32,19 @@ jobs:
-
name: Run detached caddy
run: cd middleware/caddy && ./caddy run &

build-roadrunner-validator:
name: Check that go-esi build as roadrunner middleware
runs-on: ubuntu-latest
steps:
-
name: Install Go
uses: actions/setup-go@v3
with:
go-version: 1.19
-
name: Checkout code
uses: actions/checkout@v3
-
name: Run Roadrunner tests
run: cd middleware/roadrunner && go test -v ./...
35 changes: 26 additions & 9 deletions .github/workflows/non-regression.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,33 @@ on:

jobs:
lint-and-tests:
name: Validate Go code linting
name: lint and static tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Install Go
uses: actions/setup-go@v2
-
name: Add domain.com host to /etc/hosts
run: |
sudo echo "127.0.0.1 domain.com" | sudo tee -a /etc/hosts
-
name: checkout code
uses: actions/checkout@v3
-
name: install Go
uses: actions/setup-go@v3
with:
go-version: 1.18
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
- name: tests
go-version: 1.19
-
name: golangci-lint
uses: golangci/golangci-lint-action@v3
-
name: install xcaddy
run: go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
-
name: build caddy binary
run: cd middleware/caddy && make build && cd -
-
name: run caddy binary as detached mode
run: cd middleware/caddy && make run &
-
name: tests
run: go test -v -race ./...
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.18
go-version: 1.19
-
name: Checkout
uses: actions/checkout@v2
Expand Down
22 changes: 22 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
run:
timeout: 30s
issues-exit-code: 1

linters:
enable-all: true
disable:
- bodyclose
- cyclop
- exhaustivestruct
- exhaustruct
- forbidigo
- gochecknoglobals
- gci
- golint
- gomnd
- ifshort
- ireturn
- nestif
- nonamedreturns
- nosnakecase
- revive
- testpackage
- stylecheck
- varnamelen
21 changes: 19 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
.PHONY: lint run-caddy run-server run-traefik
.PHONY: bump-version lint run-caddy run-roadrunner run-server run-traefik vendor
MIDDLEWARES_LIST=caddy roadrunner server traefik

bump-version:
test $(from)
test $(to)
sed -i '' 's/version: $(from)/version: $(to)/' README.md
for middleware in $(MIDDLEWARES_LIST) ; do \
sed -i '' 's/github.com\/darkweak\/go-esi $(from)/github.com\/darkweak\/go-esi $(to)/' middleware/$$middleware/go.mod ; \
done

lint: ## Run golangci-lint to ensure the code quality
docker run --rm -v $(PWD):/app -w /app golangci/golangci-lint golangci-lint run

run-caddy: ## Build and run caddy binary
cd middleware/caddy && $(MAKE) build && $(MAKE) run

run-roadrunner: ## Build and run roadrunner
cd middleware/roadrunner && $(MAKE) build && $(MAKE) run

run-server: ## Run server main.go
go run middleware/server/main.go

run-traefik: ## Run server main.go
run-traefik: ## Build and run træfik
cd middleware/traefik && $(MAKE) build && $(MAKE) run

vendor: ## Generate and prepare vendors for each plugin
go mod tidy && go mod download
for middleware in $(MIDDLEWARES_LIST) ; do \
cd middleware/$$middleware && ($(MAKE) build || true) && cd -; done
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,60 @@ func functionToParseESITags(b []byte, r *http.Request) []byte {
## Available as middleware
- [x] Caddy
- [x] Træfik
- [x] Roadrunner

### Caddy middleware
```bash
xcaddy build --with github.com/darkweak/go-esi/middleware/caddy
```
Refer to the [sample Caddyfile](https://github.com/darkweak/go-esi/blob/master/middleware/caddy/Caddyfile) to know how to use that.

### Roadrunner middleware
To use the `go-esi` processor as Roadrunner middleware, you just have to follow the steps below.
You have to build your `rr` binary with the `go-esi` dependency.
```toml
[velox]
build_args = ['-trimpath', '-ldflags', '-s -X github.com/roadrunner-server/roadrunner/v2/internal/meta.version=v2.12.0 -X github.com/roadrunner-server/roadrunner/v2/internal/meta.buildTime=10:00:00']

[roadrunner]
ref = "v2.12.3"

[github]
[github.token]
token = "GH_TOKEN"

[github.plugins]
logger = { ref = "v3.2.0", owner = "roadrunner-server", repository = "logger" }
esi = { ref = "master", owner = "darkweak", repository = "go-esi", folder = "middleware/roadrunner", replace = "/opt/middleware/roadrunner" }
server = { ref = "v3.2.0", owner = "roadrunner-server", repository = "server" }
gzip = { ref = "v3.2.0", owner = "roadrunner-server", repository = "gzip" }
http = { ref = "v3.2.0", owner = "roadrunner-server", repository = "http" }

[log]
level = "debug"
mode = "development"
```

After that, you'll be able to set enable and add the esi processor to the middleware chain.
```yaml
# .rr.yaml
http:
# Other http sub keys
esi: {}
middleware:
- headers
- gzip
- esi
```
### Træfik middleware
```yaml
# anywhere/traefik.yml
experimental:
plugins:
souin:
moduleName: github.com/darkweak/go-esi
version: v0.0.5
version: v0.0.6
```
```yaml
# anywhere/dynamic-configuration
Expand Down
22 changes: 13 additions & 9 deletions esi/choose.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@ type chooseTag struct {

// Input (e.g.
// <esi:choose>
// <esi:when test="$(HTTP_COOKIE{group})=='Advanced'">
// <esi:include src="http://www.example.com/advanced.html"/>
// </esi:when>
// <esi:when test="$(HTTP_COOKIE{group})=='Basic User'">
// <esi:include src="http://www.example.com/basic.html"/>
// </esi:when>
// <esi:otherwise>
// <esi:include src="http://www.example.com/new_user.html"/>
// </esi:otherwise>
//
// <esi:when test="$(HTTP_COOKIE{group})=='Advanced'">
// <esi:include src="http://www.example.com/advanced.html"/>
// </esi:when>
// <esi:when test="$(HTTP_COOKIE{group})=='Basic User'">
// <esi:include src="http://www.example.com/basic.html"/>
// </esi:when>
// <esi:otherwise>
// <esi:include src="http://www.example.com/new_user.html"/>
// </esi:otherwise>
//
// </esi:choose>
// ).
func (c *chooseTag) Process(b []byte, req *http.Request) ([]byte, int) {
Expand All @@ -44,6 +46,7 @@ func (c *chooseTag) Process(b []byte, req *http.Request) ([]byte, int) {
for _, v := range tagIdxs {
if validateTest(v[1], req) {
res = Parse(v[2], req)

return res, c.length
}
}
Expand All @@ -64,5 +67,6 @@ func (*chooseTag) GetClosePosition(b []byte) int {
if idx := closeChoose.FindIndex(b); idx != nil {
return idx[1]
}

return 0
}
3 changes: 2 additions & 1 deletion esi/comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

const comment = "comment"

var closeComment = regexp.MustCompile("/>")
var closeComment = regexp.MustCompile("/>((\n| +)+)?")

type commentTag struct {
*baseTag
Expand All @@ -31,5 +31,6 @@ func (*commentTag) GetClosePosition(b []byte) int {
if idx := closeComment.FindIndex(b); idx != nil {
return idx[1]
}

return 0
}
11 changes: 9 additions & 2 deletions esi/escape.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ const escape = "<!--esi"

var (
escapeRg = regexp.MustCompile("<!--esi")
closeEscape = regexp.MustCompile("-->")
closeEscape = regexp.MustCompile("((\n| +)+)?-->")
startEscape = regexp.MustCompile("((\n| +)+)?")
)

type escapeTag struct {
Expand All @@ -23,8 +24,13 @@ func (e *escapeTag) Process(b []byte, req *http.Request) ([]byte, int) {
return nil, len(b)
}

startPosition := 0
if startIdx := startEscape.FindIndex(b); startIdx != nil {
startPosition = startIdx[1]
}

e.length = closeIdx[1]
b = b[:closeIdx[0]]
b = b[startPosition:closeIdx[0]]

return b, e.length
}
Expand All @@ -37,5 +43,6 @@ func (*escapeTag) GetClosePosition(b []byte) int {
if idx := closeEscape.FindIndex(b); idx != nil {
return idx[1]
}

return 0
}
3 changes: 2 additions & 1 deletion esi/esi.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ func CanProcess(b []byte) bool {
}

func ReadToTag(next []byte, pointer int) (startTagPosition, esiPointer int, t Tag) {
tagIdx := esi.FindIndex(next)
var isEscapeTag bool

tagIdx := esi.FindIndex(next)

if escIdx := escapeRg.FindIndex(next); escIdx != nil && (tagIdx == nil || escIdx[0] < tagIdx[0]) {
tagIdx = escIdx
tagIdx[1] = escIdx[0]
Expand Down
Loading

0 comments on commit dfdfaa8

Please sign in to comment.