Skip to content

Commit

Permalink
Many object creates moved out of main middleware chain
Browse files Browse the repository at this point in the history
  • Loading branch information
lonelycode committed Jul 1, 2015
1 parent 9d20a5d commit 15f4e9c
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 80 deletions.
39 changes: 0 additions & 39 deletions handler_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,6 @@ import (
// "net/http/httputil"
)

// type ProxyHandler struct {
// TykMiddleware
// }

// type ProxyHandlerConfig struct{
// sH SuccessHandler
// }

// // New lets you do any initialisations for the object can be done here
// func (p *ProxyHandler) New() {
// tm := TykMiddleware{p.Spec, p}
// p.sH = SuccessHandler{p.Spec, p}
// }

// // GetConfig retrieves the configuration from the API config - we user mapstructure for this for simplicity
// func (p *ProxyHandler) GetConfig() (interface{}, error) {
// return nil, nil
// }

// // ProcessRequest will run any checks on the request on the way through the system, return an error to have the chain fail
// func (m *ModifiedMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Request, configuration interface{}) (error, int) {
// p.sH.ServeHTTP(w, r)
// return nil,

// return nil, 200
// }

type DummyProxyHandler struct {
SH SuccessHandler
}
Expand All @@ -41,18 +14,6 @@ func (d DummyProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}

// func CreateProxyHandler(p *ReverseProxy, apiSpec APISpec) func(http.Handler) http.Handler {
// tm := TykMiddleware{apiSpec, p}
// handler := SuccessHandler{tm}

// aliceHandler := func(h http.Handler) http.Handler {

// return http.HandlerFunc(handler)
// }

// return aliceHandler
// }

// ProxyHandler Proxies requests through to their final destination, if they make it through the middleware chain.
func ProxyHandler(p *ReverseProxy, apiSpec APISpec) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
Expand Down
20 changes: 10 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ func loadApps(APISpecs []APISpec, Muxer *http.ServeMux) {
// Create the response processors
creeateResponseMiddlewareChain(&referenceSpec)

proxyHandler := http.HandlerFunc(ProxyHandler(proxy, referenceSpec))
//proxyHandler := http.HandlerFunc(ProxyHandler(proxy, referenceSpec))
tykMiddleware := TykMiddleware{referenceSpec, proxy}

keyPrefix := "cache-" + referenceSpec.APIDefinition.APIID
Expand All @@ -395,9 +395,9 @@ func loadApps(APISpecs []APISpec, Muxer *http.ServeMux) {

if referenceSpec.APIDefinition.UseKeylessAccess {
// for KeyLessAccess we can't support rate limiting, versioning or access rules
chain := alice.New(CreateMiddleware(&IPWhiteListMiddleware{tykMiddleware}, tykMiddleware),
CreateMiddleware(&OrganizationMonitor{tykMiddleware}, tykMiddleware),
CreateMiddleware(&VersionCheck{tykMiddleware}, tykMiddleware),
chain := alice.New(CreateMiddleware(&IPWhiteListMiddleware{TykMiddleware: tykMiddleware}, tykMiddleware),
CreateMiddleware(&OrganizationMonitor{TykMiddleware: tykMiddleware}, tykMiddleware),
CreateMiddleware(&VersionCheck{TykMiddleware: tykMiddleware}, tykMiddleware),
CreateMiddleware(&TransformMiddleware{tykMiddleware}, tykMiddleware),
CreateMiddleware(&TransformHeaders{TykMiddleware: tykMiddleware}, tykMiddleware),
CreateMiddleware(&RedisCacheMiddleware{TykMiddleware: tykMiddleware, CacheStore: CacheStore}, tykMiddleware)).Then(DummyProxyHandler{SH: SuccessHandler{tykMiddleware}})
Expand Down Expand Up @@ -425,9 +425,9 @@ func loadApps(APISpecs []APISpec, Muxer *http.ServeMux) {
var chainArray = []alice.Constructor{}

var baseChainArray = []alice.Constructor{
CreateMiddleware(&IPWhiteListMiddleware{tykMiddleware}, tykMiddleware),
CreateMiddleware(&OrganizationMonitor{tykMiddleware}, tykMiddleware),
CreateMiddleware(&VersionCheck{tykMiddleware}, tykMiddleware),
CreateMiddleware(&IPWhiteListMiddleware{TykMiddleware: tykMiddleware}, tykMiddleware),
CreateMiddleware(&OrganizationMonitor{TykMiddleware: tykMiddleware}, tykMiddleware),
CreateMiddleware(&VersionCheck{TykMiddleware: tykMiddleware}, tykMiddleware),
keyCheck,
CreateMiddleware(&KeyExpired{tykMiddleware}, tykMiddleware),
CreateMiddleware(&AccessRightsCheck{tykMiddleware}, tykMiddleware),
Expand All @@ -452,13 +452,13 @@ func loadApps(APISpecs []APISpec, Muxer *http.ServeMux) {
}

// Use CreateMiddleware(&ModifiedMiddleware{tykMiddleware}, tykMiddleware) to run custom middleware
chain := alice.New(chainArray...).Then(proxyHandler)
chain := alice.New(chainArray...).Then(DummyProxyHandler{SH: SuccessHandler{tykMiddleware}})

userCheckHandler := http.HandlerFunc(UserRatesCheck())
simpleChain := alice.New(
CreateMiddleware(&IPWhiteListMiddleware{tykMiddleware}, tykMiddleware),
CreateMiddleware(&OrganizationMonitor{tykMiddleware}, tykMiddleware),
CreateMiddleware(&VersionCheck{tykMiddleware}, tykMiddleware),
CreateMiddleware(&OrganizationMonitor{TykMiddleware: tykMiddleware}, tykMiddleware),
CreateMiddleware(&VersionCheck{TykMiddleware: tykMiddleware}, tykMiddleware),
keyCheck,
CreateMiddleware(&KeyExpired{tykMiddleware}, tykMiddleware),
CreateMiddleware(&AccessRightsCheck{tykMiddleware}, tykMiddleware)).Then(userCheckHandler)
Expand Down
5 changes: 2 additions & 3 deletions middleware_ip_whitelist.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,16 @@ func (i *IPWhiteListMiddleware) GetConfig() (interface{}, error) {

// ProcessRequest will run any checks on the request on the way through the system, return an error to have the chain fail
func (i *IPWhiteListMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Request, configuration interface{}) (error, int) {
ipConfig := i.TykMiddleware.Spec

// Disabled, pass through
if !ipConfig.EnableIpWhiteListing {
if !i.TykMiddleware.Spec.EnableIpWhiteListing {
return nil, 200
}

var remoteIP net.IP

// Enabled, check incoming IP address
for _, ip := range ipConfig.AllowedIPs {
for _, ip := range i.TykMiddleware.Spec.AllowedIPs {
allowedIP := net.ParseIP(ip)
splitIP := strings.Split(r.RemoteAddr, ":")
remoteIPString := splitIP[0]
Expand Down
26 changes: 13 additions & 13 deletions middleware_organisation_activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,15 @@ import (
// within it's rate limit, it makes use of the SessionLimiter object to do this
type OrganizationMonitor struct {
TykMiddleware
sessionlimiter SessionLimiter
mon Monitor
}

// New lets you do any initialisations for the object can be done here
func (k *OrganizationMonitor) New() {}
func (k *OrganizationMonitor) New() {
k.sessionlimiter = SessionLimiter{}
k.mon = Monitor{}
}

// GetConfig retrieves the configuration from the API config - we user mapstructure for this for simplicity
func (k *OrganizationMonitor) GetConfig() (interface{}, error) {
Expand All @@ -23,10 +28,7 @@ func (k *OrganizationMonitor) GetConfig() (interface{}, error) {

// ProcessRequest will run any checks on the request on the way through the system, return an error to have the chain fail
func (k *OrganizationMonitor) ProcessRequest(w http.ResponseWriter, r *http.Request, configuration interface{}) (error, int) {
sessionLimiter := SessionLimiter{}

thisOrg := k.Spec.OrgID
thisSessionState, found := k.GetOrgSession(thisOrg)
thisSessionState, found := k.GetOrgSession(k.Spec.OrgID)

if !found {
// No organisation session has been created, should not be a pre-requisite in site setups, so we pass the request on
Expand All @@ -38,24 +40,23 @@ func (k *OrganizationMonitor) ProcessRequest(w http.ResponseWriter, r *http.Requ
log.WithFields(logrus.Fields{
"path": r.URL.Path,
"origin": r.RemoteAddr,
"key": thisOrg,
"key": k.Spec.OrgID,
}).Info("Organisation access is disabled.")

return errors.New("This organisation access has been disabled, please contact your API administrator."), 403
}

// We found a session, apply the quota limiter
storeRef := k.Spec.OrgSessionManager.GetStore()
forwardMessage, reason := sessionLimiter.ForwardMessage(&thisSessionState, thisOrg, storeRef)
forwardMessage, reason := k.sessionlimiter.ForwardMessage(&thisSessionState, k.Spec.OrgID, k.Spec.OrgSessionManager.GetStore())

k.Spec.OrgSessionManager.UpdateSession(thisOrg, thisSessionState, 0)
k.Spec.OrgSessionManager.UpdateSession(k.Spec.OrgID, thisSessionState, 0)

if !forwardMessage {
if reason == 2 {
log.WithFields(logrus.Fields{
"path": r.URL.Path,
"origin": r.RemoteAddr,
"key": thisOrg,
"key": k.Spec.OrgID,
}).Info("Organisation quota has been exceeded.")

// Fire a quota exceeded event
Expand All @@ -64,7 +65,7 @@ func (k *OrganizationMonitor) ProcessRequest(w http.ResponseWriter, r *http.Requ
EventMetaDefault: EventMetaDefault{Message: "Organisation quota has been exceeded", OriginatingRequest: EncodeRequestToEvent(r)},
Path: r.URL.Path,
Origin: r.RemoteAddr,
Key: thisOrg,
Key: k.Spec.OrgID,
})

return errors.New("This organisation quota has been exceeded, please contact your API administrator"), 403
Expand All @@ -73,8 +74,7 @@ func (k *OrganizationMonitor) ProcessRequest(w http.ResponseWriter, r *http.Requ

if config.Monitor.MonitorOrgKeys {
// Run the trigger monitor
mon := Monitor{}
mon.Check(&thisSessionState, "")
k.mon.Check(&thisSessionState, "")
}
// Request is valid, carry on
return nil, 200
Expand Down
24 changes: 13 additions & 11 deletions middleware_redis_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import (
"bytes"
"crypto/md5"
"encoding/hex"
"errors"
"github.com/gorilla/context"
"io"
"net/http"
"strconv"
"strings"
"errors"
)

const (
Expand All @@ -22,12 +22,16 @@ const (
type RedisCacheMiddleware struct {
TykMiddleware
CacheStore StorageHandler
sh SuccessHandler
}

type RedisCacheMiddlewareConfig struct{}
type RedisCacheMiddlewareConfig struct {
}

// New lets you do any initialisations for the object can be done here
func (m *RedisCacheMiddleware) New() {}
func (m *RedisCacheMiddleware) New() {
m.sh = SuccessHandler{m.TykMiddleware}
}

// GetConfig retrieves the configuration from the API config - we user mapstructure for this for simplicity
func (m *RedisCacheMiddleware) GetConfig() (interface{}, error) {
Expand Down Expand Up @@ -93,21 +97,20 @@ func (m *RedisCacheMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Req
authHeaderValue, ipErr = GetIP(r.RemoteAddr)
if ipErr != nil {
log.Error(ipErr)
return nil, 200
return nil, 200
}
} else {
authHeaderValue = authVal.(string)
}
}

thisKey := m.CreateCheckSum(r, authHeaderValue)
retBlob, found := m.CacheStore.GetKey(thisKey)
if found != nil {
log.Debug("Cache enabled, but record not found")
// Pass through to proxy AND CACHE RESULT
sNP := SuccessHandler{m.TykMiddleware}

// This passes through and will write the value to the writer, but spit out a copy for the cache
reqVal := sNP.ServeHTTP(w, r)
reqVal := m.sh.ServeHTTP(w, r)

cacheThisRequest := true
cacheTTL := m.Spec.APIDefinition.CacheOptions.CacheTimeout
Expand Down Expand Up @@ -167,14 +170,13 @@ func (m *RedisCacheMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Req
w.Header().Set("X-RateLimit-Limit", strconv.Itoa(int(thisSessionState.QuotaMax)))
w.Header().Set("X-RateLimit-Remaining", strconv.Itoa(int(thisSessionState.QuotaRemaining)))
w.Header().Set("X-RateLimit-Reset", strconv.Itoa(int(thisSessionState.QuotaRenews)))
}
}
w.Header().Add("x-tyk-cached-response", "1")
w.WriteHeader(newRes.StatusCode)
m.Proxy.copyResponse(w, newRes.Body)

// Record analytics
sNP := SuccessHandler{m.TykMiddleware}
go sNP.RecordHit(w, r, 0)
go m.sh.RecordHit(w, r, 0)

// Stop any further execution
return nil, 666
Expand Down
9 changes: 5 additions & 4 deletions middleware_version_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ import (
// VersionCheck will check whether the version of the requested API the request is accessing has any restrictions on URL endpoints
type VersionCheck struct {
TykMiddleware
sh SuccessHandler
}

// New lets you do any initialisations for the object can be done here
func (v *VersionCheck) New() {}
func (v *VersionCheck) New() {
v.sh = SuccessHandler{v.TykMiddleware}
}

// GetConfig retrieves the configuration from the API config
func (v *VersionCheck) GetConfig() (interface{}, error) {
Expand Down Expand Up @@ -57,9 +60,7 @@ func (v *VersionCheck) ProcessRequest(w http.ResponseWriter, r *http.Request, co
}

if stat == StatusOkAndIgnore {
handler := SuccessHandler{v.TykMiddleware}
// Skip all other execution
handler.ServeHTTP(w, r)
v.sh.ServeHTTP(w, r)
return nil, 666
}

Expand Down

0 comments on commit 15f4e9c

Please sign in to comment.