@@ -1116,6 +1116,49 @@ func TestDo_rateLimit_noNetworkCall(t *testing.T) {
11161116 }
11171117}
11181118
1119+ // Ignore rate limit headers if the response was served from cache.
1120+ func TestDo_rateLimit_ignoredFromCache (t * testing.T ) {
1121+ client , mux , _ , teardown := setup ()
1122+ defer teardown ()
1123+
1124+ reset := time .Now ().UTC ().Add (time .Minute ).Round (time .Second ) // Rate reset is a minute from now, with 1 second precision.
1125+
1126+ // By adding the X-From-Cache header we pretend this is served from a cache.
1127+ mux .HandleFunc ("/first" , func (w http.ResponseWriter , r * http.Request ) {
1128+ w .Header ().Set ("X-From-Cache" , "1" )
1129+ w .Header ().Set (headerRateLimit , "60" )
1130+ w .Header ().Set (headerRateRemaining , "0" )
1131+ w .Header ().Set (headerRateReset , fmt .Sprint (reset .Unix ()))
1132+ w .Header ().Set ("Content-Type" , "application/json; charset=utf-8" )
1133+ w .WriteHeader (http .StatusForbidden )
1134+ fmt .Fprintln (w , `{
1135+ "message": "API rate limit exceeded for xxx.xxx.xxx.xxx. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)",
1136+ "documentation_url": "https://docs.github.com/en/free-pro-team@latest/rest/overview/resources-in-the-rest-api#abuse-rate-limits"
1137+ }` )
1138+ })
1139+
1140+ madeNetworkCall := false
1141+ mux .HandleFunc ("/second" , func (w http.ResponseWriter , r * http.Request ) {
1142+ madeNetworkCall = true
1143+ })
1144+
1145+ // First request is made so afterwards we can check the returned rate limit headers were ignored.
1146+ req , _ := client .NewRequest ("GET" , "first" , nil )
1147+ ctx := context .Background ()
1148+ client .Do (ctx , req , nil )
1149+
1150+ // Second request should not by hindered by rate limits.
1151+ req , _ = client .NewRequest ("GET" , "second" , nil )
1152+ _ , err := client .Do (ctx , req , nil )
1153+
1154+ if err != nil {
1155+ t .Fatalf ("Second request failed, even though the rate limits from the cache should've been ignored: %v" , err )
1156+ }
1157+ if ! madeNetworkCall {
1158+ t .Fatal ("Network call was not made, even though the rate limits from the cache should've been ignored" )
1159+ }
1160+ }
1161+
11191162// Ensure *AbuseRateLimitError is returned when the response indicates that
11201163// the client has triggered an abuse detection mechanism.
11211164func TestDo_rateLimit_abuseRateLimitError (t * testing.T ) {
0 commit comments