Skip to content

Commit 16d34f3

Browse files
committed
Workaround for hub4j#669 - retry with cache overridden
This is much more reasonable way to address this issue. When the Requester detects a 404 response with an ETag (only happpens when the server's 304 is bogus and would cause cache corruption), try the query again with new request header that forces the server to not return 304 and return new data instead. Ths solution is transparent to users of this library and autmatically fixes a situation that was causing cache corruption. If GitHub ever fixes the issue and begins providing accurate ETags to their 404 responses, this will result in two calls being made for each 404 response. While that would be unfortunate, it would still be better than the current situation.
1 parent 61e8dd0 commit 16d34f3

1 file changed

Lines changed: 20 additions & 0 deletions

File tree

src/main/java/org/kohsuke/github/Requester.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,26 @@ private <T> T parse(Class<T> type, T instance, int timeouts) throws IOException
882882
// java.net.URLConnection handles 404 exception has FileNotFoundException, don't wrap exception in
883883
// HttpException
884884
// to preserve backward compatibility
885+
886+
// WORKAROUND FOR ISSUE #669:
887+
// When caching GitHub doesn't handle "If-Modified-Since" correctly
888+
// In the case that an item didn't exist (returned 404) but now does exist
889+
// Accurate 404 responses from GitHub do not have ETag information (at this time)
890+
// If we see a 404 with an ETag we treat it as corrupt and make new request with
891+
// caching headers overridden to force refresh.
892+
// If we tried this once already, don't try again.
893+
if (Objects.equals(uc.getRequestMethod(), "GET")
894+
&& uc.getHeaderField("ETag") != null
895+
&& !Objects.equals(uc.getRequestProperty("Cache-Control"), "no-cache")
896+
&& timeouts > 0) {
897+
setupConnection(uc.getURL());
898+
// Setting "Cache-Control" to "no-cache" stops the cache from supplying
899+
// "If-Modified-Since" or "If-None-Match" values.
900+
// This makes GitHub give us current data (not incorrectly cached data)
901+
uc.setRequestProperty("Cache-Control", "no-cache");
902+
return parse(type, instance, timeouts - 1);
903+
}
904+
885905
throw e;
886906
} catch (IOException e) {
887907
if (e instanceof SocketTimeoutException && timeouts > 0) {

0 commit comments

Comments
 (0)