Skip to content

Commit

Permalink
Fixed global rate limit not updating after a reload
Browse files Browse the repository at this point in the history
For #356.
  • Loading branch information
lonelycode authored and mvdan committed Oct 10, 2017
1 parent a0e0e65 commit 747c405
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
7 changes: 6 additions & 1 deletion mw_api_rate_limit.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import (

"github.com/Sirupsen/logrus"

"strconv"
"time"

"github.com/TykTechnologies/tyk/user"
)

Expand All @@ -29,10 +32,12 @@ func (k *RateLimitForAPI) EnabledForSpec() bool {

// We'll init here
k.keyName = fmt.Sprintf("apilimiter-%s%s", k.Spec.OrgID, k.Spec.APIID)

// Set last updated on each load to ensure we always use a new rate limit bucket
k.apiSess = &user.SessionState{
Rate: k.Spec.GlobalRateLimit.Rate,
Per: k.Spec.GlobalRateLimit.Per,
LastUpdated: "na",
LastUpdated: strconv.Itoa(int(time.Now().UnixNano())),
}

return true
Expand Down
50 changes: 49 additions & 1 deletion mw_api_rate_limit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ func getRLOpenChain(spec *APISpec) http.Handler {
baseMid := BaseMiddleware{spec, proxy}
chain := alice.New(mwList(
&IPWhiteListMiddleware{baseMid},
&RateLimitForAPI{BaseMiddleware: baseMid},
&VersionCheck{BaseMiddleware: baseMid},
&RateLimitForAPI{BaseMiddleware: baseMid},
)...).Then(proxyHandler)
return chain
}
Expand Down Expand Up @@ -122,6 +122,54 @@ func TestRLClosed(t *testing.T) {
DRLManager.RequestTokenValue = 0
}

func TestRLOpenWithReload(t *testing.T) {
spec := createSpecTest(t, openRLDefSmall)

req := testReq(t, "GET", "/rl_test/", nil)

DRLManager.CurrentTokenValue = 1
DRLManager.RequestTokenValue = 1

chain := getRLOpenChain(spec)
for a := 0; a <= 10; a++ {
recorder := httptest.NewRecorder()
chain.ServeHTTP(recorder, req)
if a < 3 {
if recorder.Code != 200 {
t.Fatalf("Rate limit (pre change) kicked in too early, after only %v requests", a)
}
}

if a > 7 {
if recorder.Code != 429 {
t.Fatalf("Rate limit (pre change) did not activate, code was: %v", recorder.Code)
}
}
}

// CHange rate and emulate a reload
spec.GlobalRateLimit.Rate = 20
chain = getRLOpenChain(spec)
for a := 0; a <= 30; a++ {
recorder := httptest.NewRecorder()
chain.ServeHTTP(recorder, req)
if a < 20 {
if recorder.Code != 200 {
t.Fatalf("Rate limit (post change) kicked in too early, after only %v requests", a)
}
}

if a > 23 {
if recorder.Code != 429 {
t.Fatalf("Rate limit (post change) did not activate, code was: %v", recorder.Code)
}
}
}

DRLManager.CurrentTokenValue = 0
DRLManager.RequestTokenValue = 0
}

const openRLDefSmall = `{
"api_id": "313232",
"org_id": "default",
Expand Down

0 comments on commit 747c405

Please sign in to comment.