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

Add support for X-RateLimit-* headers in ratelimit filter #12410

Merged
merged 30 commits into from
Aug 5, 2020

Conversation

Pchelolo
Copy link
Contributor

@Pchelolo Pchelolo commented Jul 31, 2020

Adds support for X-RateLimit-* headers described in the draft RFC. The X-RateLimit-Limit header contains the quota-policy per RFC. The descriptor name is included in the quota policy under the name key. X-RateLimit-Reset header is emitted, but it would need a followup in the ratelimit service, which I will do once this is merged.

Commit Message: Add support for X-RateLimit-* headers in ratelimit filter

Risk Level: Low, new codepaths are disabled by default

Testing: unit&integration tests created covering new features

Docs Changes: docs for the new config variable added

Release Notes: added to current.rst

Fixes #12356

Signed-off-by: Petr Pchelko ppchelko@wikimedia.org

@numerodix fyi

Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
@repokitteh-read-only
Copy link

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/envoy/.
CC @envoyproxy/api-watchers: FYI only for changes made to api/envoy/.

🐱

Caused by: #12410 was opened by Pchelolo.

see: more, trace.

@mattklein123 mattklein123 self-assigned this Jul 31, 2020
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
@Pchelolo Pchelolo requested a review from zuercher as a code owner July 31, 2020 21:40
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
@mattklein123
Copy link
Member

Please check CI, thank you!

/wait

Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool. Thanks for working on this. A few comments to get started.

/wait

Comment on lines 114 to 115
// Number of seconds until reset of the current limit window.
uint32 seconds_until_reset = 4;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about using a protobuf duration here? I think that would future proof it a bit better?

// The headers are specified in the `draft RFC
// <https://tools.ietf.org/id/draft-polli-ratelimit-headers-00.html>`_
// Defaults to false.
bool enable_response_headers = 8;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make the name of this field more specific? enable_x_ratelimit_headers or similar? It's a little unclear what this does from the field name.

@@ -64,4 +64,10 @@ message RateLimit {
// success.
config.ratelimit.v3.RateLimitServiceConfig rate_limit_service = 7
[(validate.rules).message = {required: true}];

// If set to true enables emitting X-RateLimit-* headers by the filter.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid having to read the RFC in all cases, can you spell out a bit more what headers are emitted and what they do?

Comment on lines 312 to 314
HEADER_FUNC(XRateLimitLimit) \
HEADER_FUNC(XRateLimitRemaining) \
HEADER_FUNC(XRateLimitReset)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be defined as custom inline headers for the ratelimit header vs. global inline headers. See RegisterCustomInlineHeader

response_headers_to_add_ = Http::ResponseHeaderMapImpl::create();
}
Http::HeaderUtility::addHeaders(*response_headers_to_add_, *rate_limit_headers);
rate_limit_headers = nullptr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this goes out of scope and it not necessary

Comment on lines 45 to 47
result->setXRateLimitLimit(rate_limit_limit);
result->setXRateLimitRemaining(min_remaining_limit_status.value().limit_remaining());
result->setXRateLimitReset(min_remaining_limit_status.value().seconds_until_reset());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI if these are just being set on an empty map, these don't need to be inline at all. Just directly use the various add* functions.


absl::optional<envoy::service::ratelimit::v3::RateLimitResponse_DescriptorStatus>
min_remaining_limit_status;
std::ostringstream quotaPolicy;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: quota_policy.

Also please avoid using ostringstream. Prefer the absl::String functions instead for this type of case.

}
uint32_t window = convertRateLimitUnit(status.current_limit().unit());
if (window) {
fmt::print(quotaPolicy, ", {:d};{:s}={:d}", status.current_limit().requests_per_unit(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you comment/reference the spec for what this is doing? It's not clear to the casual reader.

Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few more comments, thanks. Also looks like clang-tidy is still broken on the current main branch, not your fault. cc @lizan

/wait

api/envoy/service/ratelimit/v3/rls.proto Outdated Show resolved Hide resolved
@lizan
Copy link
Member

lizan commented Aug 4, 2020

tidy passes on my local with latest change, feel free to ignore while I'm investigating why it fails in AZP.

Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
@Pchelolo
Copy link
Contributor Author

Pchelolo commented Aug 4, 2020

tidy passes on my local with latest change, feel free to ignore while I'm investigating why it fails in AZP.

Thank you. Same here, I was banging my head over it and boiling my laptop running it locally :)

Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
mattklein123
mattklein123 previously approved these changes Aug 4, 2020
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@repokitteh-read-only repokitteh-read-only bot removed the api label Aug 4, 2020
Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
@repokitteh-read-only repokitteh-read-only bot removed the api label Aug 4, 2020
@mattklein123 mattklein123 merged commit 9f40563 into envoyproxy:master Aug 5, 2020
@unleashed
Copy link

Just a minor comment, since IIRC the diff is not going to be important for this PR, but version 03 of the draft was published about two months ago.

@Pchelolo
Copy link
Contributor Author

Pchelolo commented Aug 5, 2020

@unleashed oh! I guess we replace everything with v3 to start off from the latest. I'll make another PR.

mattklein123 pushed a commit that referenced this pull request Aug 5, 2020
Followup for a new feature introduced by #12410 Apologies for not noticing that a later draft was introduced recently. I think we should start with supporting the latest available spec draft, so update version 2 to version 3. The change is technically backwards-incompatible, but the new feature was introduced one day ago, nobody could have been so fast to depend on it.

Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
chaoqin-li1123 pushed a commit to chaoqin-li1123/envoy that referenced this pull request Aug 7, 2020
…#12410)

Adds support for X-RateLimit-* headers described in the draft RFC. The X-RateLimit-Limit header contains the quota-policy per RFC. The descriptor name is included in the quota policy under the name key. X-RateLimit-Reset header is emitted, but it would need a followup in the ratelimit service, which I will do once this is merged.

Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
chaoqin-li1123 pushed a commit to chaoqin-li1123/envoy that referenced this pull request Aug 7, 2020
Followup for a new feature introduced by envoyproxy#12410 Apologies for not noticing that a later draft was introduced recently. I think we should start with supporting the latest available spec draft, so update version 2 to version 3. The change is technically backwards-incompatible, but the new feature was introduced one day ago, nobody could have been so fast to depend on it.

Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
chaoqin-li1123 pushed a commit to chaoqin-li1123/envoy that referenced this pull request Aug 7, 2020
…#12410)

Adds support for X-RateLimit-* headers described in the draft RFC. The X-RateLimit-Limit header contains the quota-policy per RFC. The descriptor name is included in the quota policy under the name key. X-RateLimit-Reset header is emitted, but it would need a followup in the ratelimit service, which I will do once this is merged.

Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: chaoqinli <chaoqinli@google.com>
chaoqin-li1123 pushed a commit to chaoqin-li1123/envoy that referenced this pull request Aug 7, 2020
Followup for a new feature introduced by envoyproxy#12410 Apologies for not noticing that a later draft was introduced recently. I think we should start with supporting the latest available spec draft, so update version 2 to version 3. The change is technically backwards-incompatible, but the new feature was introduced one day ago, nobody could have been so fast to depend on it.

Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
Signed-off-by: chaoqinli <chaoqinli@google.com>
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

Successfully merging this pull request may close these issues.

Proposal: add support for x-ratelimit-* headers
5 participants