mirror of
https://github.com/kataras/iris.git
synced 2026-01-10 13:35:59 +00:00
Publish the new version ✈️ | Look description please!
# FAQ ### Looking for free support? http://support.iris-go.com https://kataras.rocket.chat/channel/iris ### Looking for previous versions? https://github.com/kataras/iris#version ### Should I upgrade my Iris? Developers are not forced to upgrade if they don't really need it. Upgrade whenever you feel ready. > Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes. **How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris`. For further installation support, please click [here](http://support.iris-go.com/d/16-how-to-install-iris-web-framework). ### About our new home page http://iris-go.com Thanks to [Santosh Anand](https://github.com/santoshanand) the http://iris-go.com has been upgraded and it's really awesome! [Santosh](https://github.com/santoshanand) is a freelancer, he has a great knowledge of nodejs and express js, Android, iOS, React Native, Vue.js etc, if you need a developer to find or create a solution for your problem or task, please contact with him. The amount of the next two or three donations you'll send they will be immediately transferred to his own account balance, so be generous please! Read more at https://github.com/kataras/iris/blob/master/HISTORY.md Former-commit-id: eec2d71bbe011d6b48d2526eb25919e36e5ad94e
This commit is contained in:
60
cache/client/rule/chained.go
vendored
Normal file
60
cache/client/rule/chained.go
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2017 Gerasimos Maropoulos, ΓΜ. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package rule
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/context"
|
||||
)
|
||||
|
||||
// chainedRule is a Rule with next Rule
|
||||
type chainedRule struct {
|
||||
Rule
|
||||
next Rule
|
||||
}
|
||||
|
||||
var _ Rule = &chainedRule{}
|
||||
|
||||
// chainedSingle returns a new rule witch has a next rule too
|
||||
func chainedSingle(rule Rule, next Rule) Rule {
|
||||
if next == nil {
|
||||
next = Satisfied()
|
||||
}
|
||||
|
||||
return &chainedRule{
|
||||
Rule: rule,
|
||||
next: next,
|
||||
}
|
||||
}
|
||||
|
||||
// Chained returns a new rule which has more than one coming next ruleset
|
||||
func Chained(rule Rule, next ...Rule) Rule {
|
||||
if len(next) == 0 {
|
||||
return chainedSingle(rule, nil)
|
||||
}
|
||||
c := chainedSingle(rule, next[0])
|
||||
|
||||
for i := 1; i < len(next); i++ {
|
||||
c = chainedSingle(c, next[i])
|
||||
}
|
||||
|
||||
return c
|
||||
|
||||
}
|
||||
|
||||
// Claim validator
|
||||
func (c *chainedRule) Claim(ctx context.Context) bool {
|
||||
if !c.Rule.Claim(ctx) {
|
||||
return false
|
||||
}
|
||||
return c.next.Claim(ctx)
|
||||
}
|
||||
|
||||
// Valid validator
|
||||
func (c *chainedRule) Valid(ctx context.Context) bool {
|
||||
if !c.Rule.Valid(ctx) {
|
||||
return false
|
||||
}
|
||||
return c.next.Valid(ctx)
|
||||
}
|
||||
53
cache/client/rule/conditional.go
vendored
Normal file
53
cache/client/rule/conditional.go
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright 2017 Gerasimos Maropoulos, ΓΜ. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package rule
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/context"
|
||||
)
|
||||
|
||||
// Conditional is a Rule witch adds a predicate in order to its methods to execute
|
||||
type conditionalRule struct {
|
||||
claimPredicate func() bool
|
||||
validPredicate func() bool
|
||||
}
|
||||
|
||||
var emptyConditionalPredicate = func() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
var _ Rule = &conditionalRule{}
|
||||
|
||||
// Conditional returns a new rule witch has conditionals
|
||||
func Conditional(claimPredicate func() bool, validPredicate func() bool) Rule {
|
||||
if claimPredicate == nil {
|
||||
claimPredicate = emptyConditionalPredicate
|
||||
}
|
||||
|
||||
if validPredicate == nil {
|
||||
validPredicate = emptyConditionalPredicate
|
||||
}
|
||||
|
||||
return &conditionalRule{
|
||||
claimPredicate: claimPredicate,
|
||||
validPredicate: validPredicate,
|
||||
}
|
||||
}
|
||||
|
||||
// Claim validator
|
||||
func (c *conditionalRule) Claim(ctx context.Context) bool {
|
||||
if !c.claimPredicate() {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Valid validator
|
||||
func (c *conditionalRule) Valid(ctx context.Context) bool {
|
||||
if !c.validPredicate() {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
59
cache/client/rule/header.go
vendored
Normal file
59
cache/client/rule/header.go
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2017 Gerasimos Maropoulos, ΓΜ. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package rule
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/context"
|
||||
|
||||
"github.com/kataras/iris/cache/ruleset"
|
||||
)
|
||||
|
||||
// The HeaderPredicate should be alived on each of $package/rule BUT GOLANG DOESN'T SUPPORT type alias and I don't want to have so many copies around
|
||||
// read more at ../../ruleset.go
|
||||
|
||||
// headerRule is a Rule witch receives and checks for a header predicates
|
||||
// request headers on Claim and response headers on Valid.
|
||||
type headerRule struct {
|
||||
claim ruleset.HeaderPredicate
|
||||
valid ruleset.HeaderPredicate
|
||||
}
|
||||
|
||||
var _ Rule = &headerRule{}
|
||||
|
||||
// Header returns a new rule witch claims and execute the post validations trough headers
|
||||
func Header(claim ruleset.HeaderPredicate, valid ruleset.HeaderPredicate) Rule {
|
||||
if claim == nil {
|
||||
claim = ruleset.EmptyHeaderPredicate
|
||||
}
|
||||
|
||||
if valid == nil {
|
||||
valid = ruleset.EmptyHeaderPredicate
|
||||
}
|
||||
|
||||
return &headerRule{
|
||||
claim: claim,
|
||||
valid: valid,
|
||||
}
|
||||
}
|
||||
|
||||
// HeaderClaim returns a header rule which cares only about claiming (pre-validation)
|
||||
func HeaderClaim(claim ruleset.HeaderPredicate) Rule {
|
||||
return Header(claim, nil)
|
||||
}
|
||||
|
||||
// HeaderValid returns a header rule which cares only about valid (post-validation)
|
||||
func HeaderValid(valid ruleset.HeaderPredicate) Rule {
|
||||
return Header(nil, valid)
|
||||
}
|
||||
|
||||
// Claim validator
|
||||
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 {
|
||||
return h.valid(ctx.ResponseWriter().Header().Get)
|
||||
}
|
||||
26
cache/client/rule/not_satisfied.go
vendored
Normal file
26
cache/client/rule/not_satisfied.go
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2017 Gerasimos Maropoulos, ΓΜ. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package rule
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/context"
|
||||
)
|
||||
|
||||
type notSatisfiedRule struct{}
|
||||
|
||||
var _ Rule = ¬SatisfiedRule{}
|
||||
|
||||
// NotSatisfied returns a rule which allows nothing
|
||||
func NotSatisfied() Rule {
|
||||
return ¬SatisfiedRule{}
|
||||
}
|
||||
|
||||
func (n *notSatisfiedRule) Claim(context.Context) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (n *notSatisfiedRule) Valid(context.Context) bool {
|
||||
return false
|
||||
}
|
||||
15
cache/client/rule/rule.go
vendored
Normal file
15
cache/client/rule/rule.go
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright 2017 Gerasimos Maropoulos, ΓΜ. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package rule
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/context"
|
||||
)
|
||||
|
||||
// Rule a superset of validators
|
||||
type Rule interface {
|
||||
Claim(ctx context.Context) bool
|
||||
Valid(ctx context.Context) bool
|
||||
}
|
||||
28
cache/client/rule/satisfied.go
vendored
Normal file
28
cache/client/rule/satisfied.go
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2017 Gerasimos Maropoulos, ΓΜ. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package rule
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/context"
|
||||
)
|
||||
|
||||
type satisfiedRule struct{}
|
||||
|
||||
var _ Rule = &satisfiedRule{}
|
||||
|
||||
// Satisfied returns a rule which allows anything,
|
||||
// it's usually the last rule on chained rules if no next rule is given,
|
||||
// but it can be used outside of a chain too as a default allow-all rule.
|
||||
func Satisfied() Rule {
|
||||
return &satisfiedRule{}
|
||||
}
|
||||
|
||||
func (n *satisfiedRule) Claim(context.Context) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (n *satisfiedRule) Valid(context.Context) bool {
|
||||
return true
|
||||
}
|
||||
97
cache/client/rule/validator.go
vendored
Normal file
97
cache/client/rule/validator.go
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright 2017 Gerasimos Maropoulos, ΓΜ. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package rule
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/context"
|
||||
)
|
||||
|
||||
// Validators are introduced to implement the RFC about cache (https://tools.ietf.org/html/rfc7234#section-1.1).
|
||||
|
||||
// PreValidator like middleware, executes before the cache action begins, if a callback returns false
|
||||
// then this specific cache action, with specific request, is ignored and the real (original)
|
||||
// handler is executed instead.
|
||||
//
|
||||
// I'll not add all specifications here I'll give the opportunity (public API in the httpcache package-level)
|
||||
// to the end-user to specify her/his ignore rules too (ignore-only for now).
|
||||
//
|
||||
// Each package, nethttp and fhttp should implement their own encapsulations because of different request object.
|
||||
//
|
||||
// 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
|
||||
|
||||
// PostValidator type is is introduced to implement the second part of the RFC about cache.
|
||||
//
|
||||
// Q: What's the difference between this and a PreValidator?
|
||||
// A: PreValidator runs BEFORE trying to get the cache, it cares only for the request
|
||||
// and if at least one PreValidator returns false then it just runs the original handler and stop there, at the other hand
|
||||
// a PostValidator runs if all PreValidators returns true and original handler is executed but with a response recorder,
|
||||
// also the PostValidator should return true to store the cached response.
|
||||
// Last, a PostValidator accepts a context
|
||||
// in order to be able to catch the original handler's response,
|
||||
// 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
|
||||
|
||||
// validatorRule is a rule witch receives PreValidators and PostValidators
|
||||
// it's a 'complete set of rules', you can call it as a Responsible Validator,
|
||||
// it's used when you the user wants to check for special things inside a request and a response.
|
||||
type validatorRule struct {
|
||||
// preValidators a list of PreValidator functions, execute before real cache begins
|
||||
// if at least one of them returns false then the original handler will execute as it's
|
||||
// and the whole cache action(set & get) will be skipped for this specific client's request.
|
||||
//
|
||||
// Read-only 'runtime'
|
||||
preValidators []PreValidator
|
||||
|
||||
// postValidators a list of PostValidator functions, execute after the original handler is executed with the response recorder
|
||||
// and exactly before this cached response is saved,
|
||||
// if at least one of them returns false then the response will be not saved for this specific client's request.
|
||||
//
|
||||
// Read-only 'runtime'
|
||||
postValidators []PostValidator
|
||||
}
|
||||
|
||||
var _ Rule = &validatorRule{}
|
||||
|
||||
// DefaultValidator returns a new validator which contains the default pre and post cache validators
|
||||
func DefaultValidator() Rule { return Validator(nil, nil) }
|
||||
|
||||
// Validator receives the preValidators and postValidators and returns a new Validator rule
|
||||
func Validator(preValidators []PreValidator, postValidators []PostValidator) Rule {
|
||||
return &validatorRule{
|
||||
preValidators: preValidators,
|
||||
postValidators: postValidators,
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// 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 {
|
||||
if !shouldProcess(ctx) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// check if it's a valid response, if it's not then just return.
|
||||
for _, valid := range v.postValidators {
|
||||
if !valid(ctx) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user