draft-ietf-httpapi-ratelimit-headers-09.unpg.txt | draft-ietf-httpapi-ratelimit-headers-latest.txt | |||
---|---|---|---|---|
HTTPAPI Working Group R. Polli | HTTPAPI Working Group R. Polli | |||
Internet-Draft Team Digitale, Italian Government | Internet-Draft Team Digitale, Italian Government | |||
Intended status: Standards Track A. Martinez | Intended status: Standards Track A. Martinez | |||
Expires: September 19, 2025 Red Hat | Expires: March 13, 2026 Red Hat | |||
D. Miller | D. Miller | |||
Microsoft | Microsoft | |||
March 18, 2025 | September 09, 2025 | |||
RateLimit header fields for HTTP | RateLimit header fields for HTTP | |||
draft-ietf-httpapi-ratelimit-headers-09 | draft-ietf-httpapi-ratelimit-headers-latest | |||
Abstract | Abstract | |||
This document defines the RateLimit-Policy and RateLimit HTTP header | This document defines the RateLimit-Policy and RateLimit HTTP header | |||
fields for servers to advertise their quota policies and the current | fields for servers to advertise their quota policies and the current | |||
service limits, thereby allowing clients to avoid being throttled. | service limits, thereby allowing clients to avoid being throttled. | |||
About This Document | About This Document | |||
This note is to be removed before publishing as an RFC. | This note is to be removed before publishing as an RFC. | |||
skipping to change at line 52 ¶ | skipping to change at page 2, line 7 ¶ | |||
Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
Drafts is at https://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
This Internet-Draft will expire on September 19, 2025. | This Internet-Draft will expire on March 13, 2026. | |||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2025 IETF Trust and the persons identified as the | Copyright (c) 2025 IETF Trust and the persons identified as the | |||
document authors. All rights reserved. | document authors. All rights reserved. | |||
This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
(https://trustee.ietf.org/license-info) in effect on the date of | (https://trustee.ietf.org/license-info) in effect on the date of | |||
publication of this document. Please review these documents | publication of this document. Please review these documents | |||
carefully, as they describe your rights and restrictions with respect | carefully, as they describe your rights and restrictions with respect | |||
to this document. Code Components extracted from this document must | to this document. Code Components extracted from this document must | |||
include Simplified BSD License text as described in Section 4.e of | include Simplified BSD License text as described in Section 4.e of | |||
the Trust Legal Provisions and are provided without warranty as | the Trust Legal Provisions and are provided without warranty as | |||
described in the Simplified BSD License. | described in the Simplified BSD License. | |||
Table of Contents | Table of Contents | |||
1. Introduction | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 | |||
1.1. Goals | 1.1. Goals . . . . . . . . . . . . . . . . . . . . . . . . . . 4 | |||
1.2. Notational Conventions | 1.2. Notational Conventions . . . . . . . . . . . . . . . . . 5 | |||
2. Terminology | 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 5 | |||
3. RateLimit-Policy Field | 3. RateLimit-Policy Field . . . . . . . . . . . . . . . . . . . 6 | |||
3.1. Quota Policy Item | 3.1. Quota Policy Item . . . . . . . . . . . . . . . . . . . . 6 | |||
3.1.1. Quota Parameter | 3.1.1. Quota Parameter . . . . . . . . . . . . . . . . . . . 7 | |||
3.1.2. Quota Unit Parameter | 3.1.2. Quota Unit Parameter . . . . . . . . . . . . . . . . 7 | |||
3.1.3. Window Parameter | 3.1.3. Window Parameter . . . . . . . . . . . . . . . . . . 7 | |||
3.1.4. Partition Key Parameter | 3.1.4. Partition Key Parameter . . . . . . . . . . . . . . . 8 | |||
3.2. RateLimit Policy Field Examples | 3.2. RateLimit Policy Field Examples . . . . . . . . . . . . . 8 | |||
4. RateLimit Field | 4. RateLimit Field . . . . . . . . . . . . . . . . . . . . . . . 8 | |||
4.1. Service Limit Item | 4.1. Service Limit Item . . . . . . . . . . . . . . . . . . . 9 | |||
4.1.1. Remaining Parameter | 4.1.1. Remaining Parameter . . . . . . . . . . . . . . . . . 9 | |||
4.1.2. Reset Parameter | 4.1.2. Reset Parameter . . . . . . . . . . . . . . . . . . . 9 | |||
4.1.3. Partition Key Parameter | 4.1.3. Partition Key Parameter . . . . . . . . . . . . . . . 10 | |||
4.2. RateLimit Field Examples | 4.2. RateLimit Field Examples . . . . . . . . . . . . . . . . 10 | |||
5. Server Behavior | 5. Problem Types . . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
5.1. Generating Partition Keys | 5.1. Quota Exceeded . . . . . . . . . . . . . . . . . . . . . 10 | |||
5.2. Performance Considerations | 5.2. Temporary Reduced Capacity . . . . . . . . . . . . . . . 11 | |||
6. Client Behavior | 5.3. Abnormal Usage Detected . . . . . . . . . . . . . . . . . 11 | |||
6.1. Consuming Partition Keys | 6. Server Behavior . . . . . . . . . . . . . . . . . . . . . . . 12 | |||
6.2. Intermediaries | 6.1. Generating Partition Keys . . . . . . . . . . . . . . . . 12 | |||
6.3. Caching | 6.2. Performance Considerations . . . . . . . . . . . . . . . 13 | |||
7. Security Considerations | 7. Client Behavior . . . . . . . . . . . . . . . . . . . . . . . 13 | |||
7.1. Throttling does not prevent clients from issuing requests | 7.1. Consuming Partition Keys . . . . . . . . . . . . . . . . 14 | |||
7.2. Information disclosure | 7.2. Intermediaries . . . . . . . . . . . . . . . . . . . . . 14 | |||
7.3. Remaining quota units are not granted requests | 7.3. Caching . . . . . . . . . . . . . . . . . . . . . . . . . 15 | |||
7.4. Reliability of the reset parameter | 8. Security Considerations . . . . . . . . . . . . . . . . . . . 15 | |||
7.5. Resource exhaustion | 8.1. Throttling does not prevent clients from issuing requests 15 | |||
7.5.1. Denial of Service | 8.2. Information disclosure . . . . . . . . . . . . . . . . . 15 | |||
8. Privacy Considerations | 8.3. Remaining quota units are not granted requests . . . . . 16 | |||
9. IANA Considerations | 8.4. Reliability of the reset parameter . . . . . . . . . . . 16 | |||
9.1. RateLimit quota unit registry | 8.5. Resource exhaustion . . . . . . . . . . . . . . . . . . . 16 | |||
9.1.1. Registration Template | 8.5.1. Denial of Service . . . . . . . . . . . . . . . . . . 17 | |||
10. References | 9. Privacy Considerations . . . . . . . . . . . . . . . . . . . 18 | |||
10.1. Normative References | 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 18 | |||
10.2. Informative References | 10.1. Update HTTP Field Name Registry . . . . . . . . . . . . 18 | |||
Appendix A. Rate-limiting and quotas | 10.2. Update HTTP Problem Type registry . . . . . . . . . . . 18 | |||
A.1. Interoperability issues | 10.2.1. Registration of "quota-exceeded" Problem Type . . . 18 | |||
Appendix B. Examples | 10.2.2. Registration of "temporary-reduced-capacity" Problem | |||
B.1. Responses without defining policies | Type . . . . . . . . . . . . . . . . . . . . . . . . 19 | |||
B.1.1. Throttling information in responses | 10.2.3. Registration of "abnormal-usage-detected" Problem | |||
B.1.2. Multiple policies in response | Type . . . . . . . . . . . . . . . . . . . . . . . . 19 | |||
B.1.3. Use for limiting concurrency | 10.3. RateLimit quota unit registry . . . . . . . . . . . . . 19 | |||
B.1.4. Use in throttled responses | 10.3.1. Registration Template . . . . . . . . . . . . . . . 20 | |||
B.2. Responses with defined policies | 11. References . . . . . . . . . . . . . . . . . . . . . . . . . 20 | |||
B.2.1. Throttling window specified via parameter | 11.1. Normative References . . . . . . . . . . . . . . . . . . 20 | |||
B.2.2. Dynamic limits with parameterized windows | 11.2. Informative References . . . . . . . . . . . . . . . . . 21 | |||
B.2.3. Dynamic limits for pushing back and slowing down | Appendix A. Rate-limiting and quotas . . . . . . . . . . . . . . 21 | |||
A.1. Interoperability issues . . . . . . . . . . . . . . . . . 22 | ||||
Appendix B. Examples . . . . . . . . . . . . . . . . . . . . . . 23 | ||||
B.1. Responses without defining policies . . . . . . . . . . . 23 | ||||
B.1.1. Throttling information in responses . . . . . . . . . 23 | ||||
B.1.2. Multiple policies in response . . . . . . . . . . . . 24 | ||||
B.1.3. Use for limiting concurrency . . . . . . . . . . . . 25 | ||||
B.1.4. Use in throttled responses . . . . . . . . . . . . . 26 | ||||
B.2. Responses with defined policies . . . . . . . . . . . . . 26 | ||||
B.2.1. Throttling window specified via parameter . . . . . . 26 | ||||
B.2.2. Dynamic limits with parameterized windows . . . . . . 27 | ||||
B.2.3. Dynamic limits for pushing back and slowing down . . 27 | ||||
B.3. Dynamic limits for pushing back with Retry-After and slow | B.3. Dynamic limits for pushing back with Retry-After and slow | |||
down | down . . . . . . . . . . . . . . . . . . . . . . . . . . 28 | |||
B.3.1. Missing Remaining information | B.3.1. Missing Remaining information . . . . . . . . . . . . 29 | |||
B.3.2. Use with multiple windows | B.3.2. Use with multiple windows . . . . . . . . . . . . . . 30 | |||
FAQ | FAQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 | |||
RateLimit header fields currently used on the web | RateLimit header fields currently used on the web . . . . . . . . 33 | |||
Acknowledgements | Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 34 | |||
Changes | Changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 | |||
F.1. Since draft-ietf-httpapi-ratelimit-headers-07 | F.1. Since draft-ietf-httpapi-ratelimit-headers-08 . . . . . . 35 | |||
F.2. Since draft-ietf-httpapi-ratelimit-headers-03 | F.2. Since draft-ietf-httpapi-ratelimit-headers-07 . . . . . . 35 | |||
F.3. Since draft-ietf-httpapi-ratelimit-headers-02 | F.3. Since draft-ietf-httpapi-ratelimit-headers-03 . . . . . . 35 | |||
F.4. Since draft-ietf-httpapi-ratelimit-headers-01 | F.4. Since draft-ietf-httpapi-ratelimit-headers-02 . . . . . . 35 | |||
F.5. Since draft-ietf-httpapi-ratelimit-headers-00 | F.5. Since draft-ietf-httpapi-ratelimit-headers-01 . . . . . . 35 | |||
Authors' Addresses | F.6. Since draft-ietf-httpapi-ratelimit-headers-00 . . . . . . 36 | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 36 | ||||
1. Introduction | 1. Introduction | |||
Rate limiting of HTTP clients has become a widespread practice, | Rate limiting of HTTP clients has become a widespread practice, | |||
especially for HTTP APIs. Typically, servers who do so limit the | especially for HTTP APIs. Typically, servers who do so limit the | |||
number of acceptable requests in a given time window (e.g. 10 | number of acceptable requests in a given time window (e.g. 10 | |||
requests per second). See Appendix A for further information on the | requests per second). See Appendix A for further information on the | |||
current usage of rate limiting in HTTP. | current usage of rate limiting in HTTP. | |||
Currently, there is no standard way for servers to communicate quotas | Currently, there is no standard way for servers to communicate quotas | |||
skipping to change at line 210 ¶ | skipping to change at page 5, line 33 ¶ | |||
BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all | BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all | |||
capitals, as shown here. | capitals, as shown here. | |||
The term Origin is to be interpreted as described in Section 7 of | The term Origin is to be interpreted as described in Section 7 of | |||
[WEB-ORIGIN]. | [WEB-ORIGIN]. | |||
This document uses the terms List, Item and Integer from Section 3 of | This document uses the terms List, Item and Integer from Section 3 of | |||
[STRUCTURED-FIELDS] to specify syntax and parsing, along with the | [STRUCTURED-FIELDS] to specify syntax and parsing, along with the | |||
concept of "bare item". | concept of "bare item". | |||
The term "problem type" in this document is to be interpreted as | ||||
described in [PROBLEM]. | ||||
2. Terminology | 2. Terminology | |||
Quota: A quota is an allocation of capacity used by a resource | Quota: A quota is an allocation of capacity used by a resource | |||
server to limit client requests. That capacity is measured in | server to limit client requests. That capacity is measured in | |||
quota units and may be reallocated at the end of a time window. | quota units and may be reallocated at the end of a time window. | |||
Quota Unit: A quota unit is the unit of measure used to measure the | Quota Unit: A quota unit is the unit of measurement used to measure | |||
activity of a client. | the activity of a client. | |||
Quota Partition: A quota partition is a division of a server's | Quota Partition: A quota partition is a division of a server's | |||
capacity across different clients, users and owned resources. | capacity across different clients, users and owned resources. | |||
Time Window: A time window indicates a period of time associated to | Time Window: A time window indicates a period of time associated to | |||
the allocated quota. | the allocated quota. | |||
Quota Policy: A quota policy is implemented by the server to | Quota Policy: A quota policy is implemented by the server to | |||
regulate the activity within a specified quota partition, | regulate the activity within a specified quota partition, | |||
quantified in quota units, over a defined time window. This | quantified in quota units, over a defined time window. This | |||
activity is restricted to a predefined limit, known as the quota. | activity is restricted to a predefined limit, known as the quota. | |||
Quota policies can be advertised by servers, but they are not | Quota policies can be advertised by servers, but they are not | |||
required to be, and more than one quota policy can affect a given | required to be, and more than one quota policy can affect a given | |||
request from a client to a server. | request from a client to a server. | |||
Service Limit: A service limit is the currently remaining quota from | Service Limit: A service limit is the currently remaining quota from | |||
a specific quota policy and, if defined, the remaining time before | a specific quota policy and, if defined, the remaining time before | |||
quota is reallocated. | quota is reallocated. | |||
List: A [STRUCTURED-FIELDS] list of Items | ||||
Item: A [STRUCTURED-FIELDS] item with a set of associated parameters | ||||
3. RateLimit-Policy Field | 3. RateLimit-Policy Field | |||
The "RateLimit-Policy" response header field is a non-empty List of | The "RateLimit-Policy" response header field is a non-empty | |||
Quota Policy Items (Section 3.1). The Item value MUST be a String. | List[RFC9651] of Quota Policy Items (Section 3.1). The Item[RFC9651] | |||
Its value is informative. The field value is expected to remain | value MUST be a String[RFC9651]. | |||
consistent over a the lifetime of a connection. It is this | ||||
characteristic that differentiates it from the RateLimit (Section 4) | The field value SHOULD remain consistent over a sequence of HTTP | |||
field that contains information that may change on every request. | responses. It is this characteristic that differentiates it from the | |||
RateLimit (Section 4) field that contains information that MAY change | ||||
on every request. The "RateLimit-Policy" field enables clients to | ||||
control their own flow of requests based on policy information | ||||
provided by the server. Situations where throttling constraints are | ||||
highly dynamic are better served using the (RateLimit | ||||
field)[{#ratelimit-field}] that communicates the latest service | ||||
information a client can react to. Both fields can be communicated | ||||
by the server when appropriate. | ||||
Lists of Quota Policy Items (Section 3.1) can be split over multiple | ||||
"RateLimit-Policy" fields in the same HTTP response as described in | ||||
Section 3.1 of [STRUCTURED-FIELDS]. | ||||
RateLimit-Policy: "burst";q=100;w=60,"daily";q=1000;w=86400 | RateLimit-Policy: "burst";q=100;w=60,"daily";q=1000;w=86400 | |||
3.1. Quota Policy Item | 3.1. Quota Policy Item | |||
A quota policy Item contains an identifier for the policy and a set | A quota policy Item contains an identifier for the policy and a set | |||
of parameters that contain information about a server's capacity | of Parameters[RFC9651] that contain information about a server's | |||
allocation for the policy. | capacity allocation for the policy. | |||
The following parameters are defined: | The following parameters are defined: | |||
q: The REQUIRED "q" parameter indicates the quota allocated by this | q: The REQUIRED "q" parameter indicates the quota allocated by this | |||
policy measured in quota units. | policy measured in quota units. | |||
qu: The OPTIONAL "qu" parameter value conveys the quota units | qu: The OPTIONAL "qu" parameter value conveys the quota units | |||
associated to the "q" parameter. The default quota unit is | associated to the "q" parameter. The default quota unit is | |||
"requests". | "requests". | |||
skipping to change at line 274 ¶ | skipping to change at page 7, line 23 ¶ | |||
pk: The OPTIONAL "pk" parameter value conveys the partition key | pk: The OPTIONAL "pk" parameter value conveys the partition key | |||
associated to the corresponding request. | associated to the corresponding request. | |||
Other parameters are allowed and can be regarded as comments. | Other parameters are allowed and can be regarded as comments. | |||
Implementation- or service-specific parameters SHOULD be prefixed | Implementation- or service-specific parameters SHOULD be prefixed | |||
parameters with a vendor identifier, e.g. "acme-policy", "acme- | parameters with a vendor identifier, e.g. "acme-policy", "acme- | |||
burst". | burst". | |||
This field MUST NOT appear in a trailer section. | ||||
3.1.1. Quota Parameter | 3.1.1. Quota Parameter | |||
The "q" parameter value MUST be a non-negative Integer. The value | The "q" parameter value MUST be a non-negative Integer. The value | |||
indicates the quota allocated for client activity (measured in quota | indicates the quota allocated for client activity (measured in quota | |||
units) for a given quota partition. | units) for a given quota partition. | |||
3.1.2. Quota Unit Parameter | 3.1.2. Quota Unit Parameter | |||
The "qu" parameter value conveys the quota units applicable to the | The "qu" parameter value conveys the quota units applicable to the | |||
quota (Section 3.1.1). The value MUST be a String. Allowed values | quota (Section 3.1.1). The value MUST be a String. Allowed values | |||
are listed in the RateLimit Quota Units registry (Section 9.1). This | are listed in the RateLimit Quota Units registry (Section 10.3). | |||
specification defines three quota units: | This specification defines three quota units: | |||
requests: This value indicates the quota is based on the number of | requests: This value indicates the quota is based on the number of | |||
requests processed by the resource server. Whether a specific | requests processed by the resource server. Whether a specific | |||
request actually consumes a quota unit is implementation-specific. | request actually consumes a quota unit is implementation-specific. | |||
content-bytes: This value indicates the quota is based on the number | content-bytes: This value indicates the quota is based on the number | |||
of content bytes processed by the resource server. | of content bytes processed by the resource server. | |||
concurrent-requests: This value indicates the quota is based on the | concurrent-requests: This value indicates the quota is based on the | |||
number of concurrent requests processed by the resource server. | number of concurrent requests processed by the resource server. | |||
3.1.3. Window Parameter | 3.1.3. Window Parameter | |||
The "w" parameter value conveys a time window applicable to the quota | The "w" parameter value conveys a time window applicable to the quota | |||
(Section 3.1.1). The time window MUST be a non-negative Integer | (Section 3.1.1). The time window MUST be a non-negative, non-zero, | |||
value expressing an interval in seconds, similar to the "delay- | Integer value expressing an interval in seconds, similar to the | |||
seconds" rule defined in Section 10.2.3 of [HTTP]. Sub-second | "delay-seconds" rule defined in Section 10.2.3 of [HTTP]. Sub-second | |||
precision is not supported. | precision is not supported. | |||
3.1.4. Partition Key Parameter | 3.1.4. Partition Key Parameter | |||
The "pk" parameter value conveys the partition key associated to the | The "pk" parameter value conveys the partition key associated to the | |||
request. The value MUST be a Byte Sequence. Servers MAY use the | request. The value MUST be a Byte Sequence. Servers MAY use the | |||
partition key to divide server capacity across different clients and | partition key to divide server capacity across different clients and | |||
resources. Quotas are allocated per partition key. | resources. Quotas are allocated per partition key. | |||
3.2. RateLimit Policy Field Examples | 3.2. RateLimit Policy Field Examples | |||
skipping to change at line 330 ¶ | skipping to change at page 8, line 32 ¶ | |||
RateLimit-Policy: "permin";q=50;w=60,"perhr";q=1000;w=3600 | RateLimit-Policy: "permin";q=50;w=60,"perhr";q=1000;w=3600 | |||
The following example shows a policy with a partition key: | The following example shows a policy with a partition key: | |||
RateLimit-Policy: "peruser";q=100;w=60;pk=:cHsdsRa894==: | RateLimit-Policy: "peruser";q=100;w=60;pk=:cHsdsRa894==: | |||
The following example shows a policy with a partition key and a quota | The following example shows a policy with a partition key and a quota | |||
unit: | unit: | |||
RateLimit-Policy: "peruser";q=65535;qu="bytes";w=10;pk=:sdfjLJUOUH==: | RateLimit-Policy: "peruser";q=65535;qu="content-bytes";w=10;pk=:sdfjLJUOUH==: | |||
This field cannot appear in a trailer section. | ||||
4. RateLimit Field | 4. RateLimit Field | |||
A server uses the "RateLimit" response header field to communicate | A server uses the "RateLimit" response header field to communicate | |||
the service limit for a quota policy for a particular partition key. | the current service limit for a quota policy for a particular | |||
partition key. | ||||
The field is expressed as List of Service Limit Items (Section 4.1). | The field is expressed as a List[RFC9651] of Service Limit Items | |||
(Section 4.1). | ||||
Lists of Service Limit Items can be split over multiple "RateLimit" | ||||
fields in the same HTTP response as described in Section 3.1 of | ||||
[STRUCTURED-FIELDS]. | ||||
RateLimit: "default";r=50;t=30 | RateLimit: "default";r=50;t=30 | |||
4.1. Service Limit Item | 4.1. Service Limit Item | |||
Each service limit Item identifies the quota policy (Section 3.1) | Each service limit Item[RFC9651] identifies the quota policy | |||
associated with the request and contains parameters with information | (Section 3.1) associated with the request and contains | |||
about the current service limit. | Parameters[RFC9651] with information about the current service limit. | |||
The following parameters are defined in this specification: | The following parameters are defined in this specification: | |||
r: This parameter value conveys the remaining quota units for the | r: This REQUIRED parameter value conveys the remaining quota units | |||
identified policy (Section 4.1.1). | for the identified policy (Section 4.1.1). | |||
t: This OPTIONAL parameter value conveys the time window reset time | t: This OPTIONAL parameter value conveys the time window reset time | |||
for the identified policy (Section 4.1.2). | for the identified policy (Section 4.1.2). | |||
pk: The OPTIONAL "pk" parameter value conveys the partition key | pk: The OPTIONAL "pk" parameter value conveys the partition key | |||
associated to the corresponding request. | associated to the corresponding request. | |||
This field cannot appear in a trailer section. Other parameters are | This field cannot appear in a trailer section. Other parameters are | |||
allowed and can be regarded as comments. | allowed and can be regarded as comments. | |||
skipping to change at line 374 ¶ | skipping to change at page 9, line 36 ¶ | |||
parameters with a vendor identifier, e.g. "acme-policy", "acme- | parameters with a vendor identifier, e.g. "acme-policy", "acme- | |||
burst". | burst". | |||
4.1.1. Remaining Parameter | 4.1.1. Remaining Parameter | |||
The "r" parameter indicates the remaining quota units for the | The "r" parameter indicates the remaining quota units for the | |||
identified policy (Section 4.1.1). | identified policy (Section 4.1.1). | |||
It is a non-negative Integer expressed in quota units. Clients MUST | It is a non-negative Integer expressed in quota units. Clients MUST | |||
NOT assume that a positive remaining value is a guarantee that | NOT assume that a positive remaining value is a guarantee that | |||
further requests will be served. When remaining parameter value is | further requests will be served. When the remaining parameter value | |||
low, it indicates that the server may soon throttle the client (see | is low, it indicates that the server may soon throttle the client | |||
Section 5). | (see Section 6). | |||
4.1.2. Reset Parameter | 4.1.2. Reset Parameter | |||
The "t" parameter indicates the number of seconds until the quota | The "t" parameter indicates the number of seconds until the quota | |||
associated with the quota policy resets. | associated with the quota policy resets. | |||
It is a non-negative Integer compatible with the delay-seconds rule, | It is a non-negative Integer compatible with the delay-seconds rule, | |||
because: | because: | |||
o it does not rely on clock synchronization and is resilient to | o it does not rely on clock synchronization and is resilient to | |||
skipping to change at line 423 ¶ | skipping to change at page 10, line 38 ¶ | |||
This example shows a remaining quota of 999 requests for a partition | This example shows a remaining quota of 999 requests for a partition | |||
key that has no time window reset: | key that has no time window reset: | |||
RateLimit: "default";r=999;pk=:dHJpYWwxMjEzMjM=: | RateLimit: "default";r=999;pk=:dHJpYWwxMjEzMjM=: | |||
This example shows a 300MB remaining quota for an application in the | This example shows a 300MB remaining quota for an application in the | |||
next 60 seconds: | next 60 seconds: | |||
RateLimit: "default";r=300000000;t=60;pk=:QXBwLTk5OQ==: | RateLimit: "default";r=300000000;t=60;pk=:QXBwLTk5OQ==: | |||
5. Server Behavior | 5. Problem Types | |||
5.1. Quota Exceeded | ||||
This section defines the "https://iana.org/assignments/http-problem- | ||||
types#quota-exceeded" problem type. A server MAY use this problem | ||||
type if it wants to communicate to the client that the requests sent | ||||
by the client exceed one or more Quota Policies. This problem type | ||||
defines the extension member "violated-policies" as an array of | ||||
strings, whose value is the names of policies where the quota was | ||||
exceeded. | ||||
HTTP/1.1 429 Bad Request | ||||
Content-Type: application/problem+json | ||||
{ | ||||
"type": "https://iana.org/assignments/http-problem-types#quota-exceeded", | ||||
"title": "Request cannot be satisifed as assigned quota has been exceeded", | ||||
"violated-policies": ["daily","bandwidth"] | ||||
} | ||||
5.2. Temporary Reduced Capacity | ||||
This section defines the "https://iana.org/assignments/http-problem- | ||||
types#temporary-reduced-capacity" problem type. A server MAY use | ||||
this problem type if it wants to communicate to the client that the | ||||
requests sent by the client exceed cannot currently be satisfied due | ||||
to a temporary reduction in capacity due to service limitations. The | ||||
server MAY chose to include a RateLimit-Policy field indicating the | ||||
new temporarily lower quota. This problem type defines the extension | ||||
member "violated-policies" as an array of strings, whose value is the | ||||
names of policies where the quota was exceeded. | ||||
HTTP/1.1 503 Server Unavailable | ||||
Content-Type: application/problem+json | ||||
{ | ||||
"type": "https://iana.org/assignments/http-problem-types#temporary-reduced-capacity", | ||||
"title": "Request cannot be satisifed due to temporary server capacity constraints", | ||||
"violated-policies": ["hourly"] | ||||
} | ||||
5.3. Abnormal Usage Detected | ||||
This section defines the "https://iana.org/assignments/http-problem- | ||||
types#abnormal-usage-detected" problem type. A server MAY use this | ||||
problem type to communicate to the client that it has detected a | ||||
pattern of requests that suggest unintentional or malicous behaviour | ||||
on the part of the client. This problem type defines the extension | ||||
member "violated-policies" as an array of strings, whose value is the | ||||
names of policies where the quota was exceeded. | ||||
HTTP/1.1 429 Too Many Requests | ||||
Content-Type: application/problem+json | ||||
{ | ||||
"type": "https://iana.org/assignments/http-problem-types#abnormal-usage-detected", | ||||
"title": "Request not satisifed due to detection of abnormal request pattern", | ||||
"violated-policies": ["hourly"] | ||||
} | ||||
6. Server Behavior | ||||
A server MAY return RateLimit header fields independently of the | A server MAY return RateLimit header fields independently of the | |||
response status code. This includes on throttled responses. This | response status code. This includes throttled responses. This | |||
document does not mandate any correlation between the RateLimit | document does not mandate any correlation between the RateLimit | |||
header field values and the returned status code. | header field values and the returned status code. | |||
Servers should be careful when returning RateLimit header fields in | Servers should be careful when returning RateLimit header fields in | |||
redirection responses (i.e., responses with 3xx status codes) because | redirection responses (i.e., responses with 3xx status codes) because | |||
a low remaining parameter value could prevent the client from issuing | a low remaining parameter value could prevent the client from issuing | |||
requests. For example, given the RateLimit header fields below, a | requests. For example, given the RateLimit header fields below, a | |||
client could decide to wait 10 seconds before following the | client could decide to wait 10 seconds before following the | |||
"Location" header field (see Section 10.2.2 of [HTTP]), because the | "Location" header field (see Section 10.2.2 of [HTTP]), because the | |||
remaining parameter value is 0. | remaining parameter value is 0. | |||
skipping to change at line 449 ¶ | skipping to change at page 12, line 30 ¶ | |||
Location: /foo/123 | Location: /foo/123 | |||
RateLimit: "problemPolicy";r=0;t=10 | RateLimit: "problemPolicy";r=0;t=10 | |||
If a response contains both the Retry-After and the RateLimit header | If a response contains both the Retry-After and the RateLimit header | |||
fields, the reset parameter value SHOULD reference the same point in | fields, the reset parameter value SHOULD reference the same point in | |||
time as the Retry-After field value. | time as the Retry-After field value. | |||
A service using RateLimit header fields MUST NOT convey values | A service using RateLimit header fields MUST NOT convey values | |||
exposing an unwanted volume of requests and SHOULD implement | exposing an unwanted volume of requests and SHOULD implement | |||
mechanisms to cap the ratio between the remaining and the reset | mechanisms to cap the ratio between the remaining and the reset | |||
parameter values (see Section 7.5); this is especially important when | parameter values (see Section 8.5); this is especially important when | |||
a quota policy uses a large time window. | a quota policy uses a large time window. | |||
Under certain conditions, a server MAY artificially lower RateLimit | Under certain conditions, a server MAY artificially lower RateLimit | |||
header field values between subsequent requests, e.g. to respond to | header field values between subsequent requests, e.g. to respond to | |||
Denial of Service attacks or in case of resource saturation. | Denial of Service attacks or in case of resource saturation. | |||
5.1. Generating Partition Keys | 6.1. Generating Partition Keys | |||
Servers MAY choose to return partition keys that distinguish between | Servers MAY choose to return partition keys that distinguish between | |||
quota allocated to different consumers or different resources. There | quota allocated to different consumers or different resources. There | |||
are a wide range of strategies for partitioning server capacity, | are a wide range of strategies for partitioning server capacity, | |||
including per user, per application, per HTTP method, per resource, | including per user, per application, per HTTP method, per resource, | |||
or some combination of those values. The server SHOULD document how | or some combination of those values. The server SHOULD document how | |||
the partition key is generated so that clients can predict the key | the partition key is generated so that clients can predict the key | |||
value for a future request and determine if there is sufficient quota | value for a future request and determine if there is sufficient quota | |||
remaining to execute the request. Servers should avoid returning | remaining to execute the request. Servers should avoid returning | |||
partition keys that contain sensitive information. Servers SHOULD | partition keys that contain sensitive information. Servers SHOULD | |||
only use information that is present in the request to generate the | only use information that is present in the request to generate the | |||
partition key. | partition key. | |||
5.2. Performance Considerations | 6.2. Performance Considerations | |||
Servers are not required to return RateLimit header fields in every | Servers are not required to return RateLimit header fields in every | |||
response, and clients need to take this into account. For example, | response, and clients need to take this into account. For example, | |||
an implementer concerned with performance might provide RateLimit | an implementer concerned with performance might provide RateLimit | |||
header fields only when a given quota is close to exhaustion. | header fields only when a given quota is close to exhaustion. | |||
Implementers concerned with response fields' size, might take into | Implementers concerned with response fields' size, might take into | |||
account their ratio with respect to the content length, or use | account their ratio with respect to the content length, or use | |||
header-compression HTTP features such as [HPACK]. | header-compression HTTP features such as [HPACK]. | |||
6. Client Behavior | 7. Client Behavior | |||
The RateLimit header fields can be used by clients to determine | The RateLimit header fields can be used by clients to determine | |||
whether the associated request respected the server's quota policy, | whether the associated request respected the server's quota policy, | |||
and as an indication of whether subsequent requests will. However, | and as an indication of whether subsequent requests will. However, | |||
the server might apply other criteria when servicing future requests, | the server might apply other criteria when servicing future requests, | |||
and so the quota policy may not completely reflect whether requests | and so the quota policy may not completely reflect whether requests | |||
will succeed. | will succeed. | |||
For example, a successful response with the following fields: | For example, a successful response with the following fields: | |||
RateLimit: "default";r=1;t=7 | RateLimit: "default";r=1;t=7 | |||
does not guarantee that the next request will be successful. | does not guarantee that the next request will be successful. | |||
Servers' behavior may be subject to other conditions. | Servers' behavior may be subject to other conditions. | |||
A client is responsible for ensuring that RateLimit header field | A client is responsible for ensuring that RateLimit header field | |||
values returned cause reasonable client behavior with respect to | values returned cause reasonable client behavior with respect to | |||
throughput and latency (see Section 7.5 and Section 7.5.1). | throughput and latency (see Section 8.5 and Section 8.5.1). | |||
A client receiving RateLimit header fields MUST NOT assume that | A client receiving RateLimit header fields MUST NOT assume that | |||
future responses will contain the same RateLimit header fields, or | future responses will contain the same RateLimit header fields, or | |||
any RateLimit header fields at all. | any RateLimit header fields at all. | |||
Malformed RateLimit header fields MUST be ignored. | Malformed RateLimit header fields MUST be ignored. | |||
A client SHOULD NOT exceed the quota units conveyed by the remaining | A client SHOULD NOT exceed the quota units conveyed by the remaining | |||
parameter before the time window expressed in the reset parameter. | parameter before the time window expressed in the reset parameter. | |||
skipping to change at line 532 ¶ | skipping to change at page 14, line 18 ¶ | |||
This specification does not mandate a specific throttling behavior | This specification does not mandate a specific throttling behavior | |||
and implementers can adopt their preferred policies, including: | and implementers can adopt their preferred policies, including: | |||
o slowing down or pre-emptively back-off their request rate when | o slowing down or pre-emptively back-off their request rate when | |||
approaching quota limits; | approaching quota limits; | |||
o consuming all the quota according to the exposed limits and then | o consuming all the quota according to the exposed limits and then | |||
wait. | wait. | |||
6.1. Consuming Partition Keys | 7.1. Consuming Partition Keys | |||
Partition keys are useful for a client if it is likely that single | Partition keys are useful for a client if it is likely that single | |||
client will make requests that consume different quota allocations. | client will make requests that consume different quota allocations. | |||
E.g. a client making requests on behalf of different users or for | E.g. a client making requests on behalf of different users or for | |||
different resources that have independent quota allocations. | different resources that have independent quota allocations. | |||
If a server documents the partition key generation algorithm, clients | If a server documents the partition key generation algorithm, clients | |||
MAY generate a partition key for a future request. Using this key, | MAY generate a partition key for a future request. Using this key, | |||
and comparing to the key returned by the server, the client can | and comparing to the key returned by the server, the client can | |||
determine if there is sufficient quota remaining to execute the | determine if there is sufficient quota remaining to execute the | |||
request. | request. | |||
For cases where the partition key generation algorithm of a server is | For cases where the partition key generation algorithm of a server is | |||
unknown, clients MAY use heuristics to guess if a future request will | unknown, clients MAY use heuristics to guess if a future request will | |||
be successful based on its similarity to previous requests. | be successful based on its similarity to previous requests. | |||
6.2. Intermediaries | 7.2. Intermediaries | |||
This section documents the considerations advised in Section 16.3.2 | This section documents the considerations advised in Section 16.3.2 | |||
of [HTTP]. | of [HTTP]. | |||
An intermediary that is not part of the originating service | An intermediary that is not part of the originating service | |||
infrastructure and is not aware of the quota policy semantic used by | infrastructure and is not aware of the quota policy semantic used by | |||
the Origin Server SHOULD NOT alter the RateLimit header fields' | the Origin Server SHOULD NOT alter the RateLimit header fields' | |||
values in such a way as to communicate a more permissive quota | values in such a way as to communicate a more permissive quota | |||
policy; this includes removing the RateLimit header fields. | policy; this includes removing the RateLimit header fields. | |||
skipping to change at line 579 ¶ | skipping to change at page 15, line 16 ¶ | |||
might not be serviced; the service returning the RateLimit header | might not be serviced; the service returning the RateLimit header | |||
fields is the sole responsible of enforcing the communicated quota | fields is the sole responsible of enforcing the communicated quota | |||
policy, and it is always free to service incoming requests. | policy, and it is always free to service incoming requests. | |||
This specification does not mandate any behavior on intermediaries | This specification does not mandate any behavior on intermediaries | |||
respect to retries, nor requires that intermediaries have any role in | respect to retries, nor requires that intermediaries have any role in | |||
respecting quota policies. For example, it is legitimate for a proxy | respecting quota policies. For example, it is legitimate for a proxy | |||
to retransmit a request without notifying the client, and thus | to retransmit a request without notifying the client, and thus | |||
consuming quota units. | consuming quota units. | |||
Privacy considerations (Section 8) provide further guidance on | Privacy considerations (Section 9) provide further guidance on | |||
intermediaries. | intermediaries. | |||
6.3. Caching | 7.3. Caching | |||
[HTTP-CACHING] defines how responses can be stored and reused for | [HTTP-CACHING] defines how responses can be stored and reused for | |||
subsequent requests, including those with RateLimit header fields. | subsequent requests, including those with RateLimit header fields. | |||
Because the information in RateLimit header fields on a cached | Because the information in RateLimit header fields on a cached | |||
response may not be current, they SHOULD be ignored on responses that | response may not be current, they SHOULD be ignored on responses that | |||
come from cache (i.e., those with a positive current_age; see | come from cache (i.e., those with a positive current_age; see | |||
Section 4.2.3 of [HTTP-CACHING]). | Section 4.2.3 of [HTTP-CACHING]). | |||
7. Security Considerations | 8. Security Considerations | |||
7.1. Throttling does not prevent clients from issuing requests | 8.1. Throttling does not prevent clients from issuing requests | |||
This specification does not prevent clients from making requests. | This specification does not prevent clients from making requests. | |||
Servers should always implement mechanisms to prevent resource | Servers should always implement mechanisms to prevent resource | |||
exhaustion. | exhaustion. | |||
7.2. Information disclosure | 8.2. Information disclosure | |||
Servers should not disclose to untrusted parties operational capacity | Servers should not disclose to untrusted parties operational capacity | |||
information that can be used to saturate its infrastructural | information that can be used to saturate its infrastructural | |||
resources. | resources. | |||
While this specification does not mandate whether non-successful | While this specification does not mandate whether non-successful | |||
responses consume quota, if error responses (such as 401 | responses consume quota, if error responses (such as 401 | |||
(Unauthorized) and 403 (Forbidden)) count against quota, a malicious | (Unauthorized) and 403 (Forbidden)) count against quota, a malicious | |||
client could probe the endpoint to get traffic information of another | client could probe the endpoint to get traffic information of another | |||
user. | user. | |||
As intermediaries might retransmit requests and consume quota units | As intermediaries might retransmit requests and consume quota units | |||
without prior knowledge of the user agent, RateLimit header fields | without prior knowledge of the user agent, RateLimit header fields | |||
might reveal the existence of an intermediary to the user agent. | might reveal the existence of an intermediary to the user agent. | |||
Where partition keys contain identifying information, either of the | Where partition keys contain identifying information, either of the | |||
client application or the user, servers should be aware of the | client application or the user, servers should be aware of the | |||
potential for impersonation and apply the appropriate security | potential for impersonation and apply the appropriate security | |||
mechanisms. | mechanisms. | |||
7.3. Remaining quota units are not granted requests | 8.3. Remaining quota units are not granted requests | |||
RateLimit header fields convey hints from the server to the clients | RateLimit header fields convey hints from the server to the clients | |||
in order to help them avoid being throttled out. | in order to help them avoid being throttled out. | |||
Clients MUST NOT consider the quota returned in the remaining | Clients MUST NOT consider the quota returned in the remaining | |||
parameter (Section 4.1.1) as a service level agreement. | parameter (Section 4.1.1) as a service level agreement. | |||
In case of resource saturation, the server MAY artificially lower the | In case of resource saturation, the server MAY artificially lower the | |||
returned values or not serve the request regardless of the advertised | returned values or not serve the request regardless of the advertised | |||
quotas. | quotas. | |||
7.4. Reliability of the reset parameter | 8.4. Reliability of the reset parameter | |||
Consider that quota might not be restored after the moment referenced | Consider that quota might not be restored after the moment referenced | |||
by the reset parameter (Section 4.1.2), and the reset parameter value | by the reset parameter (Section 4.1.2), and the reset parameter value | |||
may not be constant. | may not be constant. | |||
Subsequent requests might return a higher reset parameter value to | Subsequent requests might return a higher reset parameter value to | |||
limit concurrency or implement dynamic or adaptive throttling | limit concurrency or implement dynamic or adaptive throttling | |||
policies. | policies. | |||
7.5. Resource exhaustion | 8.5. Resource exhaustion | |||
When returning reset values, servers must be aware that many | When returning reset values, servers must be aware that many | |||
throttled clients may come back at the very moment specified. | throttled clients may come back at the very moment specified. | |||
This is true for Retry-After too. | This is true for Retry-After too. | |||
For example, if the quota resets every day at "18:00:00" and your | For example, if the quota resets every day at "18:00:00" and your | |||
server returns the reset parameter accordingly | server returns the reset parameter accordingly | |||
Date: Tue, 15 Nov 1994 18:00:00 GMT | Date: Tue, 15 Nov 1994 18:00:00 GMT | |||
skipping to change at line 677 ¶ | skipping to change at page 17, line 19 ¶ | |||
quota policy of 10000 quota units per 1000 seconds. | quota policy of 10000 quota units per 1000 seconds. | |||
RateLimit-Policy: "somepolicy";q=10000;w=1000 | RateLimit-Policy: "somepolicy";q=10000;w=1000 | |||
RateLimit: "somepolicy";r=10000;t=10 | RateLimit: "somepolicy";r=10000;t=10 | |||
A client implementing a simple ratio between remaining parameter and | A client implementing a simple ratio between remaining parameter and | |||
reset parameter could infer an average throughput of 1000 quota units | reset parameter could infer an average throughput of 1000 quota units | |||
per second, while the quota parameter conveys a quota-policy with an | per second, while the quota parameter conveys a quota-policy with an | |||
average of 10 quota units per second. If the service cannot handle | average of 10 quota units per second. If the service cannot handle | |||
such load, it should return either a lower remaining parameter value | such load, it should return either a lower remaining parameter value | |||
or an higher reset parameter value. Moreover, complementing large | or a higher reset parameter value. Moreover, complementing large | |||
time window quota policies with a short time window one mitigates | time window quota policies with a short time window one mitigates | |||
those risks. | those risks. | |||
7.5.1. Denial of Service | 8.5.1. Denial of Service | |||
RateLimit header fields may contain unexpected values by chance or on | RateLimit header fields may contain unexpected values by chance or on | |||
purpose. For example, an excessively high remaining parameter value | purpose. For example, an excessively high remaining parameter value | |||
may be: | may be: | |||
o used by a malicious intermediary to trigger a Denial of Service | o used by a malicious intermediary to trigger a Denial of Service | |||
attack or consume client resources boosting its requests; | attack or consume client resources boosting its requests; | |||
o passed by a misconfigured server; | o passed by a misconfigured server; | |||
skipping to change at line 706 ¶ | skipping to change at page 18, line 5 ¶ | |||
reasonable in terms of quota units, time window, concurrent requests | reasonable in terms of quota units, time window, concurrent requests | |||
or throughput, and define a consistent behavior when the RateLimit | or throughput, and define a consistent behavior when the RateLimit | |||
exceed those thresholds. For example this means capping the maximum | exceed those thresholds. For example this means capping the maximum | |||
number of request per second, or implementing retries when the reset | number of request per second, or implementing retries when the reset | |||
parameter exceeds ten minutes. | parameter exceeds ten minutes. | |||
The considerations above are not limited to RateLimit header fields, | The considerations above are not limited to RateLimit header fields, | |||
but apply to all fields affecting how clients behave in subsequent | but apply to all fields affecting how clients behave in subsequent | |||
requests (e.g. Retry-After). | requests (e.g. Retry-After). | |||
8. Privacy Considerations | 9. Privacy Considerations | |||
Clients that act upon a request to rate limit are potentially re- | Clients that act upon a request to rate limit are potentially re- | |||
identifiable (see Section 5.2.1 of [PRIVACY]) because they react to | identifiable (see Section 5.2.1 of [PRIVACY]) because they react to | |||
information that might only be given to them. Note that this might | information that might only be given to them. Note that this might | |||
apply to other fields too (e.g. Retry-After). | apply to other fields too (e.g. Retry-After). | |||
Since rate limiting is usually implemented in contexts where clients | Since rate limiting is usually implemented in contexts where clients | |||
are either identified or profiled (e.g. assigning different quota | are either identified or profiled (e.g. assigning different quota | |||
units to different users), this is rarely a concern. | units to different users), this is rarely a concern. | |||
Privacy enhancing infrastructures using RateLimit header fields can | Privacy enhancing infrastructures using RateLimit header fields can | |||
define specific techniques to mitigate the risks of re- | define specific techniques to mitigate the risks of re- | |||
identification. | identification. | |||
9. IANA Considerations | 10. IANA Considerations | |||
IANA is requested to update one registry and create one new registry. | IANA is requested to update two registries and create one new | |||
registry. | ||||
10.1. Update HTTP Field Name Registry | ||||
Please add the following entries to the "Hypertext Transfer Protocol | Please add the following entries to the "Hypertext Transfer Protocol | |||
(HTTP) Field Name Registry" registry ([HTTP]): | (HTTP) Field Name Registry" registry ([HTTP]): | |||
+------------------+-----------+-----------------------+ | +------------------+---------------+-----------+--------------------+ | |||
| Field Name | Status | Specification | | | Field Name | Structured | Status | Specification | | |||
+------------------+-----------+-----------------------+ | | | Type | | | | |||
| RateLimit | permanent | Section 4 of RFC nnnn | | +------------------+---------------+-----------+--------------------+ | |||
| RateLimit-Policy | permanent | Section 3 of RFC nnnn | | | RateLimit | List | permanent | Section 4 of RFC | | |||
+------------------+-----------+-----------------------+ | | | | | nnnn | | |||
| RateLimit-Policy | List | permanent | Section 3 of RFC | | ||||
| | | | nnnn | | ||||
+------------------+---------------+-----------+--------------------+ | ||||
9.1. RateLimit quota unit registry | 10.2. Update HTTP Problem Type registry | |||
IANA is asked to register the following entries in the "HTTP Problem | ||||
Types" registry at https://www.iana.org/assignments/http-problem- | ||||
types. | ||||
10.2.1. Registration of "quota-exceeded" Problem Type | ||||
Type URI: https://iana.org/assignments/http-problem-types#quota- | ||||
exceeded | ||||
Title: Quota Exceeded | ||||
Recommended HTTP status code: 429 | ||||
Reference: Section 5.1 of this document | ||||
10.2.2. Registration of "temporary-reduced-capacity" Problem Type | ||||
Type URI: https://iana.org/assignments/http-problem-types#temporary- | ||||
reduced-capacity | ||||
Title: Temporary Reduced Capacity | ||||
Recommended HTTP status code: 503 | ||||
Reference: Section 5.2 of this document | ||||
10.2.3. Registration of "abnormal-usage-detected" Problem Type | ||||
Type URI: https://iana.org/assignments/http-problem-types#abnormal- | ||||
usage-detected | ||||
Title: Abnormal Usage Detected | ||||
Recommended HTTP status code: 429 | ||||
Reference: Section 5.3 of this document | ||||
10.3. RateLimit quota unit registry | ||||
This specification establishes the registry "Hypertext Transfer | This specification establishes the registry "Hypertext Transfer | |||
Protocol (HTTP) RateLimit Quota Units" registry to be located at | Protocol (HTTP) RateLimit Quota Units" registry to be located at | |||
https://www.iana.org/assignments/http-ratelimit-quota-units. | https://www.iana.org/assignments/http-ratelimit-quota-units. | |||
Registration is done on the advice of a Designated Expert, appointed | Registration is done on the advice of a Designated Expert, appointed | |||
by the IESG or their delegate. All entries are Specification | by the IESG or their delegate. All entries are Specification | |||
Required ([IANA], Section 4.6). | Required ([IANA], Section 4.6). | |||
The registry has the following initial content: | The registry has the following initial content: | |||
+---------------+-----------+-------+ | +---------------------+-----------+-------+ | |||
| Quota Unit | Reference | Notes | | | Quota Unit | Reference | Notes | | |||
+---------------+-----------+-------+ | +---------------------+-----------+-------+ | |||
| request | RFC nnnn | | | | request | RFC nnnn | | | |||
| content-bytes | RFC nnnn | | | | content-bytes | RFC nnnn | | | |||
+---------------+-----------+-------+ | | concurrent-requests | RFC nnnn | | | |||
+---------------------+-----------+-------+ | ||||
9.1.1. Registration Template | 10.3.1. Registration Template | |||
The registration template for the RateLimit Quota Units registry is | The registration template for the RateLimit Quota Units registry is | |||
as follows: | as follows: | |||
o Quota Unit: The name of the quota unit. | o Quota Unit: The name of the quota unit. | |||
o Reference: A reference to the document that specifies the quota | o Reference: A reference to the document that specifies the quota | |||
unit. | unit. | |||
o Notes: Any additional notes about the quota unit. | o Notes: Any additional notes about the quota unit. | |||
10. References | 11. References | |||
10.1. Normative References | 11.1. Normative References | |||
[HTTP] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, | [HTTP] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, | |||
Ed., "HTTP Semantics", STD 97, RFC 9110, | Ed., "HTTP Semantics", STD 97, RFC 9110, | |||
DOI 10.17487/RFC9110, June 2022, | DOI 10.17487/RFC9110, June 2022, | |||
<https://www.rfc-editor.org/info/rfc9110>. | <https://www.rfc-editor.org/info/rfc9110>. | |||
[IANA] Cotton, M., Leiba, B., and T. Narten, "Guidelines for | [IANA] Cotton, M., Leiba, B., and T. Narten, "Guidelines for | |||
Writing an IANA Considerations Section in RFCs", BCP 26, | Writing an IANA Considerations Section in RFCs", BCP 26, | |||
RFC 8126, DOI 10.17487/RFC8126, June 2017, | RFC 8126, DOI 10.17487/RFC8126, June 2017, | |||
<https://www.rfc-editor.org/info/rfc8126>. | <https://www.rfc-editor.org/info/rfc8126>. | |||
[PROBLEM] Nottingham, M., Wilde, E., and S. Dalal, "Problem Details | ||||
for HTTP APIs", RFC 9457, DOI 10.17487/RFC9457, July 2023, | ||||
<https://www.rfc-editor.org/info/rfc9457>. | ||||
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
Requirement Levels", BCP 14, RFC 2119, | Requirement Levels", BCP 14, RFC 2119, | |||
DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
<https://www.rfc-editor.org/info/rfc2119>. | <https://www.rfc-editor.org/info/rfc2119>. | |||
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | |||
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | |||
May 2017, <https://www.rfc-editor.org/info/rfc8174>. | May 2017, <https://www.rfc-editor.org/info/rfc8174>. | |||
[RFC9651] Nottingham, M. and P. Kamp, "Structured Field Values for | ||||
HTTP", RFC 9651, DOI 10.17487/RFC9651, September 2024, | ||||
<https://www.rfc-editor.org/info/rfc9651>. | ||||
[STRUCTURED-FIELDS] | [STRUCTURED-FIELDS] | |||
Nottingham, M. and P. Kamp, "Structured Field Values for | Nottingham, M. and P. Kamp, "Structured Field Values for | |||
HTTP", RFC 8941, DOI 10.17487/RFC8941, February 2021, | HTTP", RFC 9651, DOI 10.17487/RFC9651, September 2024, | |||
<https://www.rfc-editor.org/info/rfc8941>. | <https://www.rfc-editor.org/info/rfc9651>. | |||
[WEB-ORIGIN] | [WEB-ORIGIN] | |||
Barth, A., "The Web Origin Concept", RFC 6454, | Barth, A., "The Web Origin Concept", RFC 6454, | |||
DOI 10.17487/RFC6454, December 2011, | DOI 10.17487/RFC6454, December 2011, | |||
<https://www.rfc-editor.org/info/rfc6454>. | <https://www.rfc-editor.org/info/rfc6454>. | |||
10.2. Informative References | 11.2. Informative References | |||
[HPACK] Peon, R. and H. Ruellan, "HPACK: Header Compression for | [HPACK] Peon, R. and H. Ruellan, "HPACK: Header Compression for | |||
HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, | HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, | |||
<https://www.rfc-editor.org/info/rfc7541>. | <https://www.rfc-editor.org/info/rfc7541>. | |||
[HTTP-CACHING] | [HTTP-CACHING] | |||
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, | Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, | |||
Ed., "HTTP Caching", STD 98, RFC 9111, | Ed., "HTTP Caching", STD 98, RFC 9111, | |||
DOI 10.17487/RFC9111, June 2022, | DOI 10.17487/RFC9111, June 2022, | |||
<https://www.rfc-editor.org/info/rfc9111>. | <https://www.rfc-editor.org/info/rfc9111>. | |||
skipping to change at line 827 ¶ | skipping to change at page 21, line 39 ¶ | |||
Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002, | Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002, | |||
<https://www.rfc-editor.org/info/rfc3339>. | <https://www.rfc-editor.org/info/rfc3339>. | |||
[RFC6585] Nottingham, M. and R. Fielding, "Additional HTTP Status | [RFC6585] Nottingham, M. and R. Fielding, "Additional HTTP Status | |||
Codes", RFC 6585, DOI 10.17487/RFC6585, April 2012, | Codes", RFC 6585, DOI 10.17487/RFC6585, April 2012, | |||
<https://www.rfc-editor.org/info/rfc6585>. | <https://www.rfc-editor.org/info/rfc6585>. | |||
[UNIX] The Open Group, "The Single UNIX Specification, Version 2 | [UNIX] The Open Group, "The Single UNIX Specification, Version 2 | |||
- 6 Vol Set for UNIX 98", February 1997. | - 6 Vol Set for UNIX 98", February 1997. | |||
10.3. URIs | 11.3. URIs | |||
[1] https://community.ntppool.org/t/another-ntp-client-failure- | [1] https://community.ntppool.org/t/another-ntp-client-failure- | |||
story/1014/ | story/1014/ | |||
[2] https://lists.w3.org/Archives/Public/ietf-http- | [2] https://lists.w3.org/Archives/Public/ietf-http- | |||
wg/2019JulSep/0202.html | wg/2019JulSep/0202.html | |||
Appendix A. Rate-limiting and quotas | Appendix A. Rate-limiting and quotas | |||
Servers use quota mechanisms to avoid systems overload, to ensure an | Servers use quota mechanisms to avoid systems overload, to ensure an | |||
skipping to change at line 849 ¶ | skipping to change at page 22, line 13 ¶ | |||
policies - e.g. monetization. | policies - e.g. monetization. | |||
A basic quota mechanism limits the number of acceptable requests in a | A basic quota mechanism limits the number of acceptable requests in a | |||
given time window, e.g. 10 requests per second. | given time window, e.g. 10 requests per second. | |||
When quota is exceeded, servers usually do not serve the request | When quota is exceeded, servers usually do not serve the request | |||
replying instead with a 4xx HTTP status code (e.g. 429 or 403) or | replying instead with a 4xx HTTP status code (e.g. 429 or 403) or | |||
adopt more aggressive policies like dropping connections. | adopt more aggressive policies like dropping connections. | |||
Quotas may be enforced on different basis (e.g. per user, per IP, per | Quotas may be enforced on different basis (e.g. per user, per IP, per | |||
geographic area, ..) and at different levels. For example, an user | geographic area, etc.) and at different levels. For example, an user | |||
may be allowed to issue: | may be allowed to issue: | |||
o 10 requests per second; | o 10 requests per second; | |||
o limited to 60 requests per minute; | o limited to 60 requests per minute; | |||
o limited to 1000 requests per hour. | o limited to 1000 requests per hour. | |||
Moreover system metrics, statistics and heuristics can be used to | Moreover system metrics, statistics and heuristics can be used to | |||
implement more complex policies, where the number of acceptable | implement more complex policies, where the number of acceptable | |||
skipping to change at line 1040 ¶ | skipping to change at page 26, line 23 ¶ | |||
The 429 (Too Many Request) HTTP status code is just used as an | The 429 (Too Many Request) HTTP status code is just used as an | |||
example. | example. | |||
Request: | Request: | |||
GET /items/123 HTTP/1.1 | GET /items/123 HTTP/1.1 | |||
Host: api.example | Host: api.example | |||
Response: | Response: | |||
HTTP/1.1 429 Too Many Requests | HTTP/1.1 429 Too Many Requests | |||
Content-Type: application/json | Content-Type: application/problem+json | |||
Date: Mon, 05 Aug 2019 09:27:00 GMT | Date: Mon, 05 Aug 2019 09:27:00 GMT | |||
Retry-After: Mon, 05 Aug 2019 09:27:05 GMT | Retry-After: Mon, 05 Aug 2019 09:27:05 GMT | |||
RateLimit: "default";r=0;t=5 | RateLimit: "default";r=0;t=5 | |||
{ | { | |||
"title": "Too Many Requests", | "type": "https://iana.org/assignments/http-problem-types#quota-exceeded" | |||
"status": 429, | "title": "Too Many Requests", | |||
"detail": "You have exceeded your quota" | "status": 429, | |||
} | "policy-violations": ["default"] | |||
} | ||||
B.2. Responses with defined policies | B.2. Responses with defined policies | |||
B.2.1. Throttling window specified via parameter | B.2.1. Throttling window specified via parameter | |||
The client has 99 quota units left for the next 50 seconds. The time | The client has 99 quota units left for the next 50 seconds. The time | |||
window is communicated by the "w" parameter, so we know the | window is communicated by the "w" parameter, so we know the | |||
throughput is 100 quota units per minute. | throughput is 100 quota units per minute. | |||
Request: | Request: | |||
skipping to change at line 1252 ¶ | skipping to change at page 31, line 14 ¶ | |||
FAQ | FAQ | |||
This section is to be removed before publishing as an RFC. | This section is to be removed before publishing as an RFC. | |||
1. Why defining standard fields for throttling? | 1. Why defining standard fields for throttling? | |||
To simplify enforcement of throttling policies and enable clients | To simplify enforcement of throttling policies and enable clients | |||
to constraint their requests to avoid being throttled. | to constraint their requests to avoid being throttled. | |||
2. Can I use RateLimit header fields in throttled responses (eg with | 2. Can I use RateLimit header fields in throttled responses (e.g. | |||
status code 429)? | with status code 429)? | |||
Yes, you can. | Yes, you can. | |||
3. Are those specs tied to RFC 6585? | 3. Are those specs tied to RFC 6585? | |||
No. [RFC6585] defines the "429" status code and we use it just | No. [RFC6585] defines the "429" status code and we use it just | |||
as an example of a throttled request, that could instead use even | as an example of a throttled request, that could instead use even | |||
"403" or whatever status code. | "403" or whatever status code. | |||
4. Why is the partition key necessary? | 4. Why is the partition key necessary? | |||
Without a partition key, a server can only effectively only have | Without a partition key, a server can effectively only have one | |||
one scope (aka partition), which is impractical for most | scope (aka partition), which is impractical for most services, or | |||
services, or it needs to communicate the scopes out-of-band. | it needs to communicate the scopes out-of-band. This prevents | |||
This prevents the development of generic connector code that can | the development of generic connector code that can be used to | |||
be used to prevent requests from being throttled. Many APIs rely | prevent requests from being throttled. Many APIs rely on API | |||
on API keys, user identity or client identity to allocate quota. | keys, user identity or client identity to allocate quota. As | |||
As soon as a single client processes requests for more than one | soon as a single client processes requests for more than one | |||
partition, the client needs to know the corresponding partition | partition, the client needs to know the corresponding partition | |||
key to properly track requests against allocated quota. | key to properly track requests against allocated quota. | |||
5. Why using delay-seconds instead of a UNIX Timestamp? Why not | 5. Why using delay-seconds instead of a UNIX Timestamp? Why not | |||
using subsecond precision? | using subsecond precision? | |||
Using delay-seconds aligns with Retry-After, which is returned in | Using delay-seconds aligns with Retry-After, which is returned in | |||
similar contexts, eg on 429 responses. | similar contexts, e.g. on 429 responses. | |||
Timestamps require a clock synchronization protocol (see | Timestamps require a clock synchronization protocol (see | |||
Section 5.6.7 of [HTTP]). This may be problematic (e.g. clock | Section 5.6.7 of [HTTP]). This may be problematic (e.g. clock | |||
adjustment, clock skew, failure of hardcoded clock | adjustment, clock skew, failure of hardcoded clock | |||
synchronization servers, IoT devices, ..). Moreover timestamps | synchronization servers, IoT devices, etc.). Moreover timestamps | |||
may not be monotonically increasing due to clock adjustment. See | may not be monotonically increasing due to clock adjustment. See | |||
Another NTP client failure story [1] | Another NTP client failure story [1] | |||
We did not use subsecond precision because: | We did not use subsecond precision because: | |||
* that is more subject to system clock correction like the one | * that is more subject to system clock correction like the one | |||
implemented via the adjtimex() Linux system call; | implemented via the adjtimex() Linux system call; | |||
* response-time latency may not make it worth. A brief | * response-time latency may not make it worth. A brief | |||
discussion on the subject is on the httpwg ml [2] | discussion on the subject is on the httpwg ml [2] | |||
skipping to change at line 1311 ¶ | skipping to change at page 32, line 26 ¶ | |||
level (see {#use-for-limiting-concurrency}) and help clients to | level (see {#use-for-limiting-concurrency}) and help clients to | |||
shape their requests avoiding being throttled out. | shape their requests avoiding being throttled out. | |||
A problematic way to limit concurrency is connection dropping, | A problematic way to limit concurrency is connection dropping, | |||
especially when connections are multiplexed (e.g. HTTP/2) because | especially when connections are multiplexed (e.g. HTTP/2) because | |||
this results in unserviced client requests, which is something we | this results in unserviced client requests, which is something we | |||
want to avoid. | want to avoid. | |||
A semantic way to limit concurrency is to return 503 + Retry- | A semantic way to limit concurrency is to return 503 + Retry- | |||
After in case of resource saturation (e.g. thrashing, connection | After in case of resource saturation (e.g. thrashing, connection | |||
queues too long, Service Level Objectives not meet, ..). | queues too long, Service Level Objectives not meet, etc.). | |||
Saturation conditions can be either dynamic or static: all this | Saturation conditions can be either dynamic or static: all this | |||
is out of the scope for the current document. | is out of the scope for the current document. | |||
7. Do a positive value of remaining paramter imply any service | 7. Do a positive value of remaining parameter imply any service | |||
guarantee for my future requests to be served? | guarantee for my future requests to be served? | |||
No. FAQ integrated in Section 4.1.1. | No. FAQ integrated in Section 4.1.1. | |||
8. Is the quota-policy definition too complex? | 8. Is the quota-policy definition too complex? | |||
You can always return the simplest form | You can always return the simplest form | |||
RateLimit:"default";r=50;t=60 | RateLimit:"default";r=50;t=60 | |||
skipping to change at line 1336 ¶ | skipping to change at page 33, line 4 ¶ | |||
The policy key clearly connects the current usage status of a policy | The policy key clearly connects the current usage status of a policy | |||
to the defined limits. So for the following field: | to the defined limits. So for the following field: | |||
RateLimit-Policy: "sliding";q=100;w=60;burst=1000 | RateLimit-Policy: "sliding";q=100;w=60;burst=1000 | |||
RateLimit-Policy: "fixed";q=5000;w=3600;burst=0 | RateLimit-Policy: "fixed";q=5000;w=3600;burst=0 | |||
RateLimit: "sliding";r=50;t=44 | RateLimit: "sliding";r=50;t=44 | |||
the value "sliding" identifies the policy being reported. | the value "sliding" identifies the policy being reported. | |||
1. Can intermediaries alter RateLimit header fields? | 1. Can intermediaries alter RateLimit header fields? | |||
Generally, they should not because it might result in unserviced | Generally, they should not because it might result in unserviced | |||
requests. There are reasonable use cases for intermediaries | requests. There are reasonable use cases for intermediaries | |||
mangling RateLimit header fields though, e.g. when they enforce | mangling RateLimit header fields though, e.g. when they enforce | |||
stricter quota-policies, or when they are an active component of | stricter quota-policies, or when they are an active component of | |||
the service. In those case we will consider them as part of the | the service. In those case we will consider them as part of the | |||
originating infrastructure. | originating infrastructure. | |||
2. Why the "w" parameter is just informative? Could it be used by a | 2. Why the "w" parameter is just informative? Could it be used by a | |||
client to determine the request rate? | client to determine the request rate? | |||
A non-informative "w" parameter might be fine in an environment | A non-informative "w" parameter might be fine in an environment | |||
where clients and servers are tightly coupled. Conveying | where clients and servers are tightly coupled. Conveying | |||
policies with this detail on a large scale would be very complex | policies with this detail on a large scale would be very complex | |||
and implementations would be likely not interoperable. We thus | and implementations would likely be not interoperable. We thus | |||
decided to leave "w" as an informational parameter and only rely | decided to leave "w" as an informational parameter and only rely | |||
on the limit, remaining and reset parameters for defining the | on the limit, remaining and reset parameters for defining the | |||
throttling behavior. | throttling behavior. | |||
3. Can I use RateLimit fields in trailers? Servers usually | 3. Can I use RateLimit fields in trailers? Servers usually | |||
establish whether the request is in-quota before creating a | establish whether the request is in-quota before creating a | |||
response, so the RateLimit field values should be already | response, so the RateLimit field values should be already | |||
available in that moment. Supporting trailers has the only | available in that moment. Supporting trailers has the only | |||
advantage that allows to provide more up-to-date information to | advantage that it allows to provide more up-to-date information | |||
the client in case of slow responses. However, this complicates | to the client in case of slow responses. However, this | |||
client implementations with respect to combining fields from | complicates client implementations with respect to combining | |||
headers and accounting for intermediaries that drop trailers. | fields from headers and accounting for intermediaries that drop | |||
Since there are no current implementations that use trailers, we | trailers. Since there are no current implementations that use | |||
decided to leave this as a future-work. | trailers, we decided to leave this as a future-work. | |||
RateLimit header fields currently used on the web | RateLimit header fields currently used on the web | |||
This section is to be removed before publishing as an RFC. | This section is to be removed before publishing as an RFC. | |||
Commonly used header field names are: | Commonly used header field names are: | |||
o "X-RateLimit-Limit", "X-RateLimit-Remaining", "X-RateLimit-Reset"; | o "X-RateLimit-Limit", "X-RateLimit-Remaining", "X-RateLimit-Reset"; | |||
There are variants too, where the window is specified in the header | There are variants too, where the window is specified in the header | |||
field name, eg: | field name, e.g.: | |||
o "x-ratelimit-limit-minute", "x-ratelimit-limit-hour", "x- | o "x-ratelimit-limit-minute", "x-ratelimit-limit-hour", "x- | |||
ratelimit-limit-day" | ratelimit-limit-day" | |||
o "x-ratelimit-remaining-minute", "x-ratelimit-remaining-hour", "x- | o "x-ratelimit-remaining-minute", "x-ratelimit-remaining-hour", "x- | |||
ratelimit-remaining-day" | ratelimit-remaining-day" | |||
Here are some interoperability issues: | Here are some interoperability issues: | |||
o "X-RateLimit-Remaining" references different values, depending on | o "X-RateLimit-Remaining" references different values, depending on | |||
skipping to change at line 1438 ¶ | skipping to change at page 35, line 13 ¶ | |||
Talvensaari, Nathan Friedly and Sanyam Dogra. | Talvensaari, Nathan Friedly and Sanyam Dogra. | |||
In addition to the people above, this document owes a lot to the | In addition to the people above, this document owes a lot to the | |||
extensive discussion in the HTTPAPI workgroup, including Rich Salz, | extensive discussion in the HTTPAPI workgroup, including Rich Salz, | |||
and Julian Reschke. | and Julian Reschke. | |||
Changes | Changes | |||
This section is to be removed before publishing as an RFC. | This section is to be removed before publishing as an RFC. | |||
F.1. Since draft-ietf-httpapi-ratelimit-headers-07 | F.1. Since draft-ietf-httpapi-ratelimit-headers-08 | |||
This section is to be removed before publishing as an RFC. | ||||
o Added Problem Types | ||||
o Clarified when to use RateLimit-Policy vs RateLimit fields | ||||
F.2. Since draft-ietf-httpapi-ratelimit-headers-07 | ||||
This section is to be removed before publishing as an RFC. | This section is to be removed before publishing as an RFC. | |||
o Refactored both fields to lists of Items that identify policy and | o Refactored both fields to lists of Items that identify policy and | |||
use parameters | use parameters | |||
o Added quota unit parameter | o Added quota unit parameter | |||
o Added partition key parameter | o Added partition key parameter | |||
F.2. Since draft-ietf-httpapi-ratelimit-headers-03 | F.3. Since draft-ietf-httpapi-ratelimit-headers-03 | |||
This section is to be removed before publishing as an RFC. | This section is to be removed before publishing as an RFC. | |||
o Split policy informatiom in RateLimit-Policy #81 | o Split policy informatiom in RateLimit-Policy #81 | |||
F.3. Since draft-ietf-httpapi-ratelimit-headers-02 | F.4. Since draft-ietf-httpapi-ratelimit-headers-02 | |||
This section is to be removed before publishing as an RFC. | This section is to be removed before publishing as an RFC. | |||
o Address throttling scope #83 | o Address throttling scope #83 | |||
F.4. Since draft-ietf-httpapi-ratelimit-headers-01 | F.5. Since draft-ietf-httpapi-ratelimit-headers-01 | |||
This section is to be removed before publishing as an RFC. | This section is to be removed before publishing as an RFC. | |||
o Update IANA considerations #60 | o Update IANA considerations #60 | |||
o Use Structured fields #58 | o Use Structured fields #58 | |||
o Reorganize document #67 | o Reorganize document #67 | |||
F.5. Since draft-ietf-httpapi-ratelimit-headers-00 | F.6. Since draft-ietf-httpapi-ratelimit-headers-00 | |||
This section is to be removed before publishing as an RFC. | This section is to be removed before publishing as an RFC. | |||
o Use I-D.httpbis-semantics, which includes referencing delay- | o Use I-D.httpbis-semantics, which includes referencing delay- | |||
seconds instead of delta-seconds. #5 | seconds instead of delta-seconds. #5 | |||
Authors' Addresses | Authors' Addresses | |||
Roberto Polli | Roberto Polli | |||
Team Digitale, Italian Government | Team Digitale, Italian Government | |||
End of changes. 71 change blocks. | ||||
175 lines changed or deleted | 333 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |