1
0
mirror of https://github.com/google/nomulus synced 2025-12-23 14:25:44 +00:00

Save session data directly in a cookie (#2732)

This commit is contained in:
Lai Jiang
2025-03-31 12:21:50 -04:00
committed by GitHub
parent 2d072c3844
commit 4999a72d96
10 changed files with 420 additions and 69 deletions

View File

@@ -0,0 +1,155 @@
// Copyright 2025 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.flows;
import static java.nio.charset.StandardCharsets.US_ASCII;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.flogger.FluentLogger;
import com.google.common.io.BaseEncoding;
import google.registry.request.Response;
import jakarta.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A metadata class that saves the data directly in cookies.
*
* <p>Unlike {@link HttpSessionMetadata}, this class does not rely on a session manager to translate
* an opaque session cookie into the metadata. This means that the locality of the session manager
* is irrelevant and as long as the client (the proxy) respects the {@code Set-Cookie} headers and
* sets the respective cookies in subsequent requests in a session, the metadata will be available
* to all servers, not just the one that created the session.
*
* <p>The string representation of the metadata is saved in Base64 URL-safe format in a cookie named
* {@code SESSION_INFO}.
*/
public class CookieSessionMetadata extends SessionMetadata {
protected static final String COOKIE_NAME = "SESSION_INFO";
protected static final String REGISTRAR_ID = "clientId";
protected static final String SERVICE_EXTENSIONS = "serviceExtensionUris";
protected static final String FAILED_LOGIN_ATTEMPTS = "failedLoginAttempts";
private static final Pattern COOKIE_PATTERN = Pattern.compile("SESSION_INFO=([^;\\s]+)?");
private static final Pattern REGISTRAR_ID_PATTERN = Pattern.compile("clientId=([^,\\s]+)?");
private static final Pattern SERVICE_EXTENSIONS_PATTERN =
Pattern.compile("serviceExtensionUris=([^,\\s}]+)?");
private static final Pattern FAILED_LOGIN_ATTEMPTS_PATTERN =
Pattern.compile("failedLoginAttempts=([^,\\s]+)?");
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private final Map<String, String> data = new HashMap<>();
public CookieSessionMetadata(HttpServletRequest request) {
Optional.ofNullable(request.getHeader("Cookie"))
.ifPresent(
cookie -> {
Matcher matcher = COOKIE_PATTERN.matcher(cookie);
if (matcher.find()) {
String sessionInfo = decode(matcher.group(1));
logger.atInfo().log("SESSION INFO: %s", sessionInfo);
matcher = REGISTRAR_ID_PATTERN.matcher(sessionInfo);
if (matcher.find()) {
String registrarId = matcher.group(1);
if (!registrarId.equals("null")) {
data.put(REGISTRAR_ID, registrarId);
}
}
matcher = SERVICE_EXTENSIONS_PATTERN.matcher(sessionInfo);
if (matcher.find()) {
String serviceExtensions = matcher.group(1);
if (serviceExtensions != null) {
data.put(SERVICE_EXTENSIONS, serviceExtensions);
}
}
matcher = FAILED_LOGIN_ATTEMPTS_PATTERN.matcher(sessionInfo);
if (matcher.find()) {
String failedLoginAttempts = matcher.group(1);
data.put(FAILED_LOGIN_ATTEMPTS, failedLoginAttempts);
}
}
});
}
@Override
public void invalidate() {
data.clear();
}
@Override
public String getRegistrarId() {
return data.getOrDefault(REGISTRAR_ID, null);
}
@Override
public Set<String> getServiceExtensionUris() {
return Optional.ofNullable(data.getOrDefault(SERVICE_EXTENSIONS, null))
.map(s -> Splitter.on('.').splitToList(s))
.map(ImmutableSet::copyOf)
.orElse(ImmutableSet.of());
}
@Override
public int getFailedLoginAttempts() {
return Optional.ofNullable(data.getOrDefault(FAILED_LOGIN_ATTEMPTS, null))
.map(Integer::parseInt)
.orElse(0);
}
@Override
public void setRegistrarId(String registrarId) {
data.put(REGISTRAR_ID, registrarId);
}
@Override
public void setServiceExtensionUris(Set<String> serviceExtensionUris) {
if (serviceExtensionUris == null || serviceExtensionUris.isEmpty()) {
data.remove(SERVICE_EXTENSIONS);
} else {
data.put(SERVICE_EXTENSIONS, Joiner.on('.').join(serviceExtensionUris));
}
}
@Override
public void incrementFailedLoginAttempts() {
data.put(FAILED_LOGIN_ATTEMPTS, String.valueOf(getFailedLoginAttempts() + 1));
}
@Override
public void resetFailedLoginAttempts() {
data.remove(FAILED_LOGIN_ATTEMPTS);
}
@Override
public void save(Response response) {
String value = encode(toString());
response.setHeader("Set-Cookie", COOKIE_NAME + "=" + value);
}
protected static String encode(String plainText) {
return BaseEncoding.base64Url().encode(plainText.getBytes(US_ASCII));
}
protected static String decode(String cipherText) {
return new String(BaseEncoding.base64Url().decode(cipherText), US_ASCII);
}
}

View File

@@ -78,6 +78,8 @@ public class EppRequestHandler {
} catch (Exception e) { } catch (Exception e) {
logger.atWarning().withCause(e).log("handleEppCommand general exception."); logger.atWarning().withCause(e).log("handleEppCommand general exception.");
response.setStatus(SC_BAD_REQUEST); response.setStatus(SC_BAD_REQUEST);
} finally {
sessionMetadata.save(response);
} }
} }
} }

View File

@@ -20,7 +20,7 @@ import google.registry.request.Action.Method;
import google.registry.request.Payload; import google.registry.request.Payload;
import google.registry.request.auth.Auth; import google.registry.request.auth.Auth;
import jakarta.inject.Inject; import jakarta.inject.Inject;
import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpServletRequest;
/** /**
* Establishes a transport for EPP+TLS over HTTP. All commands and responses are EPP XML according * Establishes a transport for EPP+TLS over HTTP. All commands and responses are EPP XML according
@@ -35,18 +35,18 @@ public class EppTlsAction implements Runnable {
@Inject @Payload byte[] inputXmlBytes; @Inject @Payload byte[] inputXmlBytes;
@Inject TlsCredentials tlsCredentials; @Inject TlsCredentials tlsCredentials;
@Inject HttpSession session; @Inject HttpServletRequest request;
@Inject EppRequestHandler eppRequestHandler; @Inject EppRequestHandler eppRequestHandler;
@Inject EppTlsAction() {} @Inject EppTlsAction() {}
@Override @Override
public void run() { public void run() {
eppRequestHandler.executeEpp( eppRequestHandler.executeEpp(
new HttpSessionMetadata(session), new CookieSessionMetadata(request),
tlsCredentials, tlsCredentials,
EppRequestSource.TLS, EppRequestSource.TLS,
false, // This endpoint is never a dry run. false, // This endpoint is never a dry run.
false, // This endpoint is never a superuser. false, // This endpoint is never a superuser.
inputXmlBytes); inputXmlBytes);
} }
} }

View File

@@ -14,16 +14,14 @@
package google.registry.flows; package google.registry.flows;
import static com.google.common.base.MoreObjects.toStringHelper;
import static google.registry.util.CollectionUtils.nullToEmpty; import static google.registry.util.CollectionUtils.nullToEmpty;
import com.google.common.base.Joiner;
import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpSession;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
/** A metadata class that is a wrapper around {@link HttpSession}. */ /** A metadata class that is a wrapper around {@link HttpSession}. */
public class HttpSessionMetadata implements SessionMetadata { public class HttpSessionMetadata extends SessionMetadata {
private static final String REGISTRAR_ID = "REGISTRAR_ID"; private static final String REGISTRAR_ID = "REGISTRAR_ID";
private static final String SERVICE_EXTENSIONS = "SERVICE_EXTENSIONS"; private static final String SERVICE_EXTENSIONS = "SERVICE_EXTENSIONS";
@@ -75,13 +73,4 @@ public class HttpSessionMetadata implements SessionMetadata {
public void resetFailedLoginAttempts() { public void resetFailedLoginAttempts() {
session.removeAttribute(FAILED_LOGIN_ATTEMPTS); session.removeAttribute(FAILED_LOGIN_ATTEMPTS);
} }
@Override
public String toString() {
return toStringHelper(getClass())
.add("clientId", getRegistrarId())
.add("failedLoginAttempts", getFailedLoginAttempts())
.add("serviceExtensionUris", Joiner.on('.').join(nullToEmpty(getServiceExtensionUris())))
.toString();
}
} }

View File

@@ -14,29 +14,45 @@
package google.registry.flows; package google.registry.flows;
import static com.google.common.base.MoreObjects.toStringHelper;
import static google.registry.util.CollectionUtils.nullToEmpty;
import com.google.common.base.Joiner;
import google.registry.request.Response;
import java.util.Set; import java.util.Set;
/** Object to allow setting and retrieving session information in flows. */ /** Object to allow setting and retrieving session information in flows. */
public interface SessionMetadata { public abstract class SessionMetadata {
/** /**
* Invalidates the session. A new instance must be created after this for future sessions. * Invalidates the session. A new instance must be created after this for future sessions.
* Attempts to invoke methods of this class after this method has been called will throw * Attempts to invoke methods of this class after this method has been called will throw {@code
* {@code IllegalStateException}. * IllegalStateException}.
*/ */
void invalidate(); public abstract void invalidate();
String getRegistrarId(); public abstract String getRegistrarId();
Set<String> getServiceExtensionUris(); public abstract Set<String> getServiceExtensionUris();
int getFailedLoginAttempts(); public abstract int getFailedLoginAttempts();
void setRegistrarId(String registrarId); public abstract void setRegistrarId(String registrarId);
void setServiceExtensionUris(Set<String> serviceExtensionUris); public abstract void setServiceExtensionUris(Set<String> serviceExtensionUris);
void incrementFailedLoginAttempts(); public abstract void incrementFailedLoginAttempts();
void resetFailedLoginAttempts(); public abstract void resetFailedLoginAttempts();
@Override
public String toString() {
return toStringHelper(getClass())
.add("clientId", getRegistrarId())
.add("failedLoginAttempts", getFailedLoginAttempts())
.add("serviceExtensionUris", Joiner.on('.').join(nullToEmpty(getServiceExtensionUris())))
.toString();
}
public void save(Response response) {}
} }

View File

@@ -14,16 +14,13 @@
package google.registry.flows; package google.registry.flows;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static google.registry.util.CollectionUtils.nullToEmpty;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import java.util.Set; import java.util.Set;
/** A read-only {@link SessionMetadata} that doesn't support login/logout. */ /** A read-only {@link SessionMetadata} that doesn't support login/logout. */
public class StatelessRequestSessionMetadata implements SessionMetadata { public class StatelessRequestSessionMetadata extends SessionMetadata {
private final String registrarId; private final String registrarId;
private final ImmutableSet<String> serviceExtensionUris; private final ImmutableSet<String> serviceExtensionUris;
@@ -74,13 +71,6 @@ public class StatelessRequestSessionMetadata implements SessionMetadata {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public String toString() {
return toStringHelper(getClass())
.add("clientId", getRegistrarId())
.add("failedLoginAttempts", getFailedLoginAttempts())
.add("serviceExtensionUris", Joiner.on('.').join(nullToEmpty(getServiceExtensionUris())))
.toString();
}
} }

View File

@@ -0,0 +1,211 @@
// Copyright 2025 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.flows;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.flows.CookieSessionMetadata.COOKIE_NAME;
import static google.registry.flows.CookieSessionMetadata.decode;
import static google.registry.flows.CookieSessionMetadata.encode;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableSet;
import google.registry.testing.FakeResponse;
import jakarta.servlet.http.HttpServletRequest;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link CookieSessionMetadata}. */
public class CookieSessionMetadataTest {
private HttpServletRequest request = mock(HttpServletRequest.class);
private FakeResponse response = new FakeResponse();
private CookieSessionMetadata cookieSessionMetadata = new CookieSessionMetadata(request);
@Test
void testNoCookie() {
assertThat(cookieSessionMetadata.getRegistrarId()).isNull();
assertThat(cookieSessionMetadata.getFailedLoginAttempts()).isEqualTo(0);
assertThat(cookieSessionMetadata.getServiceExtensionUris()).isEmpty();
}
@Test
void testCookieWithAllFields() {
when(request.getHeader("Cookie"))
.thenReturn(
"THIS_COOKIE=foo; SESSION_INFO="
+ encode(
"CookieSessionMetadata{clientId=test_registrar, failedLoginAttempts=5, "
+ " serviceExtensionUris=A.B.C}")
+ "; THAT_COOKIE=bar");
cookieSessionMetadata = new CookieSessionMetadata(request);
assertThat(cookieSessionMetadata.getRegistrarId()).isEqualTo("test_registrar");
assertThat(cookieSessionMetadata.getFailedLoginAttempts()).isEqualTo(5);
assertThat(cookieSessionMetadata.getServiceExtensionUris()).containsExactly("A", "B", "C");
}
@Test
void testCookieWithNullRegistrar() {
when(request.getHeader("Cookie"))
.thenReturn(
"SESSION_INFO="
+ encode(
"CookieSessionMetadata{clientId=null, failedLoginAttempts=5, "
+ " serviceExtensionUris=A.B.C}"));
cookieSessionMetadata = new CookieSessionMetadata(request);
assertThat(cookieSessionMetadata.getRegistrarId()).isNull();
assertThat(cookieSessionMetadata.getFailedLoginAttempts()).isEqualTo(5);
assertThat(cookieSessionMetadata.getServiceExtensionUris()).containsExactly("A", "B", "C");
}
@Test
void testCookieWithEmptyExtension() {
when(request.getHeader("Cookie"))
.thenReturn(
"SESSION_INFO="
+ encode(
"CookieSessionMetadata{clientId=test_registrar, failedLoginAttempts=5, "
+ " serviceExtensionUris=}"));
cookieSessionMetadata = new CookieSessionMetadata(request);
assertThat(cookieSessionMetadata.getRegistrarId()).isEqualTo("test_registrar");
assertThat(cookieSessionMetadata.getFailedLoginAttempts()).isEqualTo(5);
assertThat(cookieSessionMetadata.getServiceExtensionUris()).isEmpty();
}
@Test
void testCookieWithSingleExtension() {
when(request.getHeader("Cookie"))
.thenReturn(
"SESSION_INFO="
+ encode(
"CookieSessionMetadata{clientId=test_registrar, failedLoginAttempts=5, "
+ " serviceExtensionUris=Foo}"));
cookieSessionMetadata = new CookieSessionMetadata(request);
assertThat(cookieSessionMetadata.getRegistrarId()).isEqualTo("test_registrar");
assertThat(cookieSessionMetadata.getFailedLoginAttempts()).isEqualTo(5);
assertThat(cookieSessionMetadata.getServiceExtensionUris()).containsExactly("Foo");
}
@Test
void testIncrementFailedLoginAttempts() {
when(request.getHeader("Cookie"))
.thenReturn(
"SESSION_INFO="
+ encode(
"CookieSessionMetadata{clientId=test_registrar, failedLoginAttempts=5, "
+ " serviceExtensionUris=Foo}"));
cookieSessionMetadata = new CookieSessionMetadata(request);
cookieSessionMetadata.incrementFailedLoginAttempts();
assertThat(cookieSessionMetadata.getRegistrarId()).isEqualTo("test_registrar");
assertThat(cookieSessionMetadata.getFailedLoginAttempts()).isEqualTo(6);
assertThat(cookieSessionMetadata.getServiceExtensionUris()).containsExactly("Foo");
}
@Test
void testResetFailedLoginAttempts() {
when(request.getHeader("Cookie"))
.thenReturn(
"SESSION_INFO="
+ encode(
"CookieSessionMetadata{clientId=test_registrar, failedLoginAttempts=5, "
+ " serviceExtensionUris=Foo}"));
cookieSessionMetadata = new CookieSessionMetadata(request);
cookieSessionMetadata.resetFailedLoginAttempts();
assertThat(cookieSessionMetadata.getRegistrarId()).isEqualTo("test_registrar");
assertThat(cookieSessionMetadata.getFailedLoginAttempts()).isEqualTo(0);
assertThat(cookieSessionMetadata.getServiceExtensionUris()).containsExactly("Foo");
}
@Test
void testSetRegistrarId() {
when(request.getHeader("Cookie"))
.thenReturn(
"SESSION_INFO="
+ encode(
"CookieSessionMetadata{clientId=test_registrar, failedLoginAttempts=5, "
+ " serviceExtensionUris=Foo}"));
cookieSessionMetadata = new CookieSessionMetadata(request);
cookieSessionMetadata.setRegistrarId("new_registrar");
assertThat(cookieSessionMetadata.getRegistrarId()).isEqualTo("new_registrar");
assertThat(cookieSessionMetadata.getFailedLoginAttempts()).isEqualTo(5);
assertThat(cookieSessionMetadata.getServiceExtensionUris()).containsExactly("Foo");
}
@Test
void testSetExtensions() {
when(request.getHeader("Cookie"))
.thenReturn(
"SESSION_INFO="
+ encode(
"CookieSessionMetadata{clientId=test_registrar, failedLoginAttempts=5, "
+ " serviceExtensionUris=Foo}"));
cookieSessionMetadata = new CookieSessionMetadata(request);
cookieSessionMetadata.setServiceExtensionUris(ImmutableSet.of("Bar", "Baz"));
assertThat(cookieSessionMetadata.getRegistrarId()).isEqualTo("test_registrar");
assertThat(cookieSessionMetadata.getFailedLoginAttempts()).isEqualTo(5);
assertThat(cookieSessionMetadata.getServiceExtensionUris()).containsExactly("Bar", "Baz");
}
@Test
void testSetEmptyExtensions() {
when(request.getHeader("Cookie"))
.thenReturn(
"SESSION_INFO="
+ encode(
"CookieSessionMetadata{clientId=test_registrar, failedLoginAttempts=5, "
+ " serviceExtensionUris=Foo}"));
cookieSessionMetadata = new CookieSessionMetadata(request);
cookieSessionMetadata.setServiceExtensionUris(ImmutableSet.of());
assertThat(cookieSessionMetadata.getRegistrarId()).isEqualTo("test_registrar");
assertThat(cookieSessionMetadata.getFailedLoginAttempts()).isEqualTo(5);
assertThat(cookieSessionMetadata.getServiceExtensionUris()).isEmpty();
}
@Test
void testInvalidate() {
when(request.getHeader("Cookie"))
.thenReturn(
"SESSION_INFO="
+ encode(
"CookieSessionMetadata{clientId=test_registrar, failedLoginAttempts=5, "
+ " serviceExtensionUris=Foo}"));
cookieSessionMetadata = new CookieSessionMetadata(request);
cookieSessionMetadata.invalidate();
assertThat(cookieSessionMetadata.getRegistrarId()).isNull();
assertThat(cookieSessionMetadata.getFailedLoginAttempts()).isEqualTo(0);
assertThat(cookieSessionMetadata.getServiceExtensionUris()).isEmpty();
}
@Test
void testSave() {
cookieSessionMetadata.save(response);
String value =
decode(
response.getHeaders().get("Set-Cookie").toString().substring(COOKIE_NAME.length() + 1));
assertThat(value)
.isEqualTo(
"CookieSessionMetadata{clientId=null, failedLoginAttempts=0, serviceExtensionUris=}");
cookieSessionMetadata.setRegistrarId("new_registrar");
cookieSessionMetadata.setServiceExtensionUris(ImmutableSet.of("Bar", "Baz"));
cookieSessionMetadata.incrementFailedLoginAttempts();
cookieSessionMetadata.save(response);
value =
decode(
response.getHeaders().get("Set-Cookie").toString().substring(COOKIE_NAME.length() + 1));
assertThat(value)
.isEqualTo(
"CookieSessionMetadata{clientId=new_registrar, failedLoginAttempts=1,"
+ " serviceExtensionUris=Bar.Baz}");
}
}

View File

@@ -12,17 +12,19 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package google.registry.flows; package google.registry.flows;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.US_ASCII;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same; import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import google.registry.testing.FakeHttpSession; import com.google.common.io.BaseEncoding;
import jakarta.servlet.http.HttpServletRequest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
@@ -36,18 +38,22 @@ class EppTlsActionTest {
EppTlsAction action = new EppTlsAction(); EppTlsAction action = new EppTlsAction();
action.inputXmlBytes = INPUT_XML_BYTES; action.inputXmlBytes = INPUT_XML_BYTES;
action.tlsCredentials = mock(TlsCredentials.class); action.tlsCredentials = mock(TlsCredentials.class);
action.session = new FakeHttpSession(); action.request = mock(HttpServletRequest.class);
action.session.setAttribute("REGISTRAR_ID", "ClientIdentifier"); when(action.request.getHeader("Cookie"))
.thenReturn(
"SESSION_INFO="
+ BaseEncoding.base64Url().encode("clientId=ClientIdentifier".getBytes(US_ASCII)));
action.eppRequestHandler = mock(EppRequestHandler.class); action.eppRequestHandler = mock(EppRequestHandler.class);
action.run(); action.run();
ArgumentCaptor<SessionMetadata> captor = ArgumentCaptor.forClass(SessionMetadata.class); ArgumentCaptor<SessionMetadata> captor = ArgumentCaptor.forClass(SessionMetadata.class);
verify(action.eppRequestHandler).executeEpp( verify(action.eppRequestHandler)
captor.capture(), .executeEpp(
same(action.tlsCredentials), captor.capture(),
eq(EppRequestSource.TLS), same(action.tlsCredentials),
eq(false), eq(EppRequestSource.TLS),
eq(false), eq(false),
eq(INPUT_XML_BYTES)); eq(false),
eq(INPUT_XML_BYTES));
assertThat(captor.getValue().getRegistrarId()).isEqualTo("ClientIdentifier"); assertThat(captor.getValue().getRegistrarId()).isEqualTo("ClientIdentifier");
} }
} }

View File

@@ -62,15 +62,4 @@ do
kubectl apply -f - kubectl apply -f -
done done
# Restart proxies
while read line
do
parts=(${line})
echo "Updating cluster ${parts[0]} in location ${parts[1]}..."
gcloud container clusters get-credentials ${parts[0]} \
--project ${project} --location ${parts[1]}
kubectl rollout restart deployment/proxy-deployment
kubectl rollout restart deployment/proxy-deployment-canary
done < <(gcloud container clusters list --project ${project} | grep proxy-cluster)
kubectl config use-context "$current_context" kubectl config use-context "$current_context"

View File

@@ -42,7 +42,6 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -272,17 +271,11 @@ class SslServerInitializerTest {
getClientHandler( getClientHandler(
sslProvider, serverSsc.cert(), clientSsc.key(), clientSsc.cert(), "TLSv1.1", null)); sslProvider, serverSsc.cert(), clientSsc.key(), clientSsc.cert(), "TLSv1.1", null));
ImmutableList<Integer> jdkVersion =
Arrays.stream(System.getProperty("java.version").split("\\."))
.map(Integer::parseInt)
.collect(ImmutableList.toImmutableList());
// In JDK v11.0.11 and above, TLS 1.1 is not supported anymore, in which case attempting to // In JDK v11.0.11 and above, TLS 1.1 is not supported anymore, in which case attempting to
// connect with TLS 1.1 results in a ClosedChannelException instead of a SSLHandShakeException. // connect with TLS 1.1 results in a ClosedChannelException instead of a SSLHandShakeException.
// See https://www.oracle.com/java/technologies/javase/11-0-11-relnotes.html#JDK-8202343 // See https://www.oracle.com/java/technologies/javase/11-0-11-relnotes.html#JDK-8202343
Class<? extends Exception> rootCause = Class<? extends Exception> rootCause =
sslProvider == SslProvider.JDK sslProvider == SslProvider.JDK
&& compareSemanticVersion(jdkVersion, ImmutableList.of(11, 0, 11))
? ClosedChannelException.class ? ClosedChannelException.class
: SSLHandshakeException.class; : SSLHandshakeException.class;