Skip to content

Commit

Permalink
fix(chore): no more lowercase on varied values (#326)
Browse files Browse the repository at this point in the history
  • Loading branch information
darkweak authored Mar 22, 2023
1 parent 712c26b commit 103602c
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 7 deletions.
14 changes: 12 additions & 2 deletions pkg/middleware/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,16 @@ func isCacheableCode(code int) bool {
return false
}

func canBypassAuthorizationRestriction(headers http.Header, bypassed []string) bool {
for _, header := range bypassed {
if strings.ToLower(header) == "authorization" {
return true
}
}

return strings.Contains(strings.ToLower(headers.Get("Vary")), "authorization")
}

func (s *SouinBaseHandler) Upstream(
customWriter *CustomWriter,
rq *http.Request,
Expand Down Expand Up @@ -164,8 +174,8 @@ func (s *SouinBaseHandler) Upstream(
customWriter.Headers.Set("Cache-Status", fmt.Sprintf("%s; fwd=uri-miss; key=%s; detail=INVALID-RESPONSE-CACHE-CONTROL", rq.Context().Value(context.CacheName), rfc.GetCacheKeyFromCtx(rq.Context())))
return nil
}
if responseCc.PrivatePresent {
customWriter.Headers.Set("Cache-Status", fmt.Sprintf("%s; fwd=uri-miss; key=%s; detail=PRIVATE-RESPONSE", rq.Context().Value(context.CacheName), rfc.GetCacheKeyFromCtx(rq.Context())))
if (responseCc.PrivatePresent || rq.Header.Get("Authorization") != "") && !canBypassAuthorizationRestriction(customWriter.Header(), rq.Context().Value(context.IgnoredHeaders).([]string)) {
customWriter.Headers.Set("Cache-Status", fmt.Sprintf("%s; fwd=uri-miss; key=%s; detail=PRIVATE-OR-AUTHENTICATED-RESPONSE", rq.Context().Value(context.CacheName), rfc.GetCacheKeyFromCtx(rq.Context())))
return nil
}

Expand Down
8 changes: 7 additions & 1 deletion pkg/rfc/age.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ func validateMaxAgeCachedResponse(res *http.Response, maxAge int, addTime int) *
}

func ValidateMaxAgeCachedResponse(co *cacheobject.RequestCacheDirectives, res *http.Response) *http.Response {
return validateMaxAgeCachedResponse(res, int(co.MaxAge), 0)
responseCc, _ := cacheobject.ParseResponseCacheControl(res.Header.Get("Cache-Control"))
ma := co.MaxAge
if responseCc.SMaxAge > -1 {
ma = responseCc.SMaxAge
}

return validateMaxAgeCachedResponse(res, int(ma), 0)
}

func ValidateMaxAgeCachedStaleResponse(co *cacheobject.RequestCacheDirectives, res *http.Response, addTime int) *http.Response {
Expand Down
2 changes: 1 addition & 1 deletion pkg/rfc/vary.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func GetVariedCacheKey(rq *http.Request, headers []string) string {
return ""
}
for i, v := range headers {
h := strings.ToLower(strings.TrimSpace(rq.Header.Get(v)))
h := strings.TrimSpace(rq.Header.Get(v))
if strings.Contains(h, ";") || strings.Contains(h, ":") {
h = url.QueryEscape(h)
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/caddy/httpcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ func (s *SouinCaddyMiddleware) FromApp(app *SouinApp) error {
if dc.Timeout.Cache.Duration == 0 {
s.Configuration.DefaultCache.Timeout.Cache = appDc.Timeout.Cache
}
if !dc.Key.DisableBody && !dc.Key.DisableHost && !dc.Key.DisableMethod && !dc.Key.DisableQuery && !dc.Key.Hide {
if !dc.Key.DisableBody && !dc.Key.DisableHost && !dc.Key.DisableMethod && !dc.Key.DisableQuery && !dc.Key.Hide && len(dc.Key.Headers) == 0 {
s.Configuration.DefaultCache.Key = appDc.Key
}
if dc.DefaultCacheControl == "" {
Expand Down
78 changes: 77 additions & 1 deletion plugins/caddy/httpcache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ func TestQueryString(t *testing.T) {
if resp1.Header.Get("Cache-Status") != "Souin; fwd=uri-miss; stored; key=GET-http-localhost:9080-/query-string" {
t.Errorf("unexpected Cache-Status header %v", resp1.Header)
}

}

func TestMaxAge(t *testing.T) {
Expand Down Expand Up @@ -253,3 +252,80 @@ func TestNotHandledRoute(t *testing.T) {
t.Errorf("unexpected Cache-Status header value %v", resp1.Header.Get("Cache-Status"))
}
}

func TestAuthenticatedRoute(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
{
admin localhost:2999
http_port 9080
https_port 9443
cache {
ttl 1000s
}
}
localhost:9080 {
route /no-auth-bypass {
cache
respond "Hello, auth {http.request.header.Authorization}!"
}
route /auth-bypass {
cache {
key {
headers Authorization Content-Type
}
}
header Cache-Control "private, s-maxage=5"
respond "Hello, auth bypass {http.request.header.Authorization}!"
}
route /auth-bypass-vary {
cache {
key {
headers Authorization Content-Type
}
}
header Cache-Control "private, s-maxage=5"
header Vary "Content-Type, Authorization"
respond "Hello, auth vary bypass {http.request.header.Authorization}!"
}
}`, "caddyfile")

getRequestFor := func(endpoint, user string) *http.Request {
rq, _ := http.NewRequest(http.MethodGet, "http://localhost:9080"+endpoint, nil)
rq.Header = http.Header{"Authorization": []string{"Bearer " + user}, "Content-Type": []string{"text/plain"}}

return rq
}

respNoAuthBypass, _ := tester.AssertResponse(getRequestFor("/no-auth-bypass", "Alice"), 200, "Hello, auth Bearer Alice!")
if respNoAuthBypass.Header.Get("Cache-Status") != "Souin; fwd=uri-miss; key=GET-http-localhost:9080-/no-auth-bypass; detail=PRIVATE-OR-AUTHENTICATED-RESPONSE" {
t.Errorf("unexpected Cache-Status header %v", respNoAuthBypass.Header.Get("Cache-Status"))
}

respAuthBypassAlice1, _ := tester.AssertResponse(getRequestFor("/auth-bypass", "Alice"), 200, "Hello, auth bypass Bearer Alice!")
if respAuthBypassAlice1.Header.Get("Cache-Status") != "Souin; fwd=uri-miss; stored; key=GET-http-localhost:9080-/auth-bypass-Bearer Alice-text/plain" {
t.Errorf("unexpected Cache-Status header %v", respAuthBypassAlice1.Header.Get("Cache-Status"))
}
respAuthBypassAlice2, _ := tester.AssertResponse(getRequestFor("/auth-bypass", "Alice"), 200, "Hello, auth bypass Bearer Alice!")
if respAuthBypassAlice2.Header.Get("Cache-Status") != "Souin; hit; ttl=4; key=GET-http-localhost:9080-/auth-bypass-Bearer Alice-text/plain" {
t.Errorf("unexpected Cache-Status header %v", respAuthBypassAlice2.Header.Get("Cache-Status"))
}

respAuthBypassBob1, _ := tester.AssertResponse(getRequestFor("/auth-bypass", "Bob"), 200, "Hello, auth bypass Bearer Bob!")
if respAuthBypassBob1.Header.Get("Cache-Status") != "Souin; fwd=uri-miss; stored; key=GET-http-localhost:9080-/auth-bypass-Bearer Bob-text/plain" {
t.Errorf("unexpected Cache-Status header %v", respAuthBypassBob1.Header.Get("Cache-Status"))
}
respAuthBypassBob2, _ := tester.AssertResponse(getRequestFor("/auth-bypass", "Bob"), 200, "Hello, auth bypass Bearer Bob!")
if respAuthBypassBob2.Header.Get("Cache-Status") != "Souin; hit; ttl=4; key=GET-http-localhost:9080-/auth-bypass-Bearer Bob-text/plain" {
t.Errorf("unexpected Cache-Status header %v", respAuthBypassBob2.Header.Get("Cache-Status"))
}

respAuthVaryBypassAlice1, _ := tester.AssertResponse(getRequestFor("/auth-bypass-vary", "Alice"), 200, "Hello, auth vary bypass Bearer Alice!")
if respAuthVaryBypassAlice1.Header.Get("Cache-Status") != "Souin; fwd=uri-miss; stored; key=GET-http-localhost:9080-/auth-bypass-vary-Bearer Alice-text/plain" {
t.Errorf("unexpected Cache-Status header %v", respAuthVaryBypassAlice1.Header.Get("Cache-Status"))
}
respAuthVaryBypassAlice2, _ := tester.AssertResponse(getRequestFor("/auth-bypass-vary", "Alice"), 200, "Hello, auth vary bypass Bearer Alice!")
if respAuthVaryBypassAlice2.Header.Get("Cache-Status") != "Souin; hit; ttl=4; key=GET-http-localhost:9080-/auth-bypass-vary-Bearer Alice-text/plain" {
t.Errorf("unexpected Cache-Status header %v", respAuthVaryBypassAlice2.Header.Get("Cache-Status"))
}
}
1 change: 0 additions & 1 deletion plugins/souin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ func main() {
return &errors.CanceledRequestContextError{}
default:
res, err := proxy.Transport.RoundTrip(req)
fmt.Printf("%+v\n%+v\n%+v\n\n", res, err, req)
if err != nil {
return err
}
Expand Down

0 comments on commit 103602c

Please sign in to comment.