Relax HTTP status handling

pull/61/head
Richard Körber 2018-02-21 19:59:01 +01:00
parent 0d42089318
commit a111187245
No known key found for this signature in database
GPG Key ID: AAB9FD19C78AA3E0
14 changed files with 32 additions and 96 deletions

View File

@ -16,7 +16,6 @@ package org.shredzone.acme4j;
import static java.util.stream.Collectors.toList;
import static org.shredzone.acme4j.toolbox.AcmeUtils.*;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.security.KeyPair;
@ -168,7 +167,7 @@ public class Account extends AcmeJsonResource {
.put("type", "dns")
.put("value", toAce(domain));
conn.sendSignedRequest(newAuthzUrl, claims, getSession(), HttpURLConnection.HTTP_CREATED);
conn.sendSignedRequest(newAuthzUrl, claims, getSession());
Authorization auth = new Authorization(getSession(), conn.getLocation());
auth.setJSON(conn.readJsonResponse());

View File

@ -16,7 +16,6 @@ package org.shredzone.acme4j;
import static java.util.Objects.requireNonNull;
import static org.shredzone.acme4j.toolbox.AcmeUtils.macKeyAlgorithm;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.security.PublicKey;
@ -177,15 +176,12 @@ public class AccountBuilder {
claims.put("onlyReturnExisting", onlyExisting);
}
int resp = conn.sendSignedRequest(resourceUrl, claims, session, true, HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_CREATED);
conn.sendSignedRequest(resourceUrl, claims, session, true);
URL location = conn.getLocation();
Account account = new Account(session, location);
if (resp == HttpURLConnection.HTTP_CREATED) {
account.setJSON(conn.readJsonResponse());
}
account.setJSON(conn.readJsonResponse());
return account;
}
}

View File

@ -16,7 +16,6 @@ package org.shredzone.acme4j;
import static java.util.Objects.requireNonNull;
import static org.shredzone.acme4j.toolbox.AcmeUtils.toAce;
import java.net.HttpURLConnection;
import java.time.Instant;
import java.util.Collection;
import java.util.Iterator;
@ -147,7 +146,7 @@ public class OrderBuilder {
claims.put("notAfter", notAfter);
}
conn.sendSignedRequest(session.resourceUrl(Resource.NEW_ORDER), claims, session, HttpURLConnection.HTTP_CREATED);
conn.sendSignedRequest(session.resourceUrl(Resource.NEW_ORDER), claims, session);
Order order = new Order(session, conn.getLocation());
order.setJSON(conn.readJsonResponse());

View File

@ -61,11 +61,9 @@ public interface Connection extends AutoCloseable {
* {@link JSONBuilder} containing claims. Must not be {@code null}.
* @param session
* {@link Session} instance to be used for signing and tracking
* @param httpStatus
* Acceptable HTTP states. 200 OK if empty.
* @return HTTP 200 class status that was returned
*/
int sendSignedRequest(URL url, JSONBuilder claims, Session session, int... httpStatus)
int sendSignedRequest(URL url, JSONBuilder claims, Session session)
throws AcmeException;
/**
@ -85,11 +83,9 @@ public interface Connection extends AutoCloseable {
* {@code true} to enforce a "jwk" header field even if a KeyIdentifier is
* set, {@code false} to choose between "kid" and "jwk" header field
* automatically
* @param httpStatus
* Acceptable HTTP states. 200 OK if empty.
* @return HTTP 200 class status that was returned
*/
int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk, int... httpStatus)
int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk)
throws AcmeException;
/**

View File

@ -30,7 +30,6 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
@ -154,12 +153,12 @@ public class DefaultConnection implements Connection {
}
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, int... httpStatus) throws AcmeException {
return sendSignedRequest(url, claims, session, false, httpStatus);
public int sendSignedRequest(URL url, JSONBuilder claims, Session session) throws AcmeException {
return sendSignedRequest(url, claims, session, false);
}
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk, int... httpStatus)
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk)
throws AcmeException {
Objects.requireNonNull(url, "url");
Objects.requireNonNull(claims, "claims");
@ -170,7 +169,7 @@ public class DefaultConnection implements Connection {
for (int attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
try {
return performRequest(url, claims, session, enforceJwk, httpStatus);
return performRequest(url, claims, session, enforceJwk);
} catch (AcmeServerException ex) {
if (!BAD_NONCE_ERROR.equals(ex.getType())) {
throw ex;
@ -296,11 +295,9 @@ public class DefaultConnection implements Connection {
* {@code true} to enforce a "jwk" header field even if a KeyIdentifier is
* set, {@code false} to choose between "kid" and "jwk" header field
* automatically
* @param httpStatus
* Acceptable HTTP states. 200 OK if empty.
* @return HTTP 200 class status that was returned
*/
private int performRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk, int... httpStatus)
private int performRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk)
throws AcmeException {
try {
KeyPair keypair = session.getKeyPair();
@ -356,8 +353,7 @@ public class DefaultConnection implements Connection {
session.setNonce(getNonce());
int rc = conn.getResponseCode();
if ((httpStatus.length == 0 && rc != HttpURLConnection.HTTP_OK)
|| (httpStatus.length > 0 && !Arrays.stream(httpStatus).filter(s -> s == rc).findFirst().isPresent())) {
if (rc != HttpURLConnection.HTTP_OK && rc != HttpURLConnection.HTTP_CREATED) {
throwAcmeException();
}
return rc;

View File

@ -51,23 +51,21 @@ public class AccountBuilderTest {
private boolean isUpdate;
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session) {
assertThat(session, is(notNullValue()));
assertThat(url, is(locationUrl));
assertThat(isUpdate, is(false));
isUpdate = true;
assertThat(httpStatus, isIntArrayContainingInAnyOrder());
return HttpURLConnection.HTTP_OK;
}
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk) {
assertThat(session, is(notNullValue()));
assertThat(url, is(resourceUrl));
assertThat(claims.toString(), sameJSONAs(getJSON("newAccount").toString()));
assertThat(enforceJwk, is(true));
isUpdate = false;
assertThat(httpStatus, isIntArrayContainingInAnyOrder(HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_CREATED));
return HttpURLConnection.HTTP_CREATED;
}
@ -117,7 +115,7 @@ public class AccountBuilderTest {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk) {
try {
assertThat(session, is(notNullValue()));
assertThat(url, is(resourceUrl));
@ -155,7 +153,6 @@ public class AccountBuilderTest {
fail("decoding inner payload failed");
}
assertThat(httpStatus, isIntArrayContainingInAnyOrder(HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_CREATED));
return HttpURLConnection.HTTP_CREATED;
}
@ -190,12 +187,11 @@ public class AccountBuilderTest {
public void testOnlyExistingRegistration() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk) {
assertThat(session, is(notNullValue()));
assertThat(url, is(resourceUrl));
assertThat(claims.toString(), sameJSONAs(getJSON("newAccountOnlyExisting").toString()));
assertThat(enforceJwk, is(true));
assertThat(httpStatus, isIntArrayContainingInAnyOrder(HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_CREATED));
return HttpURLConnection.HTTP_OK;
}

View File

@ -64,7 +64,7 @@ public class AccountTest {
private JSON jsonResponse;
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session) {
assertThat(url, is(locationUrl));
assertThat(claims.toString(), sameJSONAs(getJSON("updateAccount").toString()));
assertThat(session, is(notNullValue()));
@ -125,10 +125,9 @@ public class AccountTest {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session) {
requestWasSent.set(true);
assertThat(url, is(locationUrl));
assertThat(httpStatus, isIntArrayContainingInAnyOrder());
return HttpURLConnection.HTTP_OK;
}
@ -174,11 +173,10 @@ public class AccountTest {
public void testPreAuthorizeDomain() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session) {
assertThat(url, is(resourceUrl));
assertThat(claims.toString(), sameJSONAs(getJSON("newAuthorizationRequest").toString()));
assertThat(session, is(notNullValue()));
assertThat(httpStatus, isIntArrayContainingInAnyOrder(HttpURLConnection.HTTP_CREATED));
return HttpURLConnection.HTTP_CREATED;
}
@ -226,7 +224,7 @@ public class AccountTest {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, int... httpStatus) throws AcmeException {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session) throws AcmeException {
assertThat(url, is(resourceUrl));
assertThat(claims.toString(), sameJSONAs(getJSON("newAuthorizationRequest").toString()));
assertThat(session, is(notNullValue()));
@ -300,7 +298,7 @@ public class AccountTest {
final TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
public int sendSignedRequest(URL url, JSONBuilder payload, Session session, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder payload, Session session) {
try {
assertThat(url, is(locationUrl));
assertThat(session, is(notNullValue()));
@ -332,7 +330,6 @@ public class AccountTest {
fail("decoding inner payload failed");
}
assertThat(httpStatus, isIntArrayContainingInAnyOrder());
return HttpURLConnection.HTTP_OK;
}
@ -380,12 +377,11 @@ public class AccountTest {
public void testDeactivate() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session) {
JSON json = claims.toJSON();
assertThat(json.get("status").asString(), is("deactivated"));
assertThat(url, is(locationUrl));
assertThat(session, is(notNullValue()));
assertThat(httpStatus, isIntArrayContainingInAnyOrder());
return HttpURLConnection.HTTP_OK;
}
@ -410,11 +406,10 @@ public class AccountTest {
public void testModify() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session) {
assertThat(url, is(locationUrl));
assertThat(claims.toString(), sameJSONAs(getJSON("modifyAccount").toString()));
assertThat(session, is(notNullValue()));
assertThat(httpStatus, isIntArrayContainingInAnyOrder());
return HttpURLConnection.HTTP_OK;
}

View File

@ -224,12 +224,11 @@ public class AuthorizationTest {
public void testDeactivate() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session) {
JSON json = claims.toJSON();
assertThat(json.get("status").asString(), is("deactivated"));
assertThat(url, is(locationUrl));
assertThat(session, is(notNullValue()));
assertThat(httpStatus, isIntArrayContainingInAnyOrder());
return HttpURLConnection.HTTP_OK;
}

View File

@ -132,14 +132,13 @@ public class CertificateTest {
}
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk) {
assertThat(url, is(resourceUrl));
assertThat(claims.toString(), sameJSONAs(getJSON("revokeCertificateRequest").toString()));
assertThat(session, is(notNullValue()));
assertThat(session.getAccountLocation(), is(nullValue()));
assertThat(enforceJwk, is(true));
certRequested = false;
assertThat(httpStatus, isIntArrayContainingInAnyOrder());
return HttpURLConnection.HTTP_OK;
}
@ -182,13 +181,12 @@ public class CertificateTest {
}
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk) {
assertThat(url, is(resourceUrl));
assertThat(claims.toString(), sameJSONAs(getJSON("revokeCertificateWithReasonRequest").toString()));
assertThat(session, is(notNullValue()));
assertThat(enforceJwk, is(true));
certRequested = false;
assertThat(httpStatus, isIntArrayContainingInAnyOrder());
return HttpURLConnection.HTTP_OK;
}
@ -232,14 +230,13 @@ public class CertificateTest {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk, int... httpStatus)
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk)
throws AcmeException {
assertThat(url, is(resourceUrl));
assertThat(claims.toString(), sameJSONAs(getJSON("revokeCertificateWithReasonRequest").toString()));
assertThat(session, is(notNullValue()));
assertThat(session.getKeyPair(), is(certKeyPair));
assertThat(enforceJwk, is(true));
assertThat(httpStatus, isIntArrayContainingInAnyOrder());
return HttpURLConnection.HTTP_OK;
}
};

View File

@ -48,11 +48,10 @@ public class OrderBuilderTest {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session) {
assertThat(url, is(resourceUrl));
assertThat(claims.toString(), sameJSONAs(getJSON("requestOrderRequest").toString()));
assertThat(session, is(notNullValue()));
assertThat(httpStatus, isIntArrayContainingInAnyOrder(HttpURLConnection.HTTP_CREATED));
return HttpURLConnection.HTTP_CREATED;
}

View File

@ -151,12 +151,11 @@ public class OrderTest {
}
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session) {
assertThat(url, is(finalizeUrl));
assertThat(claims.toString(), sameJSONAs(getJSON("finalizeRequest").toString()));
assertThat(session, is(notNullValue()));
isFinalized = true;
assertThat(httpStatus, isIntArrayContainingInAnyOrder());
return HttpURLConnection.HTTP_OK;
}

View File

@ -136,11 +136,10 @@ public class ChallengeTest {
public void testTrigger() throws Exception {
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, int... httpStatus) {
public int sendSignedRequest(URL url, JSONBuilder claims, Session session) {
assertThat(url, is(locationUrl));
assertThat(claims.toString(), sameJSONAs(getJSON("triggerHttpChallengeRequest").toString()));
assertThat(session, is(notNullValue()));
assertThat(httpStatus, isIntArrayContainingInAnyOrder());
return HttpURLConnection.HTTP_OK;
}

View File

@ -40,13 +40,13 @@ public class DummyConnection implements Connection {
}
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, int... httpStatus)
public int sendSignedRequest(URL url, JSONBuilder claims, Session session)
throws AcmeException {
throw new UnsupportedOperationException();
}
@Override
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk, int... httpStatus)
public int sendSignedRequest(URL url, JSONBuilder claims, Session session, boolean enforceJwk)
throws AcmeException {
throw new UnsupportedOperationException();
}

View File

@ -40,16 +40,12 @@ import java.security.spec.ECGenParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.crypto.SecretKey;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.jose4j.base64url.Base64Url;
import org.jose4j.json.JsonUtil;
import org.jose4j.jwk.JsonWebKey;
@ -262,36 +258,6 @@ public final class TestUtils {
}
}
/**
* Creates a matcher that matches an array of int primitives. The array must contain
* exactly all of the given values, in any order.
*
* @param values
* Values to test against
* @return {@link Matcher}
*/
public static Matcher<int[]> isIntArrayContainingInAnyOrder(int... values) {
final int[] reference = values;
Arrays.sort(reference);
return new BaseMatcher<int[]>() {
@Override
public boolean matches(Object item) {
if (!(item instanceof int[])) {
return false;
}
int[] items = (int[]) item;
Arrays.sort(items);
return Arrays.equals(items, reference);
}
@Override
public void describeTo(Description description) {
description.appendValue(Arrays.toString(reference));
}
};
}
/**
* Creates a {@link Problem} with the given type and details.
*