handle case insensitive headers when parsing for API rate limiting (#2175)

This commit is contained in:
Brendan Forster
2020-04-12 13:04:30 -03:00
committed by GitHub
parent 2bfd101bd0
commit 8d7bda96e4
8 changed files with 103 additions and 18 deletions
+22 -8
View File
@@ -16,6 +16,16 @@ namespace Octokit.Internal
static readonly Regex _linkRelRegex = new Regex("rel=\"(next|prev|first|last)\"", regexOptions);
static readonly Regex _linkUriRegex = new Regex("<(.+)>", regexOptions);
static KeyValuePair<string, string> LookupHeader(IDictionary<string, string> headers, string key)
{
return headers.FirstOrDefault(h => string.Equals(h.Key, key, StringComparison.OrdinalIgnoreCase));
}
static bool Exists(KeyValuePair<string, string> kvp)
{
return !kvp.Equals(default(KeyValuePair<string, string>));
}
public static ApiInfo ParseResponseHeaders(IDictionary<string, string> responseHeaders)
{
Ensure.ArgumentNotNull(responseHeaders, nameof(responseHeaders));
@@ -25,28 +35,32 @@ namespace Octokit.Internal
var acceptedOauthScopes = new List<string>();
string etag = null;
if (responseHeaders.ContainsKey("X-Accepted-OAuth-Scopes"))
var acceptedOauthScopesKey = LookupHeader(responseHeaders, "X-Accepted-OAuth-Scopes");
if (Exists(acceptedOauthScopesKey))
{
acceptedOauthScopes.AddRange(responseHeaders["X-Accepted-OAuth-Scopes"]
acceptedOauthScopes.AddRange(acceptedOauthScopesKey.Value
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim()));
}
if (responseHeaders.ContainsKey("X-OAuth-Scopes"))
var oauthScopesKey = LookupHeader(responseHeaders, "X-OAuth-Scopes");
if (Exists(oauthScopesKey))
{
oauthScopes.AddRange(responseHeaders["X-OAuth-Scopes"]
oauthScopes.AddRange(oauthScopesKey.Value
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim()));
}
if (responseHeaders.ContainsKey("ETag"))
var etagKey = LookupHeader(responseHeaders, "ETag");
if (Exists(etagKey))
{
etag = responseHeaders["ETag"];
etag = etagKey.Value;
}
if (responseHeaders.ContainsKey("Link"))
var linkKey = LookupHeader(responseHeaders, "Link");
if (Exists(linkKey))
{
var links = responseHeaders["Link"].Split(',');
var links = linkKey.Value.Split(',');
foreach (var link in links)
{
var relMatch = _linkRelRegex.Match(link);
+24 -2
View File
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
#if !NO_SERIALIZABLE
using System.Runtime.Serialization;
#endif
@@ -65,11 +66,32 @@ namespace Octokit
[Parameter(Key = "reset")]
public long ResetAsUtcEpochSeconds { get; private set; }
static KeyValuePair<string, string> LookupHeader(IDictionary<string, string> headers, string key)
{
return headers.FirstOrDefault(h => string.Equals(h.Key, key, StringComparison.OrdinalIgnoreCase));
}
static bool Exists(KeyValuePair<string, string> kvp)
{
return !kvp.Equals(default(KeyValuePair<string, string>));
}
static long GetHeaderValueAsInt32Safe(IDictionary<string, string> responseHeaders, string key)
{
string value;
long result;
return !responseHeaders.TryGetValue(key, out value) || value == null || !long.TryParse(value, out result)
var foundKey = LookupHeader(responseHeaders, key);
if (!Exists(foundKey))
{
return 0;
}
if (string.IsNullOrWhiteSpace(foundKey.Value))
{
return 0;
}
return !long.TryParse(foundKey.Value, out result)
? 0
: result;
}