diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/AcmeJsonResource.java b/acme4j-client/src/main/java/org/shredzone/acme4j/AcmeJsonResource.java
index 1842e1d1..173ded70 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/AcmeJsonResource.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/AcmeJsonResource.java
@@ -116,7 +116,7 @@ public abstract class AcmeJsonResource extends AcmeResource {
String resourceType = getClass().getSimpleName();
LOG.debug("update {}", resourceType);
try (Connection conn = connect()) {
- conn.sendRequest(getLocation(), getSession());
+ conn.sendSignedPostAsGetRequest(getLocation(), getLogin());
JSON json = conn.readJsonResponse();
if (json != null) {
setJSON(json);
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Certificate.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Certificate.java
index d340dacb..261c75ca 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/Certificate.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Certificate.java
@@ -71,7 +71,7 @@ public class Certificate extends AcmeResource {
if (certChain == null) {
LOG.debug("download");
try (Connection conn = connect()) {
- conn.sendCertificateRequest(getLocation(), getSession());
+ conn.sendCertificateRequest(getLocation(), getLogin());
alternates = new ArrayList<>(conn.getLinks("alternate"));
certChain = new ArrayList<>(conn.readCertificates());
}
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/connector/Connection.java b/acme4j-client/src/main/java/org/shredzone/acme4j/connector/Connection.java
index 092e56d9..2d5cb9d7 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/connector/Connection.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/connector/Connection.java
@@ -58,17 +58,36 @@ public interface Connection extends AutoCloseable {
void sendRequest(URL url, Session session) throws AcmeException;
/**
- * Sends a request for a certificate resource.
+ * Sends a signed POST-as-GET request for a certificate resource. Requires a
+ * {@link Login} for the session and {@link KeyPair}. The {@link Login} account
+ * location is sent in a "kid" protected header.
*
- * If the response code was not {@link HttpURLConnection#HTTP_OK}, an
- * {@link AcmeException} matching the error is raised.
+ * If the server does not return a 200 class status code, an {@link AcmeException} is
+ * raised matching the error.
*
* @param url
* {@link URL} to send the request to.
- * @param session
- * {@link Session} instance to be used for tracking
+ * @param login
+ * {@link Login} instance to be used for signing and tracking.
+ * @return HTTP 200 class status that was returned
*/
- void sendCertificateRequest(URL url, Session session) throws AcmeException;
+ int sendCertificateRequest(URL url, Login login) throws AcmeException;
+
+ /**
+ * Sends a signed POST-as-GET request. Requires a {@link Login} for the session and
+ * {@link KeyPair}. The {@link Login} account location is sent in a "kid" protected
+ * header.
+ *
+ * If the server does not return a 200 class status code, an {@link AcmeException} is
+ * raised matching the error.
+ *
+ * @param url
+ * {@link URL} to send the request to.
+ * @param login
+ * {@link Login} instance to be used for signing and tracking.
+ * @return HTTP 200 class status that was returned
+ */
+ int sendSignedPostAsGetRequest(URL url, Login login) throws AcmeException;
/**
* Sends a signed POST request. Requires a {@link Login} for the session and
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/connector/DefaultConnection.java b/acme4j-client/src/main/java/org/shredzone/acme4j/connector/DefaultConnection.java
index ee5900dd..ca1f034f 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/connector/DefaultConnection.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/connector/DefaultConnection.java
@@ -137,15 +137,6 @@ public class DefaultConnection implements Connection {
@Override
public void sendRequest(URL url, Session session) throws AcmeException {
- sendRequest(url, session, MIME_JSON);
- }
-
- @Override
- public void sendCertificateRequest(URL url, Session session) throws AcmeException {
- sendRequest(url, session, MIME_CERTIFICATE_CHAIN);
- }
-
- private void sendRequest(URL url, Session session, String accept) throws AcmeException {
Objects.requireNonNull(url, "url");
Objects.requireNonNull(session, "session");
assertConnectionIsClosed();
@@ -155,7 +146,7 @@ public class DefaultConnection implements Connection {
try {
conn = httpConnector.openConnection(url, session.getProxy());
conn.setRequestMethod("GET");
- conn.setRequestProperty(ACCEPT_HEADER, accept);
+ conn.setRequestProperty(ACCEPT_HEADER, MIME_JSON);
conn.setRequestProperty(ACCEPT_CHARSET_HEADER, DEFAULT_CHARSET);
conn.setRequestProperty(ACCEPT_LANGUAGE_HEADER, session.getLocale().toLanguageTag());
conn.setDoOutput(false);
@@ -174,30 +165,43 @@ public class DefaultConnection implements Connection {
}
}
+ @Override
+ public int sendCertificateRequest(URL url, Login login) throws AcmeException {
+ return sendSignedRequest(url, null, login.getSession(), login.getKeyPair(),
+ login.getAccountLocation(), MIME_CERTIFICATE_CHAIN);
+ }
+
+ @Override
+ public int sendSignedPostAsGetRequest(URL url, Login login) throws AcmeException {
+ return sendSignedRequest(url, null, login.getSession(), login.getKeyPair(),
+ login.getAccountLocation(), MIME_JSON);
+ }
+
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Login login) throws AcmeException {
- return sendSignedRequest(url, claims, login.getSession(), login.getKeyPair(), login.getAccountLocation());
+ return sendSignedRequest(url, claims, login.getSession(), login.getKeyPair(),
+ login.getAccountLocation(), MIME_JSON);
}
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, KeyPair keypair)
throws AcmeException {
- return sendSignedRequest(url, claims, session, keypair, null);
+ return sendSignedRequest(url, claims, session, keypair, null, MIME_JSON);
}
- private int sendSignedRequest(URL url, JSONBuilder claims, Session session, KeyPair keypair, @Nullable URL accountLocation)
- throws AcmeException {
+ private int sendSignedRequest(URL url, @Nullable JSONBuilder claims, Session session,
+ KeyPair keypair, @Nullable URL accountLocation, String accept) throws AcmeException {
Objects.requireNonNull(url, "url");
- Objects.requireNonNull(claims, "claims");
Objects.requireNonNull(session, "session");
Objects.requireNonNull(keypair, "keypair");
+ Objects.requireNonNull(accept, "accept");
assertConnectionIsClosed();
AcmeException lastException = null;
for (int attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
try {
- return performRequest(url, claims, session, keypair, accountLocation);
+ return performRequest(url, claims, session, keypair, accountLocation, accept);
} catch (AcmeServerException ex) {
if (!BAD_NONCE_ERROR.equals(ex.getType())) {
throw ex;
@@ -322,7 +326,8 @@ public class DefaultConnection implements Connection {
* @param url
* {@link URL} to send the request to.
* @param claims
- * {@link JSONBuilder} containing claims. Must not be {@code null}.
+ * {@link JSONBuilder} containing claims. {@code null} for POST-as-GET
+ * request.
* @param session
* {@link Session} instance to be used for signing and tracking
* @param keypair
@@ -330,19 +335,23 @@ public class DefaultConnection implements Connection {
* @param accountLocation
* If set, the account location is set as "kid" header. If {@code null},
* the public key is set as "jwk" header.
+ * @param accept
+ * Accept header
* @return HTTP 200 class status that was returned
*/
- private int performRequest(URL url, JSONBuilder claims, Session session, KeyPair keypair,
- @Nullable URL accountLocation)
+ private int performRequest(URL url, @Nullable JSONBuilder claims, Session session,
+ KeyPair keypair, @Nullable URL accountLocation, String accept)
throws AcmeException {
try {
if (session.getNonce() == null) {
resetNonce(session);
}
+ String claimJson = claims != null ? claims.toString() : "";
+
conn = httpConnector.openConnection(url, session.getProxy());
conn.setRequestMethod("POST");
- conn.setRequestProperty(ACCEPT_HEADER, MIME_JSON);
+ conn.setRequestProperty(ACCEPT_HEADER, accept);
conn.setRequestProperty(ACCEPT_CHARSET_HEADER, DEFAULT_CHARSET);
conn.setRequestProperty(ACCEPT_LANGUAGE_HEADER, session.getLocale().toLanguageTag());
conn.setRequestProperty(CONTENT_TYPE_HEADER, "application/jose+json");
@@ -350,7 +359,7 @@ public class DefaultConnection implements Connection {
final PublicJsonWebKey jwk = PublicJsonWebKey.Factory.newPublicJwk(keypair.getPublic());
JsonWebSignature jws = new JsonWebSignature();
- jws.setPayload(claims.toString());
+ jws.setPayload(claimJson);
jws.getHeaders().setObjectHeaderValue("nonce", session.getNonce());
jws.getHeaders().setObjectHeaderValue("url", url);
if (accountLocation == null) {
@@ -364,8 +373,10 @@ public class DefaultConnection implements Connection {
jws.sign();
if (LOG.isDebugEnabled()) {
- LOG.debug("POST {}", url);
- LOG.debug(" Payload: {}", claims.toString());
+ LOG.debug("{} {}", claims != null ? "POST" : "POST-as-GET", url);
+ if (claims != null) {
+ LOG.debug(" Payload: {}", claimJson);
+ }
LOG.debug(" JWS Header: {}", jws.getHeaders().getFullHeaderAsJsonString());
}
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/connector/ResourceIterator.java b/acme4j-client/src/main/java/org/shredzone/acme4j/connector/ResourceIterator.java
index 9357ffb9..c3d68b80 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/connector/ResourceIterator.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/connector/ResourceIterator.java
@@ -145,7 +145,7 @@ public class ResourceIterator implements Iterator {
private void readAndQueue() throws AcmeException {
Session session = login.getSession();
try (Connection conn = session.provider().connect()) {
- conn.sendRequest(nextUrl, session);
+ conn.sendSignedPostAsGetRequest(nextUrl, login);
JSON json = conn.readJsonResponse();
if (json != null) {
diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java
index b9e549e5..ada081c5 100644
--- a/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java
+++ b/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java
@@ -72,12 +72,13 @@ public class AccountTest {
}
@Override
- public void sendRequest(URL url, Session session) {
+ public int sendSignedPostAsGetRequest(URL url, Login login) {
if (url("https://example.com/acme/acct/1/orders").equals(url)) {
jsonResponse = new JSONBuilder()
.array("orders", Arrays.asList("https://example.com/acme/order/1"))
.toJSON();
}
+ return HttpURLConnection.HTTP_OK;
}
@Override
diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/AuthorizationTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/AuthorizationTest.java
index 57182390..871c8123 100644
--- a/acme4j-client/src/test/java/org/shredzone/acme4j/AuthorizationTest.java
+++ b/acme4j-client/src/test/java/org/shredzone/acme4j/AuthorizationTest.java
@@ -92,8 +92,9 @@ public class AuthorizationTest {
public void testUpdate() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
- public void sendRequest(URL url, Session session) {
+ public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl));
+ return HttpURLConnection.HTTP_OK;
}
@Override
@@ -138,8 +139,9 @@ public class AuthorizationTest {
public void testWildcard() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
- public void sendRequest(URL url, Session session) {
+ public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl));
+ return HttpURLConnection.HTTP_OK;
}
@Override
@@ -181,9 +183,10 @@ public class AuthorizationTest {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
- public void sendRequest(URL url, Session session) {
+ public int sendSignedPostAsGetRequest(URL url, Login login) {
requestWasSent.set(true);
assertThat(url, is(locationUrl));
+ return HttpURLConnection.HTTP_OK;
}
@Override
@@ -230,8 +233,9 @@ public class AuthorizationTest {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
- public void sendRequest(URL url, Session session) {
+ public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl));
+ return HttpURLConnection.HTTP_OK;
}
@Override
diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/CertificateTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/CertificateTest.java
index 44221e8b..128f5f24 100644
--- a/acme4j-client/src/test/java/org/shredzone/acme4j/CertificateTest.java
+++ b/acme4j-client/src/test/java/org/shredzone/acme4j/CertificateTest.java
@@ -55,9 +55,10 @@ public class CertificateTest {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
- public void sendCertificateRequest(URL url, Session session) {
+ public int sendCertificateRequest(URL url, Login login) {
assertThat(url, is(locationUrl));
- assertThat(session, is(notNullValue()));
+ assertThat(login, is(notNullValue()));
+ return HttpURLConnection.HTTP_OK;
}
@Override
@@ -124,10 +125,11 @@ public class CertificateTest {
private boolean certRequested = false;
@Override
- public void sendCertificateRequest(URL url, Session session) {
+ public int sendCertificateRequest(URL url, Login login) {
assertThat(url, is(locationUrl));
- assertThat(session, is(notNullValue()));
+ assertThat(login, is(notNullValue()));
certRequested = true;
+ return HttpURLConnection.HTTP_OK;
}
@Override
@@ -171,10 +173,11 @@ public class CertificateTest {
private boolean certRequested = false;
@Override
- public void sendCertificateRequest(URL url, Session session) {
+ public int sendCertificateRequest(URL url, Login login) {
assertThat(url, is(locationUrl));
- assertThat(session, is(notNullValue()));
+ assertThat(login, is(notNullValue()));
certRequested = true;
+ return HttpURLConnection.HTTP_OK;
}
@Override
diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/OrderTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/OrderTest.java
index 9272807f..9003ba4e 100644
--- a/acme4j-client/src/test/java/org/shredzone/acme4j/OrderTest.java
+++ b/acme4j-client/src/test/java/org/shredzone/acme4j/OrderTest.java
@@ -48,8 +48,9 @@ public class OrderTest {
public void testUpdate() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
- public void sendRequest(URL url, Session session) {
+ public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl));
+ return HttpURLConnection.HTTP_OK;
}
@Override
@@ -109,9 +110,10 @@ public class OrderTest {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
- public void sendRequest(URL url, Session session) {
+ public int sendSignedPostAsGetRequest(URL url, Login login) {
requestWasSent.set(true);
assertThat(url, is(locationUrl));
+ return HttpURLConnection.HTTP_OK;
}
@Override
@@ -156,8 +158,9 @@ public class OrderTest {
private boolean isFinalized = false;
@Override
- public void sendRequest(URL url, Session session) {
+ public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl));
+ return HttpURLConnection.HTTP_OK;
}
@Override
@@ -215,8 +218,9 @@ public class OrderTest {
public void testRecurrentUpdate() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
- public void sendRequest(URL url, Session session) {
+ public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl));
+ return HttpURLConnection.HTTP_OK;
}
@Override
diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/challenge/ChallengeTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/challenge/ChallengeTest.java
index 54fcb9e5..605c52af 100644
--- a/acme4j-client/src/test/java/org/shredzone/acme4j/challenge/ChallengeTest.java
+++ b/acme4j-client/src/test/java/org/shredzone/acme4j/challenge/ChallengeTest.java
@@ -28,7 +28,6 @@ import java.time.Instant;
import org.junit.Test;
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.Problem;
-import org.shredzone.acme4j.Session;
import org.shredzone.acme4j.Status;
import org.shredzone.acme4j.exception.AcmeException;
import org.shredzone.acme4j.exception.AcmeProtocolException;
@@ -126,8 +125,9 @@ public class ChallengeTest {
public void testUpdate() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
- public void sendRequest(URL url, Session session) {
+ public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl));
+ return HttpURLConnection.HTTP_OK;
}
@Override
@@ -162,8 +162,9 @@ public class ChallengeTest {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
- public void sendRequest(URL url, Session session) {
+ public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl));
+ return HttpURLConnection.HTTP_OK;
}
@Override
diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/connector/DefaultConnectionTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/connector/DefaultConnectionTest.java
index 55dea37b..43bad46f 100644
--- a/acme4j-client/src/test/java/org/shredzone/acme4j/connector/DefaultConnectionTest.java
+++ b/acme4j-client/src/test/java/org/shredzone/acme4j/connector/DefaultConnectionTest.java
@@ -663,28 +663,6 @@ public class DefaultConnectionTest {
verifyNoMoreInteractions(mockUrlConnection);
}
- /**
- * Test certificate GET requests.
- */
- @Test
- public void testSendCertificateRequest() throws Exception {
- when(mockUrlConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK);
-
- try (DefaultConnection conn = new DefaultConnection(mockHttpConnection)) {
- conn.sendCertificateRequest(requestUrl, session);
- }
-
- verify(mockUrlConnection).setRequestMethod("GET");
- verify(mockUrlConnection).setRequestProperty("Accept", "application/pem-certificate-chain");
- verify(mockUrlConnection).setRequestProperty("Accept-Charset", "utf-8");
- verify(mockUrlConnection).setRequestProperty("Accept-Language", "ja-JP");
- verify(mockUrlConnection).setDoOutput(false);
- verify(mockUrlConnection).connect();
- verify(mockUrlConnection).getResponseCode();
- verify(mockUrlConnection, atLeast(0)).getHeaderFields();
- verifyNoMoreInteractions(mockUrlConnection);
- }
-
/**
* Test signed POST requests.
*/
@@ -760,6 +738,130 @@ public class DefaultConnectionTest {
assertThat(jws.verifySignature(), is(true));
}
+ /**
+ * Test signed POST-as-GET requests.
+ */
+ @Test
+ public void testSendSignedPostAsGetRequest() throws Exception {
+ final String nonce1 = Base64Url.encode("foo-nonce-1-foo".getBytes());
+ final String nonce2 = Base64Url.encode("foo-nonce-2-foo".getBytes());
+ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+ when(mockUrlConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK);
+ when(mockUrlConnection.getOutputStream()).thenReturn(outputStream);
+
+ try (DefaultConnection conn = new DefaultConnection(mockHttpConnection) {
+ @Override
+ public void resetNonce(Session session) {
+ assertThat(session, is(sameInstance(DefaultConnectionTest.this.session)));
+ if (session.getNonce() == null) {
+ session.setNonce(nonce1);
+ } else {
+ fail("unknown nonce");
+ }
+ }
+
+ @Override
+ public String getNonce() {
+ assertThat(session, is(sameInstance(DefaultConnectionTest.this.session)));
+ if (session.getNonce() == nonce1) {
+ return nonce2;
+ } else {
+ fail("unknown nonce");
+ return null;
+ }
+ }
+ }) {
+ conn.sendSignedPostAsGetRequest(requestUrl, login);
+ }
+
+ verify(mockUrlConnection).setRequestMethod("POST");
+ verify(mockUrlConnection).setRequestProperty("Accept", "application/json");
+ verify(mockUrlConnection).setRequestProperty("Accept-Charset", "utf-8");
+ verify(mockUrlConnection).setRequestProperty("Accept-Language", "ja-JP");
+ verify(mockUrlConnection).setRequestProperty("Content-Type", "application/jose+json");
+ verify(mockUrlConnection).connect();
+ verify(mockUrlConnection).setDoOutput(true);
+ verify(mockUrlConnection).setFixedLengthStreamingMode(outputStream.toByteArray().length);
+ verify(mockUrlConnection).getResponseCode();
+ verify(mockUrlConnection).getOutputStream();
+ verify(mockUrlConnection, atLeast(0)).getHeaderFields();
+ verifyNoMoreInteractions(mockUrlConnection);
+
+ JSON data = JSON.parse(new String(outputStream.toByteArray(), "utf-8"));
+ String encodedHeader = data.get("protected").asString();
+ String encodedSignature = data.get("signature").asString();
+ String encodedPayload = data.get("payload").asString();
+
+ StringBuilder expectedHeader = new StringBuilder();
+ expectedHeader.append('{');
+ expectedHeader.append("\"nonce\":\"").append(nonce1).append("\",");
+ expectedHeader.append("\"url\":\"").append(requestUrl).append("\",");
+ expectedHeader.append("\"alg\":\"RS256\",");
+ expectedHeader.append("\"kid\":\"").append(accountUrl).append('"');
+ expectedHeader.append('}');
+
+ assertThat(Base64Url.decodeToUtf8String(encodedHeader), sameJSONAs(expectedHeader.toString()));
+ assertThat(Base64Url.decodeToUtf8String(encodedPayload), is(""));
+ assertThat(encodedSignature, not(isEmptyOrNullString()));
+
+ JsonWebSignature jws = new JsonWebSignature();
+ jws.setCompactSerialization(CompactSerializer.serialize(encodedHeader, encodedPayload, encodedSignature));
+ jws.setKey(login.getKeyPair().getPublic());
+ assertThat(jws.verifySignature(), is(true));
+ }
+
+ /**
+ * Test certificate POST-as-GET requests.
+ */
+ @Test
+ public void testSendCertificateRequest() throws Exception {
+ final String nonce1 = Base64Url.encode("foo-nonce-1-foo".getBytes());
+ final String nonce2 = Base64Url.encode("foo-nonce-2-foo".getBytes());
+ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+ when(mockUrlConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK);
+ when(mockUrlConnection.getOutputStream()).thenReturn(outputStream);
+
+ try (DefaultConnection conn = new DefaultConnection(mockHttpConnection) {
+ @Override
+ public void resetNonce(Session session) {
+ assertThat(session, is(sameInstance(DefaultConnectionTest.this.session)));
+ if (session.getNonce() == null) {
+ session.setNonce(nonce1);
+ } else {
+ fail("unknown nonce");
+ }
+ }
+
+ @Override
+ public String getNonce() {
+ assertThat(session, is(sameInstance(DefaultConnectionTest.this.session)));
+ if (session.getNonce() == nonce1) {
+ return nonce2;
+ } else {
+ fail("unknown nonce");
+ return null;
+ }
+ }
+ }) {
+ conn.sendCertificateRequest(requestUrl, login);
+ }
+
+ verify(mockUrlConnection).setRequestMethod("POST");
+ verify(mockUrlConnection).setRequestProperty("Accept", "application/pem-certificate-chain");
+ verify(mockUrlConnection).setRequestProperty("Accept-Charset", "utf-8");
+ verify(mockUrlConnection).setRequestProperty("Accept-Language", "ja-JP");
+ verify(mockUrlConnection).setRequestProperty("Content-Type", "application/jose+json");
+ verify(mockUrlConnection).setDoOutput(true);
+ verify(mockUrlConnection).connect();
+ verify(mockUrlConnection).setFixedLengthStreamingMode(outputStream.toByteArray().length);
+ verify(mockUrlConnection).getResponseCode();
+ verify(mockUrlConnection).getOutputStream();
+ verify(mockUrlConnection, atLeast(0)).getHeaderFields();
+ verifyNoMoreInteractions(mockUrlConnection);
+ }
+
/**
* Test signed POST requests without KeyIdentifier.
*/
diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/connector/DummyConnection.java b/acme4j-client/src/test/java/org/shredzone/acme4j/connector/DummyConnection.java
index f3821134..3c3c0294 100644
--- a/acme4j-client/src/test/java/org/shredzone/acme4j/connector/DummyConnection.java
+++ b/acme4j-client/src/test/java/org/shredzone/acme4j/connector/DummyConnection.java
@@ -42,7 +42,12 @@ public class DummyConnection implements Connection {
}
@Override
- public void sendCertificateRequest(URL url, Session session) throws AcmeException {
+ public int sendCertificateRequest(URL url, Login login) throws AcmeException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int sendSignedPostAsGetRequest(URL url, Login login) throws AcmeException {
throw new UnsupportedOperationException();
}
diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/connector/ResourceIteratorTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/connector/ResourceIteratorTest.java
index 7d3170c7..c9904981 100644
--- a/acme4j-client/src/test/java/org/shredzone/acme4j/connector/ResourceIteratorTest.java
+++ b/acme4j-client/src/test/java/org/shredzone/acme4j/connector/ResourceIteratorTest.java
@@ -18,6 +18,7 @@ import static org.junit.Assert.assertThat;
import static org.shredzone.acme4j.toolbox.TestUtils.url;
import java.io.IOException;
+import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
@@ -31,7 +32,6 @@ import org.junit.Before;
import org.junit.Test;
import org.shredzone.acme4j.Authorization;
import org.shredzone.acme4j.Login;
-import org.shredzone.acme4j.Session;
import org.shredzone.acme4j.provider.TestableConnectionProvider;
import org.shredzone.acme4j.toolbox.JSON;
import org.shredzone.acme4j.toolbox.JSONBuilder;
@@ -134,9 +134,10 @@ public class ResourceIteratorTest {
private int ix;
@Override
- public void sendRequest(URL url, Session session) {
+ public int sendSignedPostAsGetRequest(URL url, Login login) {
ix = pageURLs.indexOf(url);
assertThat(ix, is(greaterThanOrEqualTo(0)));
+ return HttpURLConnection.HTTP_OK;
}
@Override