Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rate limiting headers and status code #335

Closed
ErwinSteffens opened this issue Mar 24, 2017 · 9 comments
Closed

Rate limiting headers and status code #335

ErwinSteffens opened this issue Mar 24, 2017 · 9 comments
Assignees
Milestone

Comments

@ErwinSteffens
Copy link

For now we always get a ‘403 Forbidden’ error with body ‘Authentication failed’. We would like to return a more specific error status code like ‘429 Too Many Requests’.

Also we would like to add ‘X-Rate-Limit’ headers like in the twitter API: https://dev.twitter.com/rest/public/rate-limiting.

Is this possible to create with some custom scripting?

@mikz
Copy link
Contributor

mikz commented Mar 24, 2017

The rate limiting is done by 3scale Service Management API.

When Rate Limit is reached it returns response like:

<?xml version="1.0" encoding="UTF-8"?>
<status>
  <authorized>false</authorized>
  <reason>usage limits are exceeded</reason>
  <plan>test</plan>
  <usage_reports>
    <usage_report metric="test" period="minute">
      <period_start>2017-03-24 11:21:00 +0000</period_start>
      <period_end>2017-03-24 11:22:00 +0000</period_end>
      <max_value>10</max_value>
      <current_value>10</current_value>
    </usage_report>
  </usage_reports>
</status>

Now I'm not sure how many elements there will be if multiple metrics are hit.

But I guess it would be feasible to extract this information and report it to the client. The issue is parsing XML. There are some libraries but nothing really great.

We eventually would like this feature to be in the product.

@ErwinSteffens
Copy link
Author

Ok, I think we will build something based on this.

We can share it back as an example when finished, but I think it will be based on a single metric.

@mikz
Copy link
Contributor

mikz commented Mar 25, 2017

Let me know if you make any progress. Don't try LuaXML - it does not work well with OpenResty.
Using some FFI bindings for libexpat is kind of ok, but not great. I'd suggest using https://github.com/Phrogz/SLAXML if the performance is not so terrible as it is pure lua.

If you feel like try to open an PR and I'll try to help you to get it into master.

Because the whole process is asynchronous, it has to be preparing the response for the next request.
There is shared memory for storing the last response, so adding there more metadata could work.

I guess the hardest part is to define how it is supposed to work (including multiple metrics to prevent some nasty accidents) and test it.

@mikz
Copy link
Contributor

mikz commented Apr 7, 2017

So we are playing with the idea of introducing Retry-After header which is in the HTTP spec.
It says in what time client should retry the call. This would fit the rate limiting story.

The algorithm would be following:

  • from all the limits that the authorise call exceeded
  • take the greatest granularity one
  • send in Retry-After the timestamp when the limit will reset

Would that be enough for you? @ErwinSteffens

Counting remaining quota and which metric was hit is way harder because there can be multiple overlapping metrics, methods and granularities. So we would like to start with something easy that we can get out quickly.

@ErwinSteffens
Copy link
Author

ErwinSteffens commented Apr 7, 2017

The main point for us is to get a different answer (status code) for being rate limited (429) then for providing an invalid token or credentials (401). Our clients now cannot see the difference.

We would prefer the X-Rate-Limit headers as we only have a single metric, but I understand it is not working for you developing a generic product. The Retry-After is applicable for 503 or 3xx responses, so it is not confirm specs, but I think it can be a good alternative for us.

@ErwinSteffens
Copy link
Author

Maybe you can provide an easy way for overriding this functionality so we can provide custom error handling. We provide clear descriptive error messages in our response body for other errors, so being able to override this with some custom code would be great.

@davidor
Copy link
Contributor

davidor commented Dec 5, 2017

@ErwinSteffens , the 'limits_exceeded' error is now configurable. By default it returns 429 instead of 403, so it can be distinguished from other kind of errors: #453

@davidor davidor added this to the 3.4 milestone Oct 4, 2018
@davidor
Copy link
Contributor

davidor commented Oct 5, 2018

For 3.4, we'll return a 'Retry-After' header when the request is rate-limited.

To implement that, we can use the information returned by Apisonator. However, there's a bug that we'll need to fix first: 3scale/apisonator#54

@davidor davidor self-assigned this Oct 9, 2018
@davidor
Copy link
Contributor

davidor commented Oct 11, 2018

Done in #453 and #929

@davidor davidor closed this as completed Oct 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants