Skip to content

Commit

Permalink
client: Expose rate limit extensions in response
Browse files Browse the repository at this point in the history
  • Loading branch information
philipgough committed Feb 21, 2019
1 parent e41b4f8 commit ffa7c9f
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 10 deletions.
2 changes: 1 addition & 1 deletion client/auth_rep.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func (client *ThreeScaleClient) authRep(values url.Values, extensions map[string
}

req.URL.RawQuery = values.Encode()
resp, err = client.doHttpReq(req)
resp, err = client.doHttpReq(req, extensions)
if err != nil {
return resp, fmt.Errorf("error calling 3Scale API - %s", err.Error())
}
Expand Down
4 changes: 2 additions & 2 deletions client/authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (client *ThreeScaleClient) Authorize(appId string, serviceToken string, ser
values.Add("service_id", serviceId)

req.URL.RawQuery = values.Encode()
authRepRes, err := client.doHttpReq(req)
authRepRes, err := client.doHttpReq(req, extensions)
if err != nil {
return authRepResp, fmt.Errorf("error calling 3Scale API - %s", err.Error())
}
Expand All @@ -45,7 +45,7 @@ func (client *ThreeScaleClient) AuthorizeKey(userKey string, serviceToken string
values.Add("service_id", serviceId)

req.URL.RawQuery = values.Encode()
resp, err = client.doHttpReq(req)
resp, err = client.doHttpReq(req, extensions)
if err != nil {
return resp, fmt.Errorf("error calling 3Scale API - %s", err.Error())
}
Expand Down
35 changes: 33 additions & 2 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
const (
defaultBackendUrl = "https://su1.3scale.net:443"
queryTag = "query"
limitExtensions = "limit_headers"
)

var httpReqError = errors.New("error building http request")
Expand Down Expand Up @@ -52,7 +53,7 @@ func NewThreeScale(backEnd *Backend, httpClient *http.Client) *ThreeScaleClient
}

// GetPeer - a utility method that returns the remote hostname of the client
func (client *ThreeScaleClient) GetPeer() string {
func (client *ThreeScaleClient) GetPeer() string {
return client.backend.host
}

Expand Down Expand Up @@ -93,7 +94,7 @@ func encodeExtensions(extensions map[string]string) string {
}

// Call 3scale backend with the provided HTTP request
func (client *ThreeScaleClient) doHttpReq(req *http.Request) (ApiResponse, error) {
func (client *ThreeScaleClient) doHttpReq(req *http.Request, ext map[string]string) (ApiResponse, error) {
var authRepRes ApiResponse

resp, err := client.httpClient.Do(req)
Expand All @@ -108,10 +109,40 @@ func (client *ThreeScaleClient) doHttpReq(req *http.Request) (ApiResponse, error
if err != nil {
return authRepRes, err
}

if ext != nil {
if _, ok := ext[limitExtensions]; ok {
if limitRem := resp.Header.Get("3scale-limit-remaining"); limitRem != "" {
remainingLimit, _ := strconv.Atoi(limitRem)
authRepRes.limitRemaining = &remainingLimit
}

if limReset := resp.Header.Get("3scale-limit-reset"); limReset != "" {
resetLimit, _ := strconv.Atoi(limReset)
authRepRes.limitReset = &resetLimit
}
}
}

authRepRes.StatusCode = resp.StatusCode
return authRepRes, nil
}

// GetLimitRemaining - An integer stating the amount of hits left for the full combination of metrics authorized in this call
// before the rate limiting logic would start denying authorizations for the current period.
// A negative integer value means there is no limit in the amount of hits.
// Nil value will indicate the extension has not been used.
func (r ApiResponse) GetLimitRemaining() *int {
return r.limitRemaining
}

// GetLimitReset - An integer stating the amount of seconds left for the current limiting period to elapse.
// A negative integer value means there is no limit in time.
// Nil value will indicate the extension has not been used.
func (r ApiResponse) GetLimitReset() *int {
return r.limitReset
}

// Add a metric to list of metrics to be reported
// Returns error if provided value is non-positive and entry will be ignored
func (m Metrics) Add(name string, value int) error {
Expand Down
2 changes: 1 addition & 1 deletion client/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (client *ThreeScaleClient) report(values url.Values, extensions map[string]
}

req.URL.RawQuery = values.Encode()
resp, err = client.doHttpReq(req)
resp, err = client.doHttpReq(req, extensions)
if err != nil {
return resp, fmt.Errorf("error calling 3Scale API - %s", err.Error())
}
Expand Down
10 changes: 6 additions & 4 deletions client/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ const providerKey = "provider_key"

// ApiResponse - formatted response to client
type ApiResponse struct {
Reason string
Success bool
StatusCode int
Reason string
Success bool
StatusCode int
limitRemaining *int
limitReset *int
}

// ApiResponseXML - response from backend API
Expand Down Expand Up @@ -80,7 +82,7 @@ type TokenAuth struct {
Value string
}

func (auth *TokenAuth) SetURLValues(values *url.Values) (error) {
func (auth *TokenAuth) SetURLValues(values *url.Values) error {

switch auth.Type {
case serviceToken:
Expand Down

0 comments on commit ffa7c9f

Please sign in to comment.