Skip to content

Commit 9298fae

Browse files
darkweakdkarlovi
andauthored
fix(chore): include and choose tags (#10)
* feat: pass some headers to child requests * fix(chore): include and choose tags Co-authored-by: Dalibor Karlović <[email protected]>
1 parent 8f1e394 commit 9298fae

File tree

5 files changed

+61
-10
lines changed

5 files changed

+61
-10
lines changed

esi/choose.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ func (c *chooseTag) Process(b []byte, req *http.Request) ([]byte, int) {
4444
for _, v := range tagIdxs {
4545
if validateTest(v[1], req) {
4646
res = Parse(v[2], req)
47-
48-
break
47+
return res, c.length
4948
}
5049
}
5150

esi/include.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@ var (
1515
altAttribute = regexp.MustCompile(`alt="?(.+?)"?( |/>)`)
1616
)
1717

18+
// safe to pass to any origin
19+
var headersSafe = []string{
20+
"Accept",
21+
"Accept-Language",
22+
}
23+
24+
// safe to pass only to same-origin (same scheme, same host, same port)
25+
var headersUnsafe = []string{
26+
"Cookie",
27+
"Authorization",
28+
}
29+
1830
type includeTag struct {
1931
*baseTag
2032
src string
@@ -42,6 +54,15 @@ func sanitizeURL(u string, reqUrl *url.URL) string {
4254
return reqUrl.ResolveReference(parsed).String()
4355
}
4456

57+
func addHeaders(headers []string, req *http.Request, rq *http.Request) {
58+
for _, h := range headers {
59+
v := req.Header.Get(h)
60+
if v != "" {
61+
rq.Header.Add(h, v)
62+
}
63+
}
64+
}
65+
4566
// Input (e.g. include src="https://domain.com/esi-include" alt="https://domain.com/alt-esi-include" />)
4667
// With or without the alt
4768
// With or without a space separator before the closing
@@ -59,18 +80,31 @@ func (i *includeTag) Process(b []byte, req *http.Request) ([]byte, int) {
5980
}
6081

6182
rq, _ := http.NewRequest(http.MethodGet, sanitizeURL(i.src, req.URL), nil)
83+
addHeaders(headersSafe, req, rq)
84+
if rq.URL.Scheme == req.URL.Scheme && rq.URL.Host == req.URL.Host {
85+
addHeaders(headersUnsafe, req, rq)
86+
}
87+
6288
client := &http.Client{}
6389
response, err := client.Do(rq)
6490

65-
if err != nil || response.StatusCode >= 400 {
91+
if (err != nil || response.StatusCode >= 400) && i.alt != "" {
6692
rq, _ = http.NewRequest(http.MethodGet, sanitizeURL(i.alt, req.URL), nil)
93+
addHeaders(headersSafe, req, rq)
94+
if rq.URL.Scheme == req.URL.Scheme && rq.URL.Host == req.URL.Host {
95+
addHeaders(headersUnsafe, req, rq)
96+
}
6797
response, err = client.Do(rq)
6898

6999
if err != nil || response.StatusCode >= 400 {
70100
return nil, len(b)
71101
}
72102
}
73103

104+
if response == nil {
105+
return nil, i.length
106+
}
107+
74108
defer response.Body.Close()
75109
x, _ := io.ReadAll(response.Body)
76110
b = Parse(x, req)

fixtures/full.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,18 @@
1111
-->
1212
<esi:include src="/chained-esi-include-1" />
1313
<esi:include src="http://inexistent.abc/something" alt="//domain.com:9080/alt-esi-include" />
14+
<esi:choose>
15+
<esi:when test="$(HTTP_COOKIE{group})=='Advanced'">
16+
<span><esi:include src="http://domain.com:9080/chained-esi-include-1"/></span>
17+
</esi:when>
18+
<esi:when test="$(HTTP_COOKIE{group})=='Basic User'">
19+
<esi:include src="https://google.com"/>
20+
</esi:when>
21+
<esi:otherwise>
22+
<div>
23+
<esi:include src="http://domain.com/esi-include"/>
24+
</div>
25+
</esi:otherwise>
26+
</esi:choose>
1427
</body>
1528
</html>

middleware/caddy/esi.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,25 @@ func (e *ESI) ServeHTTP(rw http.ResponseWriter, r *http.Request, next caddyhttp.
4646
defer bufPool.Put(buf)
4747
cw := writer.NewWriter(buf, rw, r)
4848
go func(w *writer.Writer) {
49-
w.Header().Del("Content-Length")
50-
if w.Rq.ProtoMajor == 1 {
51-
w.Header().Set("Content-Encoding", "chunked")
52-
}
5349
var i = 0
5450
for {
55-
if len(cw.AsyncBuf) <= i {
51+
if len(w.AsyncBuf) <= i {
5652
continue
5753
}
58-
rs := <-cw.AsyncBuf[i]
54+
rs := <-w.AsyncBuf[i]
5955
if rs == nil {
60-
cw.Done <- true
56+
w.Done <- true
6157
break
6258
}
6359
_, _ = rw.Write(rs)
6460
i++
6561
}
6662
}(cw)
6763
next.ServeHTTP(cw, r)
64+
cw.Header().Del("Content-Length")
65+
if cw.Rq.ProtoMajor == 1 {
66+
cw.Header().Set("Content-Encoding", "chunked")
67+
}
6868
cw.AsyncBuf = append(cw.AsyncBuf, make(chan []byte))
6969
go func(w *writer.Writer, iteration int) {
7070
w.AsyncBuf[iteration] <- nil

middleware/caddy/esi_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ const expectedOutput = `<html>
1919
2020
<h1>CHAINED 2</h1>
2121
<h1>ALTERNATE ESI INCLUDE</h1>
22+
23+
<div>
24+
25+
</div>
26+
2227
</body>
2328
</html>
2429
`

0 commit comments

Comments
 (0)