Skip to content

Commit 8f1e394

Browse files
authored
Merge pull request #7 from darkweak/feat/chore/support-relative-paths
feat(chore): Support relative paths
2 parents 1ea1571 + ca40ee6 commit 8f1e394

File tree

9 files changed

+162
-14
lines changed

9 files changed

+162
-14
lines changed

esi/include.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package esi
33
import (
44
"io"
55
"net/http"
6+
"net/url"
67
"regexp"
78
)
89

@@ -36,6 +37,11 @@ func (i *includeTag) loadAttributes(b []byte) error {
3637
return nil
3738
}
3839

40+
func sanitizeURL(u string, reqUrl *url.URL) string {
41+
parsed, _ := url.Parse(u)
42+
return reqUrl.ResolveReference(parsed).String()
43+
}
44+
3945
// Input (e.g. include src="https://domain.com/esi-include" alt="https://domain.com/alt-esi-include" />)
4046
// With or without the alt
4147
// With or without a space separator before the closing
@@ -52,12 +58,12 @@ func (i *includeTag) Process(b []byte, req *http.Request) ([]byte, int) {
5258
return nil, len(b)
5359
}
5460

55-
rq, _ := http.NewRequest(http.MethodGet, i.src, nil)
61+
rq, _ := http.NewRequest(http.MethodGet, sanitizeURL(i.src, req.URL), nil)
5662
client := &http.Client{}
5763
response, err := client.Do(rq)
5864

5965
if err != nil || response.StatusCode >= 400 {
60-
rq, _ = http.NewRequest(http.MethodGet, i.src, nil)
66+
rq, _ = http.NewRequest(http.MethodGet, sanitizeURL(i.alt, req.URL), nil)
6167
response, err = client.Do(rq)
6268

6369
if err != nil || response.StatusCode >= 400 {

fixtures/alt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<esi:include src="http://invalid.do.main" alt=http://domain.com:9080/alt-esi-include/>

fixtures/full.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
<head>
33
<title><esi:vars>Hello from $(HTTP_HOST)</esi:vars></title>
44
<esi:remove>
5-
<esi:include src="http://domain.com/chained-esi-include-1" />
5+
<esi:include src="http://domain.com:9080/chained-esi-include-1" />
66
</esi:remove>
77
</head>
88
<body>
99
<!--esi
1010
<esi:include src="domain.com/not-interpreted"/>
1111
-->
12-
<esi:include src="http://domain.com/chained-esi-include-1" />
13-
<esi:include src="http://domain.com/chained-esi-include-1" />
12+
<esi:include src="/chained-esi-include-1" />
13+
<esi:include src="http://inexistent.abc/something" alt="//domain.com:9080/alt-esi-include" />
1414
</body>
1515
</html>

fixtures/include

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<esi:include src="http://domain.com/chained-esi-include-1" alt=http://domain.com/alt-esi-include/>
1+
<esi:include src="http://domain.com:9080/chained-esi-include-1" alt=http://domain.com:9080/alt-esi-include/>

middleware/caddy/Caddyfile

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
{
22
order esi before basicauth
3-
admin off
4-
debug
3+
http_port 9080
54
esi
65
}
76

8-
localhost:443 {
7+
:9080 {
98
route /chained-esi-include-1 {
109
header Content-Type text/html
11-
respond `<esi:include src="http://domain.com/chained-esi-include-2"/>`
10+
respond `<esi:include src="/chained-esi-include-2"/>`
1211
}
1312

1413
route /chained-esi-include-2 {
@@ -28,8 +27,7 @@ localhost:443 {
2827

2928
route /* {
3029
esi
31-
reverse_proxy 127.0.0.1:81
32-
# root * ../../fixtures
33-
# file_server
30+
root * ../../fixtures
31+
file_server
3432
}
3533
}

middleware/caddy/esi_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package caddy_esi
2+
3+
import (
4+
"net/http"
5+
"os"
6+
"testing"
7+
8+
"github.com/caddyserver/caddy/v2/caddytest"
9+
)
10+
11+
const expectedOutput = `<html>
12+
<head>
13+
<title>Hello from domain.com:9080</title>
14+
15+
</head>
16+
<body>
17+
18+
<esi:include src="domain.com/not-interpreted"/>
19+
20+
<h1>CHAINED 2</h1>
21+
<h1>ALTERNATE ESI INCLUDE</h1>
22+
</body>
23+
</html>
24+
`
25+
26+
func loadCaddyfile() string {
27+
b, _ := os.ReadFile("./Caddyfile")
28+
return string(b)
29+
}
30+
31+
func TestFullHTML(t *testing.T) {
32+
tester := caddytest.NewTester(t)
33+
tester.InitServer(loadCaddyfile(), "caddyfile")
34+
35+
_, _ = tester.AssertGetResponse(`http://domain.com:9080/full.html`, http.StatusOK, expectedOutput)
36+
}
37+
38+
func TestInclude(t *testing.T) {
39+
tester := caddytest.NewTester(t)
40+
tester.InitServer(loadCaddyfile(), "caddyfile")
41+
42+
_, _ = tester.AssertGetResponse(`http://domain.com:9080/include`, http.StatusOK, "<h1>CHAINED 2</h1>")
43+
}
44+
45+
func TestIncludeAlt(t *testing.T) {
46+
tester := caddytest.NewTester(t)
47+
tester.InitServer(loadCaddyfile(), "caddyfile")
48+
49+
_, _ = tester.AssertGetResponse(`http://domain.com:9080/alt`, http.StatusOK, "<h1>ALTERNATE ESI INCLUDE</h1>")
50+
}
51+
52+
func TestEscape(t *testing.T) {
53+
tester := caddytest.NewTester(t)
54+
tester.InitServer(loadCaddyfile(), "caddyfile")
55+
56+
_, _ = tester.AssertGetResponse(`http://domain.com:9080/escape`, http.StatusOK, `
57+
<p><esi:vars>Hello, $(HTTP_COOKIE{name})!</esi:vars></p>
58+
`)
59+
}

middleware/caddy/go.mod

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ require (
1010
require (
1111
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
1212
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
13+
github.com/BurntSushi/toml v1.1.0 // indirect
1314
github.com/Masterminds/goutils v1.1.1 // indirect
1415
github.com/Masterminds/semver/v3 v3.1.1 // indirect
1516
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
17+
github.com/alecthomas/chroma v0.10.0 // indirect
1618
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed // indirect
1719
github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b // indirect
1820
github.com/beorn7/perks v1.0.1 // indirect
1921
github.com/caddyserver/certmagic v0.16.1 // indirect
22+
github.com/cenkalti/backoff/v4 v4.1.2 // indirect
2023
github.com/cespare/xxhash v1.1.0 // indirect
2124
github.com/cespare/xxhash/v2 v2.1.2 // indirect
2225
github.com/cheekybits/genny v1.0.0 // indirect
@@ -26,16 +29,22 @@ require (
2629
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
2730
github.com/dgraph-io/ristretto v0.0.4-0.20200906165740-41ebdbffecfd // indirect
2831
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
32+
github.com/dlclark/regexp2 v1.4.0 // indirect
2933
github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac // indirect
34+
github.com/felixge/httpsnoop v1.0.2 // indirect
3035
github.com/fsnotify/fsnotify v1.5.1 // indirect
36+
github.com/go-chi/chi v4.1.2+incompatible // indirect
3137
github.com/go-kit/kit v0.10.0 // indirect
3238
github.com/go-logfmt/logfmt v0.5.0 // indirect
39+
github.com/go-logr/logr v1.2.2 // indirect
40+
github.com/go-logr/stdr v1.2.2 // indirect
3341
github.com/go-sql-driver/mysql v1.6.0 // indirect
3442
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
3543
github.com/golang/protobuf v1.5.2 // indirect
3644
github.com/golang/snappy v0.0.4 // indirect
3745
github.com/google/cel-go v0.11.4 // indirect
3846
github.com/google/uuid v1.3.0 // indirect
47+
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
3948
github.com/huandu/xstrings v1.3.2 // indirect
4049
github.com/imdario/mergo v0.3.12 // indirect
4150
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
@@ -87,8 +96,20 @@ require (
8796
github.com/stoewer/go-strcase v1.2.0 // indirect
8897
github.com/tailscale/tscert v0.0.0-20220316030059-54bbcb9f74e2 // indirect
8998
github.com/urfave/cli v1.22.5 // indirect
99+
github.com/yuin/goldmark v1.4.12 // indirect
100+
github.com/yuin/goldmark-highlighting v0.0.0-20220208100518-594be1970594 // indirect
90101
go.etcd.io/bbolt v1.3.6 // indirect
91102
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect
103+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.29.0 // indirect
104+
go.opentelemetry.io/otel v1.4.0 // indirect
105+
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.0 // indirect
106+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.0 // indirect
107+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.0 // indirect
108+
go.opentelemetry.io/otel/internal/metric v0.27.0 // indirect
109+
go.opentelemetry.io/otel/metric v0.27.0 // indirect
110+
go.opentelemetry.io/otel/sdk v1.4.0 // indirect
111+
go.opentelemetry.io/otel/trace v1.4.0 // indirect
112+
go.opentelemetry.io/proto/otlp v0.12.0 // indirect
92113
go.step.sm/cli-utils v0.7.0 // indirect
93114
go.step.sm/crypto v0.16.1 // indirect
94115
go.step.sm/linkedca v0.15.0 // indirect
@@ -106,8 +127,10 @@ require (
106127
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect
107128
google.golang.org/grpc v1.46.0 // indirect
108129
google.golang.org/protobuf v1.28.0 // indirect
130+
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
109131
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
110132
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
133+
gopkg.in/yaml.v3 v3.0.1 // indirect
111134
howett.net/plist v1.0.0 // indirect
112135
)
113136

0 commit comments

Comments
 (0)