DefaultConnection implements Connection { @Override public Optional<ZonedDateTime> getExpiration() { assertConnectionIsOpen(); String cacheHeader = conn.getHeaderField(CACHE_CONTROL_HEADER); if (cacheHeader != null) { if (NO_CACHE_PATTERN.matcher(cacheHeader).matches()) { return Optional.empty(); } Matcher m = MAX_AGE_PATTERN.matcher(cacheHeader); if (m.matches()) { int maxAge = Integer.parseInt(m.group(1)); if (maxAge == 0) { return Optional.empty(); } return Optional.of(ZonedDateTime.now(ZoneId.of("UTC")).plusSeconds(maxAge)); } } String expiresHeader = conn.getHeaderField(EXPIRES_HEADER); if (expiresHeader != null) { try { return Optional.of(ZonedDateTime.parse(expiresHeader, RFC_1123_DATE_TIME)); } catch (DateTimeParseException ex) { LOG.debug("Ignored invalid Expires date: {}", expiresHeader, ex); } } return Optional.empty(); } DefaultConnection(HttpConnector httpConnector); @Override void resetNonce(Session session); @Override int sendRequest(URL url, Session session, @Nullable ZonedDateTime ifModifiedSince); @Override int sendCertificateRequest(URL url, Login login); @Override int sendSignedPostAsGetRequest(URL url, Login login); @Override int sendSignedRequest(URL url, JSONBuilder claims, Login login); @Override int sendSignedRequest(URL url, JSONBuilder claims, Session session, KeyPair keypair); @Override JSON readJsonResponse(); @Override List<X509Certificate> readCertificates(); @Override void handleRetryAfter(String message); @Override @Nullable String getNonce(); @Override @Nullable URL getLocation(); @Override Optional<ZonedDateTime> getLastModified(); @Override Optional<ZonedDateTime> getExpiration(); @Override Collection<URL> getLinks(String relation); @Override void close();  }
@Test public void testExpirationUnset() { when(mockUrlConnection.getHeaderField("Cache-Control")).thenReturn(null); when(mockUrlConnection.getHeaderField("Expires")).thenReturn(null); try (DefaultConnection conn = new DefaultConnection(mockHttpConnection)) { conn.conn = mockUrlConnection; assertThat(conn.getExpiration().isPresent(), is(false)); } verify(mockUrlConnection).getHeaderField("Cache-Control"); verify(mockUrlConnection).getHeaderField("Expires"); verifyNoMoreInteractions(mockUrlConnection); }
@Test public void testExpirationNoCache() { when(mockUrlConnection.getHeaderField("Cache-Control")).thenReturn("public, no-cache"); when(mockUrlConnection.getHeaderField("Expires")).thenReturn(null); try (DefaultConnection conn = new DefaultConnection(mockHttpConnection)) { conn.conn = mockUrlConnection; assertThat(conn.getExpiration().isPresent(), is(false)); } verify(mockUrlConnection).getHeaderField("Cache-Control"); verifyNoMoreInteractions(mockUrlConnection); }
@Test public void testExpirationMaxAgeZero() { when(mockUrlConnection.getHeaderField("Cache-Control")).thenReturn("public, max-age=0, no-cache"); when(mockUrlConnection.getHeaderField("Expires")).thenReturn(null); try (DefaultConnection conn = new DefaultConnection(mockHttpConnection)) { conn.conn = mockUrlConnection; assertThat(conn.getExpiration().isPresent(), is(false)); } verify(mockUrlConnection).getHeaderField("Cache-Control"); verifyNoMoreInteractions(mockUrlConnection); }
@Test public void testExpirationMaxAgeButNoCache() { when(mockUrlConnection.getHeaderField("Cache-Control")).thenReturn("public, max-age=3600, no-cache"); when(mockUrlConnection.getHeaderField("Expires")).thenReturn(null); try (DefaultConnection conn = new DefaultConnection(mockHttpConnection)) { conn.conn = mockUrlConnection; assertThat(conn.getExpiration().isPresent(), is(false)); } verify(mockUrlConnection).getHeaderField("Cache-Control"); verifyNoMoreInteractions(mockUrlConnection); }
@Test public void testExpirationMaxAge() { when(mockUrlConnection.getHeaderField("Cache-Control")).thenReturn("max-age=3600"); when(mockUrlConnection.getHeaderField("Expires")).thenReturn(null); try (DefaultConnection conn = new DefaultConnection(mockHttpConnection)) { conn.conn = mockUrlConnection; Optional<ZonedDateTime> exp = conn.getExpiration(); assertThat(exp.isPresent(), is(true)); assertThat(exp.get().isAfter(ZonedDateTime.now().plusHours(1).minusMinutes(1)), is(true)); assertThat(exp.get().isBefore(ZonedDateTime.now().plusHours(1).plusMinutes(1)), is(true)); } verify(mockUrlConnection).getHeaderField("Cache-Control"); verifyNoMoreInteractions(mockUrlConnection); }
@Test public void testExpirationExpires() { when(mockUrlConnection.getHeaderField("Cache-Control")).thenReturn(null); when(mockUrlConnection.getHeaderField("Expires")).thenReturn("Thu, 18 Jun 2020 08:43:04 GMT"); try (DefaultConnection conn = new DefaultConnection(mockHttpConnection)) { conn.conn = mockUrlConnection; Optional<ZonedDateTime> exp = conn.getExpiration(); assertThat(exp.isPresent(), is(true)); assertThat(exp.get().format(DateTimeFormatter.ISO_DATE_TIME), is("2020-06-18T08:43:04Z")); } verify(mockUrlConnection).getHeaderField("Cache-Control"); verify(mockUrlConnection).getHeaderField("Expires"); verifyNoMoreInteractions(mockUrlConnection); }
@Test public void testExpirationInvalidExpires() { when(mockUrlConnection.getHeaderField("Cache-Control")).thenReturn(null); when(mockUrlConnection.getHeaderField("Expires")).thenReturn("iNvAlId"); try (DefaultConnection conn = new DefaultConnection(mockHttpConnection)) { conn.conn = mockUrlConnection; assertThat(conn.getExpiration().isPresent(), is(false)); } verify(mockUrlConnection).getHeaderField("Cache-Control"); verify(mockUrlConnection).getHeaderField("Expires"); verifyNoMoreInteractions(mockUrlConnection); }