Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/main/java/org/kohsuke/github/GitHubResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
Expand Down Expand Up @@ -206,6 +207,9 @@ interface BodyHandler<T> {
*/
static abstract class ResponseInfo {

private static final Comparator<String> nullableCaseInsensitiveComparator = Comparator
.nullsFirst(String.CASE_INSENSITIVE_ORDER);

private final int statusCode;
@Nonnull
private final GitHubRequest request;
Expand All @@ -217,7 +221,12 @@ protected ResponseInfo(@Nonnull GitHubRequest request,
@Nonnull Map<String, List<String>> headers) {
this.request = request;
this.statusCode = statusCode;
this.headers = Collections.unmodifiableMap(new HashMap<>(headers));

// Response header field names must be case-insensitive.
TreeMap<String, List<String>> caseInsensitiveMap = new TreeMap<>(nullableCaseInsensitiveComparator);
caseInsensitiveMap.putAll(headers);

this.headers = Collections.unmodifiableMap(caseInsensitiveMap);
}

/**
Expand Down
14 changes: 9 additions & 5 deletions src/test/java/org/kohsuke/github/GHRateLimitTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import java.time.Duration;
import java.util.Date;

import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.core.IsInstanceOf.instanceOf;

/**
Expand Down Expand Up @@ -163,16 +163,20 @@ private void verifyRateLimitValues(GHRateLimit previousLimit, int remaining) {
}

private void verifyRateLimitValues(GHRateLimit previousLimit, int remaining, boolean changedResetDate) {
// newer or unchange
int resetComparisionValue = changedResetDate ? 1 : 0;

// Basic checks of values
assertThat(rateLimit, notNullValue());
assertThat(rateLimit.getLimit(), equalTo(previousLimit.getLimit()));
assertThat(rateLimit.getRemaining(), equalTo(remaining));

// Check that the reset date of the current limit is not older than the previous one
assertThat(rateLimit.getResetDate().compareTo(previousLimit.getResetDate()), equalTo(resetComparisionValue));
long diffMillis = rateLimit.getResetDate().getTime() - previousLimit.getResetDate().getTime();

assertThat(diffMillis, greaterThanOrEqualTo(0L));
if (changedResetDate) {
assertThat(diffMillis, greaterThan(1000L));
} else {
assertThat(diffMillis, lessThanOrEqualTo(1000L));
}

// Additional checks for record values
assertThat(rateLimit.getCore().getLimit(), equalTo(rateLimit.getLimit()));
Expand Down
45 changes: 45 additions & 0 deletions src/test/java/org/kohsuke/github/GitHubTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import java.util.*;

import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.kohsuke.github.GHMarketplaceAccountType.ORGANIZATION;

/**
Expand Down Expand Up @@ -162,4 +164,47 @@ public void getMyMarketplacePurchases() throws IOException {
assertNull(account.getOrganizationBillingEmail());
}
}

@Test
public void gzip() throws Exception {

GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG);

// getResponseHeaderFields is deprecated but we'll use it for testing.
assertThat(org.getResponseHeaderFields(), notNullValue());

// WireMock should automatically gzip all responses
assertThat(org.getResponseHeaderFields().get("Content-Encoding").get(0), is("gzip"));
assertThat(org.getResponseHeaderFields().get("Content-eNcoding").get(0), is("gzip"));
}

@Test
public void testHeaderFieldName() throws Exception {

GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG);

// getResponseHeaderFields is deprecated but we'll use it for testing.
assertThat(org.getResponseHeaderFields(), notNullValue());

// Header field names must be case-insensitive
assertThat(org.getResponseHeaderFields().containsKey("CacHe-ContrOl"), is(true));

// The KeySet from header fields should also be case-insensitive
assertThat(org.getResponseHeaderFields().keySet().contains("CacHe-ControL"), is(true));
assertThat(org.getResponseHeaderFields().keySet().contains("CacHe-ControL"), is(true));

assertThat(org.getResponseHeaderFields().get("cachE-cOntrol").get(0), is("private, max-age=60, s-maxage=60"));

// GitHub has started changing their headers to all lowercase.
// For this test we want the field names to be with mixed-case (harder to do comparison).
// Ensure that it remains that way, if test resources are ever refreshed.
boolean found = false;
for (String key : org.getResponseHeaderFields().keySet()) {
if (Objects.equals("Cache-Control", key)) {
found = true;
break;
}
}
assertThat("Must have the literal expected string 'Cache-Control' for header field name", found);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"login": "github-api-test-org",
"id": 7544739,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
"url": "https://api.github.com/orgs/github-api-test-org",
"repos_url": "https://api.github.com/orgs/github-api-test-org/repos",
"events_url": "https://api.github.com/orgs/github-api-test-org/events",
"hooks_url": "https://api.github.com/orgs/github-api-test-org/hooks",
"issues_url": "https://api.github.com/orgs/github-api-test-org/issues",
"members_url": "https://api.github.com/orgs/github-api-test-org/members{/member}",
"public_members_url": "https://api.github.com/orgs/github-api-test-org/public_members{/member}",
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
"description": null,
"is_verified": false,
"has_organization_projects": true,
"has_repository_projects": true,
"public_repos": 25,
"public_gists": 0,
"followers": 0,
"following": 0,
"html_url": "https://github.com/github-api-test-org",
"created_at": "2014-05-10T19:39:11Z",
"updated_at": "2015-04-20T00:42:30Z",
"type": "Organization",
"total_private_repos": 0,
"owned_private_repos": 0,
"private_gists": 0,
"disk_usage": 147,
"collaborators": 0,
"billing_email": "kk@kohsuke.org",
"default_repository_permission": "none",
"members_can_create_repositories": false,
"two_factor_requirement_enabled": false,
"plan": {
"name": "free",
"space": 976562499,
"private_repos": 0,
"filled_seats": 15,
"seats": 0
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"login": "bitwiseman",
"id": 1958953,
"node_id": "MDQ6VXNlcjE5NTg5NTM=",
"avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/bitwiseman",
"html_url": "https://github.com/bitwiseman",
"followers_url": "https://api.github.com/users/bitwiseman/followers",
"following_url": "https://api.github.com/users/bitwiseman/following{/other_user}",
"gists_url": "https://api.github.com/users/bitwiseman/gists{/gist_id}",
"starred_url": "https://api.github.com/users/bitwiseman/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/bitwiseman/subscriptions",
"organizations_url": "https://api.github.com/users/bitwiseman/orgs",
"repos_url": "https://api.github.com/users/bitwiseman/repos",
"events_url": "https://api.github.com/users/bitwiseman/events{/privacy}",
"received_events_url": "https://api.github.com/users/bitwiseman/received_events",
"type": "User",
"site_admin": false,
"name": "Liam Newman",
"company": "Cloudbees, Inc.",
"blog": "",
"location": "Seattle, WA, USA",
"email": "bitwiseman@gmail.com",
"hireable": null,
"bio": "https://twitter.com/bitwiseman",
"public_repos": 181,
"public_gists": 7,
"followers": 151,
"following": 9,
"created_at": "2012-07-11T20:38:33Z",
"updated_at": "2020-03-27T19:14:56Z",
"private_gists": 8,
"total_private_repos": 10,
"owned_private_repos": 0,
"disk_usage": 33697,
"collaborators": 0,
"two_factor_authentication": true,
"plan": {
"name": "free",
"space": 976562499,
"collaborators": 0,
"private_repos": 10000
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"id": "6b1390ac-fba9-4e09-9b33-1915d6aad42d",
"name": "orgs_github-api-test-org",
"request": {
"url": "/orgs/github-api-test-org",
"method": "GET",
"headers": {
"Accept": {
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
}
}
},
"response": {
"status": 200,
"bodyFileName": "orgs_github-api-test-org-2.json",
"headers": {
"Date": "Tue, 31 Mar 2020 01:58:58 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "200 OK",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4947",
"X-RateLimit-Reset": "1585620720",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": [
"Accept, Authorization, Cookie, X-GitHub-OTP",
"Accept-Encoding, Accept, X-Requested-With"
],
"ETag": "W/\"19a1dc3fabba80fa04e5602bb1e9457b\"",
"Last-Modified": "Mon, 20 Apr 2015 00:42:30 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
"X-Accepted-OAuth-Scopes": "admin:org, read:org, repo, user, write:org",
"X-GitHub-Media-Type": "unknown, github.v3",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "DBDB:5BD4:C4C3:F7A4:5E82A3E2"
}
},
"uuid": "6b1390ac-fba9-4e09-9b33-1915d6aad42d",
"persistent": true,
"insertionIndex": 2
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"id": "0cdbd9dc-1c6f-42f5-a4b5-9d5472b2a56b",
"id": "1f83f6e6-3e0f-4529-a615-9084272bae98",
"name": "user",
"request": {
"url": "/user",
Expand All @@ -14,35 +14,33 @@
"status": 200,
"bodyFileName": "user-1.json",
"headers": {
"Date": "Sat, 26 Oct 2019 01:27:31 GMT",
"Date": "Tue, 31 Mar 2020 01:58:58 GMT",
"Content-Type": "application/json; charset=utf-8",
"Server": "GitHub.com",
"Status": "200 OK",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4436",
"X-RateLimit-Reset": "1572055286",
"X-RateLimit-Remaining": "4949",
"X-RateLimit-Reset": "1585620721",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": [
"Accept, Authorization, Cookie, X-GitHub-OTP",
"Accept-Encoding"
"Accept-Encoding, Accept, X-Requested-With"
],
"ETag": "W/\"8c3d3dcf6fc5f9edaf26c902295396e5\"",
"Last-Modified": "Tue, 24 Sep 2019 19:32:29 GMT",
"ETag": "W/\"740bb7db37d5437d08ea1aa5e652cf37\"",
"Last-Modified": "Fri, 27 Mar 2020 19:14:56 GMT",
"X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion",
"X-Accepted-OAuth-Scopes": "",
"X-GitHub-Media-Type": "unknown, github.v3",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
"Access-Control-Allow-Origin": "*",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "CA8F:3649:E32786:1091CE0:5DB3A103"
"X-GitHub-Request-Id": "DBDB:5BD4:C4C2:F7A3:5E82A3E1"
}
},
"uuid": "0cdbd9dc-1c6f-42f5-a4b5-9d5472b2a56b",
"uuid": "1f83f6e6-3e0f-4529-a615-9084272bae98",
"persistent": true,
"insertionIndex": 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"login": "github-api-test-org",
"id": 7544739,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
"url": "https://api.github.com/orgs/github-api-test-org",
"repos_url": "https://api.github.com/orgs/github-api-test-org/repos",
"events_url": "https://api.github.com/orgs/github-api-test-org/events",
"hooks_url": "https://api.github.com/orgs/github-api-test-org/hooks",
"issues_url": "https://api.github.com/orgs/github-api-test-org/issues",
"members_url": "https://api.github.com/orgs/github-api-test-org/members{/member}",
"public_members_url": "https://api.github.com/orgs/github-api-test-org/public_members{/member}",
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
"description": null,
"is_verified": false,
"has_organization_projects": true,
"has_repository_projects": true,
"public_repos": 25,
"public_gists": 0,
"followers": 0,
"following": 0,
"html_url": "https://github.com/github-api-test-org",
"created_at": "2014-05-10T19:39:11Z",
"updated_at": "2015-04-20T00:42:30Z",
"type": "Organization",
"total_private_repos": 0,
"owned_private_repos": 0,
"private_gists": 0,
"disk_usage": 147,
"collaborators": 0,
"billing_email": "kk@kohsuke.org",
"default_repository_permission": "none",
"members_can_create_repositories": false,
"two_factor_requirement_enabled": false,
"plan": {
"name": "free",
"space": 976562499,
"private_repos": 0,
"filled_seats": 15,
"seats": 0
}
}
Loading