Send POST-as-GET requests

pull/81/head
Richard Körber 2018-09-26 19:24:20 +02:00
parent 5098b5364b
commit 1297ca4de2
No known key found for this signature in database
GPG Key ID: AAB9FD19C78AA3E0
13 changed files with 226 additions and 75 deletions

View File

@ -116,7 +116,7 @@ public abstract class AcmeJsonResource extends AcmeResource {
String resourceType = getClass().getSimpleName(); String resourceType = getClass().getSimpleName();
LOG.debug("update {}", resourceType); LOG.debug("update {}", resourceType);
try (Connection conn = connect()) { try (Connection conn = connect()) {
conn.sendRequest(getLocation(), getSession()); conn.sendSignedPostAsGetRequest(getLocation(), getLogin());
JSON json = conn.readJsonResponse(); JSON json = conn.readJsonResponse();
if (json != null) { if (json != null) {
setJSON(json); setJSON(json);

View File

@ -71,7 +71,7 @@ public class Certificate extends AcmeResource {
if (certChain == null) { if (certChain == null) {
LOG.debug("download"); LOG.debug("download");
try (Connection conn = connect()) { try (Connection conn = connect()) {
conn.sendCertificateRequest(getLocation(), getSession()); conn.sendCertificateRequest(getLocation(), getLogin());
alternates = new ArrayList<>(conn.getLinks("alternate")); alternates = new ArrayList<>(conn.getLinks("alternate"));
certChain = new ArrayList<>(conn.readCertificates()); certChain = new ArrayList<>(conn.readCertificates());
} }

View File

@ -58,17 +58,36 @@ public interface Connection extends AutoCloseable {
void sendRequest(URL url, Session session) throws AcmeException; 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.
* <p> * <p>
* If the response code was not {@link HttpURLConnection#HTTP_OK}, an * If the server does not return a 200 class status code, an {@link AcmeException} is
* {@link AcmeException} matching the error is raised. * raised matching the error.
* *
* @param url * @param url
* {@link URL} to send the request to. * {@link URL} to send the request to.
* @param session * @param login
* {@link Session} instance to be used for tracking * {@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.
* <p>
* 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 * Sends a signed POST request. Requires a {@link Login} for the session and

View File

@ -137,15 +137,6 @@ public class DefaultConnection implements Connection {
@Override @Override
public void sendRequest(URL url, Session session) throws AcmeException { 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(url, "url");
Objects.requireNonNull(session, "session"); Objects.requireNonNull(session, "session");
assertConnectionIsClosed(); assertConnectionIsClosed();
@ -155,7 +146,7 @@ public class DefaultConnection implements Connection {
try { try {
conn = httpConnector.openConnection(url, session.getProxy()); conn = httpConnector.openConnection(url, session.getProxy());
conn.setRequestMethod("GET"); conn.setRequestMethod("GET");
conn.setRequestProperty(ACCEPT_HEADER, accept); conn.setRequestProperty(ACCEPT_HEADER, MIME_JSON);
conn.setRequestProperty(ACCEPT_CHARSET_HEADER, DEFAULT_CHARSET); conn.setRequestProperty(ACCEPT_CHARSET_HEADER, DEFAULT_CHARSET);
conn.setRequestProperty(ACCEPT_LANGUAGE_HEADER, session.getLocale().toLanguageTag()); conn.setRequestProperty(ACCEPT_LANGUAGE_HEADER, session.getLocale().toLanguageTag());
conn.setDoOutput(false); 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 @Override
public int sendSignedRequest(URL url, JSONBuilder claims, Login login) throws AcmeException { 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 @Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, KeyPair keypair) public int sendSignedRequest(URL url, JSONBuilder claims, Session session, KeyPair keypair)
throws AcmeException { 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) private int sendSignedRequest(URL url, @Nullable JSONBuilder claims, Session session,
throws AcmeException { KeyPair keypair, @Nullable URL accountLocation, String accept) throws AcmeException {
Objects.requireNonNull(url, "url"); Objects.requireNonNull(url, "url");
Objects.requireNonNull(claims, "claims");
Objects.requireNonNull(session, "session"); Objects.requireNonNull(session, "session");
Objects.requireNonNull(keypair, "keypair"); Objects.requireNonNull(keypair, "keypair");
Objects.requireNonNull(accept, "accept");
assertConnectionIsClosed(); assertConnectionIsClosed();
AcmeException lastException = null; AcmeException lastException = null;
for (int attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) { for (int attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
try { try {
return performRequest(url, claims, session, keypair, accountLocation); return performRequest(url, claims, session, keypair, accountLocation, accept);
} catch (AcmeServerException ex) { } catch (AcmeServerException ex) {
if (!BAD_NONCE_ERROR.equals(ex.getType())) { if (!BAD_NONCE_ERROR.equals(ex.getType())) {
throw ex; throw ex;
@ -322,7 +326,8 @@ public class DefaultConnection implements Connection {
* @param url * @param url
* {@link URL} to send the request to. * {@link URL} to send the request to.
* @param claims * @param claims
* {@link JSONBuilder} containing claims. Must not be {@code null}. * {@link JSONBuilder} containing claims. {@code null} for POST-as-GET
* request.
* @param session * @param session
* {@link Session} instance to be used for signing and tracking * {@link Session} instance to be used for signing and tracking
* @param keypair * @param keypair
@ -330,19 +335,23 @@ public class DefaultConnection implements Connection {
* @param accountLocation * @param accountLocation
* If set, the account location is set as "kid" header. If {@code null}, * If set, the account location is set as "kid" header. If {@code null},
* the public key is set as "jwk" header. * the public key is set as "jwk" header.
* @param accept
* Accept header
* @return HTTP 200 class status that was returned * @return HTTP 200 class status that was returned
*/ */
private int performRequest(URL url, JSONBuilder claims, Session session, KeyPair keypair, private int performRequest(URL url, @Nullable JSONBuilder claims, Session session,
@Nullable URL accountLocation) KeyPair keypair, @Nullable URL accountLocation, String accept)
throws AcmeException { throws AcmeException {
try { try {
if (session.getNonce() == null) { if (session.getNonce() == null) {
resetNonce(session); resetNonce(session);
} }
String claimJson = claims != null ? claims.toString() : "";
conn = httpConnector.openConnection(url, session.getProxy()); conn = httpConnector.openConnection(url, session.getProxy());
conn.setRequestMethod("POST"); conn.setRequestMethod("POST");
conn.setRequestProperty(ACCEPT_HEADER, MIME_JSON); conn.setRequestProperty(ACCEPT_HEADER, accept);
conn.setRequestProperty(ACCEPT_CHARSET_HEADER, DEFAULT_CHARSET); conn.setRequestProperty(ACCEPT_CHARSET_HEADER, DEFAULT_CHARSET);
conn.setRequestProperty(ACCEPT_LANGUAGE_HEADER, session.getLocale().toLanguageTag()); conn.setRequestProperty(ACCEPT_LANGUAGE_HEADER, session.getLocale().toLanguageTag());
conn.setRequestProperty(CONTENT_TYPE_HEADER, "application/jose+json"); 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()); final PublicJsonWebKey jwk = PublicJsonWebKey.Factory.newPublicJwk(keypair.getPublic());
JsonWebSignature jws = new JsonWebSignature(); JsonWebSignature jws = new JsonWebSignature();
jws.setPayload(claims.toString()); jws.setPayload(claimJson);
jws.getHeaders().setObjectHeaderValue("nonce", session.getNonce()); jws.getHeaders().setObjectHeaderValue("nonce", session.getNonce());
jws.getHeaders().setObjectHeaderValue("url", url); jws.getHeaders().setObjectHeaderValue("url", url);
if (accountLocation == null) { if (accountLocation == null) {
@ -364,8 +373,10 @@ public class DefaultConnection implements Connection {
jws.sign(); jws.sign();
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("POST {}", url); LOG.debug("{} {}", claims != null ? "POST" : "POST-as-GET", url);
LOG.debug(" Payload: {}", claims.toString()); if (claims != null) {
LOG.debug(" Payload: {}", claimJson);
}
LOG.debug(" JWS Header: {}", jws.getHeaders().getFullHeaderAsJsonString()); LOG.debug(" JWS Header: {}", jws.getHeaders().getFullHeaderAsJsonString());
} }

View File

@ -145,7 +145,7 @@ public class ResourceIterator<T extends AcmeResource> implements Iterator<T> {
private void readAndQueue() throws AcmeException { private void readAndQueue() throws AcmeException {
Session session = login.getSession(); Session session = login.getSession();
try (Connection conn = session.provider().connect()) { try (Connection conn = session.provider().connect()) {
conn.sendRequest(nextUrl, session); conn.sendSignedPostAsGetRequest(nextUrl, login);
JSON json = conn.readJsonResponse(); JSON json = conn.readJsonResponse();
if (json != null) { if (json != null) {

View File

@ -72,12 +72,13 @@ public class AccountTest {
} }
@Override @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)) { if (url("https://example.com/acme/acct/1/orders").equals(url)) {
jsonResponse = new JSONBuilder() jsonResponse = new JSONBuilder()
.array("orders", Arrays.asList("https://example.com/acme/order/1")) .array("orders", Arrays.asList("https://example.com/acme/order/1"))
.toJSON(); .toJSON();
} }
return HttpURLConnection.HTTP_OK;
} }
@Override @Override

View File

@ -92,8 +92,9 @@ public class AuthorizationTest {
public void testUpdate() throws Exception { public void testUpdate() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() { TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override @Override
public void sendRequest(URL url, Session session) { public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl)); assertThat(url, is(locationUrl));
return HttpURLConnection.HTTP_OK;
} }
@Override @Override
@ -138,8 +139,9 @@ public class AuthorizationTest {
public void testWildcard() throws Exception { public void testWildcard() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() { TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override @Override
public void sendRequest(URL url, Session session) { public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl)); assertThat(url, is(locationUrl));
return HttpURLConnection.HTTP_OK;
} }
@Override @Override
@ -181,9 +183,10 @@ public class AuthorizationTest {
TestableConnectionProvider provider = new TestableConnectionProvider() { TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override @Override
public void sendRequest(URL url, Session session) { public int sendSignedPostAsGetRequest(URL url, Login login) {
requestWasSent.set(true); requestWasSent.set(true);
assertThat(url, is(locationUrl)); assertThat(url, is(locationUrl));
return HttpURLConnection.HTTP_OK;
} }
@Override @Override
@ -230,8 +233,9 @@ public class AuthorizationTest {
TestableConnectionProvider provider = new TestableConnectionProvider() { TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override @Override
public void sendRequest(URL url, Session session) { public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl)); assertThat(url, is(locationUrl));
return HttpURLConnection.HTTP_OK;
} }
@Override @Override

View File

@ -55,9 +55,10 @@ public class CertificateTest {
TestableConnectionProvider provider = new TestableConnectionProvider() { TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override @Override
public void sendCertificateRequest(URL url, Session session) { public int sendCertificateRequest(URL url, Login login) {
assertThat(url, is(locationUrl)); assertThat(url, is(locationUrl));
assertThat(session, is(notNullValue())); assertThat(login, is(notNullValue()));
return HttpURLConnection.HTTP_OK;
} }
@Override @Override
@ -124,10 +125,11 @@ public class CertificateTest {
private boolean certRequested = false; private boolean certRequested = false;
@Override @Override
public void sendCertificateRequest(URL url, Session session) { public int sendCertificateRequest(URL url, Login login) {
assertThat(url, is(locationUrl)); assertThat(url, is(locationUrl));
assertThat(session, is(notNullValue())); assertThat(login, is(notNullValue()));
certRequested = true; certRequested = true;
return HttpURLConnection.HTTP_OK;
} }
@Override @Override
@ -171,10 +173,11 @@ public class CertificateTest {
private boolean certRequested = false; private boolean certRequested = false;
@Override @Override
public void sendCertificateRequest(URL url, Session session) { public int sendCertificateRequest(URL url, Login login) {
assertThat(url, is(locationUrl)); assertThat(url, is(locationUrl));
assertThat(session, is(notNullValue())); assertThat(login, is(notNullValue()));
certRequested = true; certRequested = true;
return HttpURLConnection.HTTP_OK;
} }
@Override @Override

View File

@ -48,8 +48,9 @@ public class OrderTest {
public void testUpdate() throws Exception { public void testUpdate() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() { TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override @Override
public void sendRequest(URL url, Session session) { public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl)); assertThat(url, is(locationUrl));
return HttpURLConnection.HTTP_OK;
} }
@Override @Override
@ -109,9 +110,10 @@ public class OrderTest {
TestableConnectionProvider provider = new TestableConnectionProvider() { TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override @Override
public void sendRequest(URL url, Session session) { public int sendSignedPostAsGetRequest(URL url, Login login) {
requestWasSent.set(true); requestWasSent.set(true);
assertThat(url, is(locationUrl)); assertThat(url, is(locationUrl));
return HttpURLConnection.HTTP_OK;
} }
@Override @Override
@ -156,8 +158,9 @@ public class OrderTest {
private boolean isFinalized = false; private boolean isFinalized = false;
@Override @Override
public void sendRequest(URL url, Session session) { public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl)); assertThat(url, is(locationUrl));
return HttpURLConnection.HTTP_OK;
} }
@Override @Override
@ -215,8 +218,9 @@ public class OrderTest {
public void testRecurrentUpdate() throws Exception { public void testRecurrentUpdate() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() { TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override @Override
public void sendRequest(URL url, Session session) { public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl)); assertThat(url, is(locationUrl));
return HttpURLConnection.HTTP_OK;
} }
@Override @Override

View File

@ -28,7 +28,6 @@ import java.time.Instant;
import org.junit.Test; import org.junit.Test;
import org.shredzone.acme4j.Login; import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.Problem; import org.shredzone.acme4j.Problem;
import org.shredzone.acme4j.Session;
import org.shredzone.acme4j.Status; import org.shredzone.acme4j.Status;
import org.shredzone.acme4j.exception.AcmeException; import org.shredzone.acme4j.exception.AcmeException;
import org.shredzone.acme4j.exception.AcmeProtocolException; import org.shredzone.acme4j.exception.AcmeProtocolException;
@ -126,8 +125,9 @@ public class ChallengeTest {
public void testUpdate() throws Exception { public void testUpdate() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() { TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override @Override
public void sendRequest(URL url, Session session) { public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl)); assertThat(url, is(locationUrl));
return HttpURLConnection.HTTP_OK;
} }
@Override @Override
@ -162,8 +162,9 @@ public class ChallengeTest {
TestableConnectionProvider provider = new TestableConnectionProvider() { TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override @Override
public void sendRequest(URL url, Session session) { public int sendSignedPostAsGetRequest(URL url, Login login) {
assertThat(url, is(locationUrl)); assertThat(url, is(locationUrl));
return HttpURLConnection.HTTP_OK;
} }
@Override @Override

View File

@ -663,28 +663,6 @@ public class DefaultConnectionTest {
verifyNoMoreInteractions(mockUrlConnection); 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. * Test signed POST requests.
*/ */
@ -760,6 +738,130 @@ public class DefaultConnectionTest {
assertThat(jws.verifySignature(), is(true)); 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. * Test signed POST requests without KeyIdentifier.
*/ */

View File

@ -42,7 +42,12 @@ public class DummyConnection implements Connection {
} }
@Override @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(); throw new UnsupportedOperationException();
} }

View File

@ -18,6 +18,7 @@ import static org.junit.Assert.assertThat;
import static org.shredzone.acme4j.toolbox.TestUtils.url; import static org.shredzone.acme4j.toolbox.TestUtils.url;
import java.io.IOException; import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -31,7 +32,6 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.shredzone.acme4j.Authorization; import org.shredzone.acme4j.Authorization;
import org.shredzone.acme4j.Login; import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.Session;
import org.shredzone.acme4j.provider.TestableConnectionProvider; import org.shredzone.acme4j.provider.TestableConnectionProvider;
import org.shredzone.acme4j.toolbox.JSON; import org.shredzone.acme4j.toolbox.JSON;
import org.shredzone.acme4j.toolbox.JSONBuilder; import org.shredzone.acme4j.toolbox.JSONBuilder;
@ -134,9 +134,10 @@ public class ResourceIteratorTest {
private int ix; private int ix;
@Override @Override
public void sendRequest(URL url, Session session) { public int sendSignedPostAsGetRequest(URL url, Login login) {
ix = pageURLs.indexOf(url); ix = pageURLs.indexOf(url);
assertThat(ix, is(greaterThanOrEqualTo(0))); assertThat(ix, is(greaterThanOrEqualTo(0)));
return HttpURLConnection.HTTP_OK;
} }
@Override @Override