mirror of
https://github.com/kataras/iris.git
synced 2025-12-17 18:07:01 +00:00
(#1554) Add support for all common compressions (write and read)
- Remove the context.Context interface and export the *context, the iris.Context now points to the pointer\nSupport compression and rate limiting in the FileServer\nBit of code organisation Former-commit-id: ad1c61bf968059510c6be9e7f2cceec7da70ba17
This commit is contained in:
8
cache/browser.go
vendored
8
cache/browser.go
vendored
@@ -31,7 +31,7 @@ const (
|
||||
// A good use of this middleware is on HTML routes; to refresh the page even on "back" and "forward" browser's arrow buttons.
|
||||
//
|
||||
// See `cache#StaticCache` for the opposite behavior.
|
||||
var NoCache = func(ctx context.Context) {
|
||||
var NoCache = func(ctx *context.Context) {
|
||||
ctx.Header(context.CacheControlHeaderKey, CacheControlHeaderValue)
|
||||
ctx.Header(PragmaHeaderKey, PragmaNoCacheHeaderValue)
|
||||
ctx.Header(ExpiresHeaderKey, ExpiresNeverHeaderValue)
|
||||
@@ -59,7 +59,7 @@ var StaticCache = func(cacheDur time.Duration) context.Handler {
|
||||
}
|
||||
|
||||
cacheControlHeaderValue := "public, max-age=" + strconv.Itoa(int(cacheDur.Seconds()))
|
||||
return func(ctx context.Context) {
|
||||
return func(ctx *context.Context) {
|
||||
cacheUntil := time.Now().Add(cacheDur).Format(ctx.Application().ConfigurationReadOnly().GetTimeFormat())
|
||||
ctx.Header(ExpiresHeaderKey, cacheUntil)
|
||||
ctx.Header(context.CacheControlHeaderKey, cacheControlHeaderValue)
|
||||
@@ -98,7 +98,7 @@ const ifNoneMatchHeaderKey = "If-None-Match"
|
||||
//
|
||||
// Read more at: https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching and
|
||||
// https://en.wikipedia.org/wiki/HTTP_ETag
|
||||
var ETag = func(ctx context.Context) {
|
||||
var ETag = func(ctx *context.Context) {
|
||||
key := ctx.Request().URL.Path
|
||||
ctx.Header(context.ETagHeaderKey, key)
|
||||
if match := ctx.GetHeader(ifNoneMatchHeaderKey); match == key {
|
||||
@@ -126,7 +126,7 @@ var ETag = func(ctx context.Context) {
|
||||
// can be used on Party's that contains a static handler,
|
||||
// i.e `HandleDir`.
|
||||
var Cache304 = func(expiresEvery time.Duration) context.Handler {
|
||||
return func(ctx context.Context) {
|
||||
return func(ctx *context.Context) {
|
||||
now := time.Now()
|
||||
if modified, err := ctx.CheckIfModifiedSince(now.Add(-expiresEvery)); !modified && err == nil {
|
||||
ctx.WriteNotModified()
|
||||
|
||||
16
cache/cache_test.go
vendored
16
cache/cache_test.go
vendored
@@ -97,12 +97,12 @@ func TestClientNoCache(t *testing.T) {
|
||||
app := iris.New()
|
||||
var n uint32
|
||||
|
||||
app.Get("/", cache.Handler(cacheDuration), func(ctx context.Context) {
|
||||
app.Get("/", cache.Handler(cacheDuration), func(ctx *context.Context) {
|
||||
atomic.AddUint32(&n, 1)
|
||||
ctx.Write([]byte(expectedBodyStr))
|
||||
})
|
||||
|
||||
app.Get("/nocache", cache.Handler(cacheDuration), func(ctx context.Context) {
|
||||
app.Get("/nocache", cache.Handler(cacheDuration), func(ctx *context.Context) {
|
||||
client.NoCache(ctx) // <----
|
||||
atomic.AddUint32(&n, 1)
|
||||
ctx.Write([]byte(expectedBodyStr))
|
||||
@@ -120,7 +120,7 @@ func TestCache(t *testing.T) {
|
||||
|
||||
app.Use(cache.Handler(cacheDuration))
|
||||
|
||||
app.Get("/", func(ctx context.Context) {
|
||||
app.Get("/", func(ctx *context.Context) {
|
||||
atomic.AddUint32(&n, 1)
|
||||
ctx.Write([]byte(expectedBodyStr))
|
||||
})
|
||||
@@ -130,7 +130,7 @@ func TestCache(t *testing.T) {
|
||||
expectedBodyStr2 = "This is the other"
|
||||
)
|
||||
|
||||
app.Get("/other", func(ctx context.Context) {
|
||||
app.Get("/other", func(ctx *context.Context) {
|
||||
atomic.AddUint32(&n2, 1)
|
||||
ctx.Write([]byte(expectedBodyStr2))
|
||||
})
|
||||
@@ -154,7 +154,7 @@ func TestCacheValidator(t *testing.T) {
|
||||
app := iris.New()
|
||||
var n uint32
|
||||
|
||||
h := func(ctx context.Context) {
|
||||
h := func(ctx *context.Context) {
|
||||
atomic.AddUint32(&n, 1)
|
||||
ctx.Write([]byte(expectedBodyStr))
|
||||
}
|
||||
@@ -164,7 +164,7 @@ func TestCacheValidator(t *testing.T) {
|
||||
|
||||
managedCache := cache.Cache(cacheDuration)
|
||||
managedCache.AddRule(rule.Validator([]rule.PreValidator{
|
||||
func(ctx context.Context) bool {
|
||||
func(ctx *context.Context) bool {
|
||||
// should always invalid for cache, don't bother to go to try to get or set cache
|
||||
return ctx.Request().URL.Path != "/invalid"
|
||||
},
|
||||
@@ -173,7 +173,7 @@ func TestCacheValidator(t *testing.T) {
|
||||
managedCache2 := cache.Cache(cacheDuration)
|
||||
managedCache2.AddRule(rule.Validator(nil,
|
||||
[]rule.PostValidator{
|
||||
func(ctx context.Context) bool {
|
||||
func(ctx *context.Context) bool {
|
||||
// it's passed the Claim and now Valid checks if the response contains a header of "DONT"
|
||||
return ctx.ResponseWriter().Header().Get("DONT") == ""
|
||||
},
|
||||
@@ -183,7 +183,7 @@ func TestCacheValidator(t *testing.T) {
|
||||
app.Get("/valid", validCache.ServeHTTP, h)
|
||||
|
||||
app.Get("/invalid", managedCache.ServeHTTP, h)
|
||||
app.Get("/invalid2", managedCache2.ServeHTTP, func(ctx context.Context) {
|
||||
app.Get("/invalid2", managedCache2.ServeHTTP, func(ctx *context.Context) {
|
||||
atomic.AddUint32(&n, 1)
|
||||
ctx.Header("DONT", "DO not cache that response even if it was claimed")
|
||||
ctx.Write([]byte(expectedBodyStr))
|
||||
|
||||
2
cache/client/client.go
vendored
2
cache/client/client.go
vendored
@@ -101,7 +101,7 @@ const (
|
||||
// if <=minimumAllowedCacheDuration then the server will try to parse from "cache-control" header
|
||||
//
|
||||
// client-side function
|
||||
func (h *ClientHandler) ServeHTTP(ctx context.Context) {
|
||||
func (h *ClientHandler) ServeHTTP(ctx *context.Context) {
|
||||
// check for deniers, if at least one of them return true
|
||||
// for this specific request, then skip the whole cache
|
||||
if !h.rule.Claim(ctx) {
|
||||
|
||||
6
cache/client/handler.go
vendored
6
cache/client/handler.go
vendored
@@ -63,17 +63,17 @@ func (h *Handler) AddRule(r rule.Rule) *Handler {
|
||||
return h
|
||||
}
|
||||
|
||||
var emptyHandler = func(ctx context.Context) {
|
||||
var emptyHandler = func(ctx *context.Context) {
|
||||
ctx.StopWithText(500, "cache: empty body handler")
|
||||
}
|
||||
|
||||
func parseLifeChanger(ctx context.Context) entry.LifeChanger {
|
||||
func parseLifeChanger(ctx *context.Context) entry.LifeChanger {
|
||||
return func() time.Duration {
|
||||
return time.Duration(ctx.MaxAge()) * time.Second
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) ServeHTTP(ctx context.Context) {
|
||||
func (h *Handler) ServeHTTP(ctx *context.Context) {
|
||||
// check for pre-cache validators, if at least one of them return false
|
||||
// for this specific request, then skip the whole cache
|
||||
bodyHandler := ctx.NextHandler()
|
||||
|
||||
4
cache/client/rule/chained.go
vendored
4
cache/client/rule/chained.go
vendored
@@ -39,7 +39,7 @@ func Chained(rule Rule, next ...Rule) Rule {
|
||||
}
|
||||
|
||||
// Claim validator
|
||||
func (c *chainedRule) Claim(ctx context.Context) bool {
|
||||
func (c *chainedRule) Claim(ctx *context.Context) bool {
|
||||
if !c.Rule.Claim(ctx) {
|
||||
return false
|
||||
}
|
||||
@@ -47,7 +47,7 @@ func (c *chainedRule) Claim(ctx context.Context) bool {
|
||||
}
|
||||
|
||||
// Valid validator
|
||||
func (c *chainedRule) Valid(ctx context.Context) bool {
|
||||
func (c *chainedRule) Valid(ctx *context.Context) bool {
|
||||
if !c.Rule.Valid(ctx) {
|
||||
return false
|
||||
}
|
||||
|
||||
4
cache/client/rule/conditional.go
vendored
4
cache/client/rule/conditional.go
vendored
@@ -33,11 +33,11 @@ func Conditional(claimPredicate func() bool, validPredicate func() bool) Rule {
|
||||
}
|
||||
|
||||
// Claim validator
|
||||
func (c *conditionalRule) Claim(ctx context.Context) bool {
|
||||
func (c *conditionalRule) Claim(ctx *context.Context) bool {
|
||||
return c.claimPredicate()
|
||||
}
|
||||
|
||||
// Valid validator
|
||||
func (c *conditionalRule) Valid(ctx context.Context) bool {
|
||||
func (c *conditionalRule) Valid(ctx *context.Context) bool {
|
||||
return c.validPredicate()
|
||||
}
|
||||
|
||||
4
cache/client/rule/header.go
vendored
4
cache/client/rule/header.go
vendored
@@ -45,11 +45,11 @@ func HeaderValid(valid ruleset.HeaderPredicate) Rule {
|
||||
}
|
||||
|
||||
// Claim validator
|
||||
func (h *headerRule) Claim(ctx context.Context) bool {
|
||||
func (h *headerRule) Claim(ctx *context.Context) bool {
|
||||
return h.claim(ctx.Request().Header.Get)
|
||||
}
|
||||
|
||||
// Valid validator
|
||||
func (h *headerRule) Valid(ctx context.Context) bool {
|
||||
func (h *headerRule) Valid(ctx *context.Context) bool {
|
||||
return h.valid(ctx.ResponseWriter().Header().Get)
|
||||
}
|
||||
|
||||
4
cache/client/rule/not_satisfied.go
vendored
4
cache/client/rule/not_satisfied.go
vendored
@@ -13,10 +13,10 @@ func NotSatisfied() Rule {
|
||||
return ¬SatisfiedRule{}
|
||||
}
|
||||
|
||||
func (n *notSatisfiedRule) Claim(context.Context) bool {
|
||||
func (n *notSatisfiedRule) Claim(*context.Context) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (n *notSatisfiedRule) Valid(context.Context) bool {
|
||||
func (n *notSatisfiedRule) Valid(*context.Context) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
8
cache/client/rule/rule.go
vendored
8
cache/client/rule/rule.go
vendored
@@ -1,11 +1,9 @@
|
||||
package rule
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12/context"
|
||||
)
|
||||
import "github.com/kataras/iris/v12/context"
|
||||
|
||||
// Rule a superset of validators
|
||||
type Rule interface {
|
||||
Claim(ctx context.Context) bool
|
||||
Valid(ctx context.Context) bool
|
||||
Claim(ctx *context.Context) bool
|
||||
Valid(ctx *context.Context) bool
|
||||
}
|
||||
|
||||
4
cache/client/rule/satisfied.go
vendored
4
cache/client/rule/satisfied.go
vendored
@@ -15,10 +15,10 @@ func Satisfied() Rule {
|
||||
return &satisfiedRule{}
|
||||
}
|
||||
|
||||
func (n *satisfiedRule) Claim(context.Context) bool {
|
||||
func (n *satisfiedRule) Claim(*context.Context) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (n *satisfiedRule) Valid(context.Context) bool {
|
||||
func (n *satisfiedRule) Valid(*context.Context) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
12
cache/client/rule/validator.go
vendored
12
cache/client/rule/validator.go
vendored
@@ -1,8 +1,6 @@
|
||||
package rule
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12/context"
|
||||
)
|
||||
import "github.com/kataras/iris/v12/context"
|
||||
|
||||
// Validators are introduced to implement the RFC about cache (https://tools.ietf.org/html/rfc7234#section-1.1).
|
||||
|
||||
@@ -18,7 +16,7 @@ import (
|
||||
// One function, accepts the request and returns false if should be denied/ignore, otherwise true.
|
||||
// if at least one return false then the original handler will execute as it's
|
||||
// and the whole cache action(set & get) should be ignored, it will be never go to the step of post-cache validations.
|
||||
type PreValidator func(context.Context) bool
|
||||
type PreValidator func(*context.Context) bool
|
||||
|
||||
// PostValidator type is is introduced to implement the second part of the RFC about cache.
|
||||
//
|
||||
@@ -32,7 +30,7 @@ type PreValidator func(context.Context) bool
|
||||
// the PreValidator checks only for request.
|
||||
//
|
||||
// If a function of type of PostValidator returns true then the (shared-always) cache is allowed to be stored.
|
||||
type PostValidator func(context.Context) bool
|
||||
type PostValidator func(*context.Context) bool
|
||||
|
||||
// validatorRule is a rule witch receives PreValidators and PostValidators
|
||||
// it's a 'complete set of rules', you can call it as a Responsible Validator,
|
||||
@@ -68,7 +66,7 @@ func Validator(preValidators []PreValidator, postValidators []PostValidator) Rul
|
||||
|
||||
// Claim returns true if incoming request can claim for a cached handler
|
||||
// the original handler should run as it is and exit
|
||||
func (v *validatorRule) Claim(ctx context.Context) bool {
|
||||
func (v *validatorRule) Claim(ctx *context.Context) bool {
|
||||
// check for pre-cache validators, if at least one of them return false
|
||||
// for this specific request, then skip the whole cache
|
||||
for _, shouldProcess := range v.preValidators {
|
||||
@@ -82,7 +80,7 @@ func (v *validatorRule) Claim(ctx context.Context) bool {
|
||||
// Valid returns true if incoming request and post-response from the original handler
|
||||
// is valid to be store to the cache, if not(false) then the consumer should just exit
|
||||
// otherwise(true) the consumer should store the cached response
|
||||
func (v *validatorRule) Valid(ctx context.Context) bool {
|
||||
func (v *validatorRule) Valid(ctx *context.Context) bool {
|
||||
// check if it's a valid response, if it's not then just return.
|
||||
for _, valid := range v.postValidators {
|
||||
if !valid(ctx) {
|
||||
|
||||
2
cache/client/ruleset.go
vendored
2
cache/client/ruleset.go
vendored
@@ -28,6 +28,6 @@ var DefaultRuleSet = rule.Chained(
|
||||
|
||||
// NoCache disables the cache for a particular request,
|
||||
// can be used as a middleware or called manually from the handler.
|
||||
func NoCache(ctx context.Context) {
|
||||
func NoCache(ctx *context.Context) {
|
||||
ctx.Header(cfg.NoCacheHeader, "true")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user