Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(chore): stream response #3

Merged
merged 1 commit into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
.PHONY: lint run-caddy run-roadrunner
.PHONY: lint run-caddy run-server run-traefik

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 caddy binary
run-caddy: ## Build and run caddy binary
cd middleware/caddy && $(MAKE) build && $(MAKE) run

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

run-traefik: ## Run server main.go
cd middleware/traefik && $(MAKE) build && $(MAKE) run
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,18 @@ func functionToParseESITags(b []byte, r *http.Request) []byte {
```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 configure that.
Refer to the [sample Caddyfile](https://github.com/darkweak/go-esi/blob/master/middleware/caddy/Caddyfile) to know how to use that.

### Træfik middleware
```bash
```yaml
# anywhere/traefik.yml
experimental:
plugins:
souin:
moduleName: github.com/darkweak/go-esi
version: v0.0.4
version: v0.0.5
```
```bash
```yaml
# anywhere/dynamic-configuration
http:
routers:
Expand All @@ -74,12 +74,9 @@ http:
middlewares:
esi:
plugin:
esi:
# We don't care about the configuration but we have ot declare that block
# due to shitty træfik empty configuration handle.
disable: false
esi: {}
```
Refer to the [sample Caddyfile](https://github.com/darkweak/go-esi/blob/master/middleware/caddy/Caddyfile) to know how to configure that.
Refer to the [sample traefik file](https://github.com/darkweak/go-esi/blob/master/middleware/traefik/esi-configuration.yml) to know how to use that.

## TODO
- [x] choose tag
Expand Down
13 changes: 12 additions & 1 deletion esi/choose.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type chooseTag struct {
// </esi:otherwise>
// </esi:choose>
// ).
func (c *chooseTag) process(b []byte, req *http.Request) ([]byte, int) {
func (c *chooseTag) Process(b []byte, req *http.Request) ([]byte, int) {
found := closeChoose.FindIndex(b)
if found == nil {
return nil, len(b)
Expand All @@ -56,3 +56,14 @@ func (c *chooseTag) process(b []byte, req *http.Request) ([]byte, int) {

return res, c.length
}

func (*chooseTag) HasClose(b []byte) bool {
return closeChoose.FindIndex(b) != nil
}

func (*chooseTag) GetClosePosition(b []byte) int {
if idx := closeChoose.FindIndex(b); idx != nil {
return idx[1]
}
return 0
}
13 changes: 12 additions & 1 deletion esi/comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,22 @@ type commentTag struct {
}

// Input (e.g. comment text="This is a comment." />).
func (c *commentTag) process(b []byte, req *http.Request) ([]byte, int) {
func (c *commentTag) Process(b []byte, req *http.Request) ([]byte, int) {
found := closeComment.FindIndex(b)
if found == nil {
return nil, len(b)
}

return []byte{}, found[1]
}

func (*commentTag) HasClose(b []byte) bool {
return closeComment.FindIndex(b) != nil
}

func (*commentTag) GetClosePosition(b []byte) int {
if idx := closeComment.FindIndex(b); idx != nil {
return idx[1]
}
return 0
}
13 changes: 12 additions & 1 deletion esi/escape.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type escapeTag struct {
*baseTag
}

func (e *escapeTag) process(b []byte, req *http.Request) ([]byte, int) {
func (e *escapeTag) Process(b []byte, req *http.Request) ([]byte, int) {
closeIdx := closeEscape.FindIndex(b)

if closeIdx == nil {
Expand All @@ -28,3 +28,14 @@ func (e *escapeTag) process(b []byte, req *http.Request) ([]byte, int) {

return b, e.length
}

func (*escapeTag) HasClose(b []byte) bool {
return closeEscape.FindIndex(b) != nil
}

func (*escapeTag) GetClosePosition(b []byte) int {
if idx := closeEscape.FindIndex(b); idx != nil {
return idx[1]
}
return 0
}
41 changes: 39 additions & 2 deletions esi/esi.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"net/http"
)

func findTagName(b []byte) tag {
func findTagName(b []byte) Tag {
name := tagname.FindSubmatch(b)
if name == nil {
return nil
Expand Down Expand Up @@ -43,6 +43,43 @@ func findTagName(b []byte) tag {
return nil
}

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) {
tagIdx := esi.FindIndex(next)
var isEscapeTag bool

if escIdx := escapeRg.FindIndex(next); escIdx != nil && (tagIdx == nil || escIdx[0] < tagIdx[0]) {
tagIdx = escIdx
tagIdx[1] = escIdx[0]
isEscapeTag = true
}

if tagIdx == nil {
return len(next), 0, nil
}

esiPointer = tagIdx[1]
startTagPosition = tagIdx[0]
t = findTagName(next[esiPointer:])

if isEscapeTag {
esiPointer += 7
}

return
}

func Parse(b []byte, req *http.Request) []byte {
pointer := 0

Expand All @@ -69,7 +106,7 @@ func Parse(b []byte, req *http.Request) []byte {
esiPointer += 7
}

res, p := t.process(next[esiPointer:], req)
res, p := t.Process(next[esiPointer:], req)
esiPointer += p

b = append(b[:pointer], append(next[:tagIdx[0]], append(res, next[esiPointer:]...)...)...)
Expand Down
13 changes: 12 additions & 1 deletion esi/include.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (i *includeTag) loadAttributes(b []byte) error {
// With or without the alt
// With or without a space separator before the closing
// With or without the quotes around the src/alt value.
func (i *includeTag) process(b []byte, req *http.Request) ([]byte, int) {
func (i *includeTag) Process(b []byte, req *http.Request) ([]byte, int) {
closeIdx := closeInclude.FindIndex(b)

if closeIdx == nil {
Expand Down Expand Up @@ -71,3 +71,14 @@ func (i *includeTag) process(b []byte, req *http.Request) ([]byte, int) {

return b, i.length
}

func (*includeTag) HasClose(b []byte) bool {
return closeInclude.FindIndex(b) != nil
}

func (*includeTag) GetClosePosition(b []byte) int {
if idx := closeInclude.FindIndex(b); idx != nil {
return idx[1]
}
return 0
}
13 changes: 12 additions & 1 deletion esi/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type removeTag struct {
*baseTag
}

func (r *removeTag) process(b []byte, req *http.Request) ([]byte, int) {
func (r *removeTag) Process(b []byte, req *http.Request) ([]byte, int) {
closeIdx := closeRemove.FindIndex(b)
if closeIdx == nil {
return []byte{}, len(b)
Expand All @@ -23,3 +23,14 @@ func (r *removeTag) process(b []byte, req *http.Request) ([]byte, int) {

return []byte{}, r.length
}

func (*removeTag) HasClose(b []byte) bool {
return closeRemove.FindIndex(b) != nil
}

func (*removeTag) GetClosePosition(b []byte) int {
if idx := closeRemove.FindIndex(b); idx != nil {
return idx[1]
}
return 0
}
8 changes: 5 additions & 3 deletions esi/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import (
)

type (
tag interface {
process([]byte, *http.Request) ([]byte, int)
Tag interface {
Process([]byte, *http.Request) ([]byte, int)
HasClose([]byte) bool
GetClosePosition([]byte) int
}

baseTag struct {
Expand All @@ -18,6 +20,6 @@ func newBaseTag() *baseTag {
return &baseTag{length: 0}
}

func (b *baseTag) process(content []byte, _ *http.Request) ([]byte, int) {
func (b *baseTag) Process(content []byte, _ *http.Request) ([]byte, int) {
return []byte{}, len(content)
}
13 changes: 12 additions & 1 deletion esi/vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ type varsTag struct {
}

// Input (e.g. comment text="This is a comment." />).
func (c *varsTag) process(b []byte, req *http.Request) ([]byte, int) {
func (c *varsTag) Process(b []byte, req *http.Request) ([]byte, int) {
found := closeVars.FindIndex(b)
if found == nil {
return nil, len(b)
Expand All @@ -87,3 +87,14 @@ func (c *varsTag) process(b []byte, req *http.Request) ([]byte, int) {
return []byte(parseVariables(b, req))
}), c.length
}

func (*varsTag) HasClose(b []byte) bool {
return closeVars.FindIndex(b) != nil
}

func (*varsTag) GetClosePosition(b []byte) int {
if idx := closeVars.FindIndex(b); idx != nil {
return idx[1]
}
return 0
}
8 changes: 4 additions & 4 deletions middleware/caddy/Caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
esi
}

:80 {
localhost:443 {
route /chained-esi-include-1 {
header Content-Type text/html
respond `<esi:include src="http://domain.com/chained-esi-include-2"/>`
Expand All @@ -28,8 +28,8 @@

route /* {
esi

root * ../../fixtures
file_server
reverse_proxy 127.0.0.1:81
# root * ../../fixtures
# file_server
}
}
34 changes: 26 additions & 8 deletions middleware/caddy/esi.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ package caddy_esi

import (
"bytes"
"fmt"
"net/http"
"sync"

"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
"github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
"github.com/darkweak/go-esi/esi"
"github.com/darkweak/go-esi/writer"
)

var bufPool *sync.Pool = &sync.Pool{
Expand Down Expand Up @@ -45,14 +44,33 @@ func (e *ESI) ServeHTTP(rw http.ResponseWriter, r *http.Request, next caddyhttp.
buf := bufPool.Get().(*bytes.Buffer)
buf.Reset()
defer bufPool.Put(buf)
cw := newWriter(buf, rw)
cw := writer.NewWriter(buf, rw, r)
go func(w *writer.Writer) {
w.Header().Del("Content-Length")
if w.Rq.ProtoMajor == 1 {
w.Header().Set("Content-Encoding", "chunked")
}
var i = 0
for {
if len(cw.AsyncBuf) <= i {
continue
}
rs := <-cw.AsyncBuf[i]
if rs == nil {
cw.Done <- true
break
}
_, _ = rw.Write(rs)
i++
}
}(cw)
next.ServeHTTP(cw, r)
cw.AsyncBuf = append(cw.AsyncBuf, make(chan []byte))
go func(w *writer.Writer, iteration int) {
w.AsyncBuf[iteration] <- nil
}(cw, cw.Iteration)

b := esi.Parse(cw.buf.Bytes(), r)

rw.Header().Set("Content-Length", fmt.Sprintf("%d", len(b)))
rw.WriteHeader(cw.status)
_, _ = rw.Write(b)
<-cw.Done

return nil
}
Expand Down
4 changes: 2 additions & 2 deletions middleware/caddy/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.18

require (
github.com/caddyserver/caddy/v2 v2.5.2
github.com/darkweak/go-esi v0.0.4
github.com/darkweak/go-esi v0.0.5
)

require (
Expand Down Expand Up @@ -111,4 +111,4 @@ require (
howett.net/plist v1.0.0 // indirect
)

replace github.com/darkweak/go-esi v0.0.4 => ../..
replace github.com/darkweak/go-esi v0.0.5 => ../..
Loading