mirror of https://github.com/shred/acme4j
parent
d666ec091c
commit
1289e2f5e8
|
@ -192,7 +192,8 @@ public class DefaultConnection implements Connection {
|
||||||
return match.getAsInt();
|
return match.getAsInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!"application/problem+json".equals(conn.getHeaderField(CONTENT_TYPE_HEADER))) {
|
String contentType = AcmeUtils.getContentType(conn.getHeaderField(CONTENT_TYPE_HEADER));
|
||||||
|
if (!"application/problem+json".equals(contentType)) {
|
||||||
throw new AcmeException("HTTP " + rc + ": " + conn.getResponseMessage());
|
throw new AcmeException("HTTP " + rc + ": " + conn.getResponseMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +213,7 @@ public class DefaultConnection implements Connection {
|
||||||
public JSON readJsonResponse() throws AcmeException {
|
public JSON readJsonResponse() throws AcmeException {
|
||||||
assertConnectionIsOpen();
|
assertConnectionIsOpen();
|
||||||
|
|
||||||
String contentType = conn.getHeaderField(CONTENT_TYPE_HEADER);
|
String contentType = AcmeUtils.getContentType(conn.getHeaderField(CONTENT_TYPE_HEADER));
|
||||||
if (!("application/json".equals(contentType)
|
if (!("application/json".equals(contentType)
|
||||||
|| "application/problem+json".equals(contentType))) {
|
|| "application/problem+json".equals(contentType))) {
|
||||||
throw new AcmeProtocolException("Unexpected content type: " + contentType);
|
throw new AcmeProtocolException("Unexpected content type: " + contentType);
|
||||||
|
@ -238,7 +239,7 @@ public class DefaultConnection implements Connection {
|
||||||
public X509Certificate readCertificate() throws AcmeException {
|
public X509Certificate readCertificate() throws AcmeException {
|
||||||
assertConnectionIsOpen();
|
assertConnectionIsOpen();
|
||||||
|
|
||||||
String contentType = conn.getHeaderField(CONTENT_TYPE_HEADER);
|
String contentType = AcmeUtils.getContentType(conn.getHeaderField(CONTENT_TYPE_HEADER));
|
||||||
if (!("application/pkix-cert".equals(contentType))) {
|
if (!("application/pkix-cert".equals(contentType))) {
|
||||||
throw new AcmeProtocolException("Unexpected content type: " + contentType);
|
throw new AcmeProtocolException("Unexpected content type: " + contentType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,9 @@ public final class AcmeUtils {
|
||||||
private static final Pattern TZ_PATTERN = Pattern.compile(
|
private static final Pattern TZ_PATTERN = Pattern.compile(
|
||||||
"([+-])(\\d{2}):?(\\d{2})$");
|
"([+-])(\\d{2}):?(\\d{2})$");
|
||||||
|
|
||||||
|
private final static Pattern CONTENT_TYPE_PATTERN = Pattern.compile(
|
||||||
|
"([^;]+)(?:;.*?charset=(\"?)([a-z0-9_-]+)(\\2))?.*", Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
private AcmeUtils() {
|
private AcmeUtils() {
|
||||||
// Utility class without constructor
|
// Utility class without constructor
|
||||||
}
|
}
|
||||||
|
@ -224,4 +227,27 @@ public final class AcmeUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the content type of a Content-Type header.
|
||||||
|
*
|
||||||
|
* @param header
|
||||||
|
* Content-Type header
|
||||||
|
* @return Content-Type, or {@code null} if the header was invalid or empty
|
||||||
|
* @throws AcmeProtocolException
|
||||||
|
* if the Content-Type header contains a different charset than "utf-8".
|
||||||
|
*/
|
||||||
|
public static String getContentType(String header) {
|
||||||
|
if (header != null) {
|
||||||
|
Matcher m = CONTENT_TYPE_PATTERN.matcher(header);
|
||||||
|
if (m.matches()) {
|
||||||
|
String charset = m.group(3);
|
||||||
|
if (charset != null && !"utf-8".equalsIgnoreCase(charset)) {
|
||||||
|
throw new AcmeProtocolException("Unsupported charset " + charset);
|
||||||
|
}
|
||||||
|
return m.group(1).trim().toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.hamcrest.Description;
|
||||||
import org.jose4j.jwk.PublicJsonWebKey;
|
import org.jose4j.jwk.PublicJsonWebKey;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.shredzone.acme4j.exception.AcmeProtocolException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link AcmeUtils}.
|
* Unit tests for {@link AcmeUtils}.
|
||||||
|
@ -231,6 +232,35 @@ public class AcmeUtilsTest {
|
||||||
assertThat(stripErrorPrefix(null), is(nullValue()));
|
assertThat(stripErrorPrefix(null), is(nullValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test {@link AcmeUtils#getContentType(String)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetContentType() {
|
||||||
|
assertThat(AcmeUtils.getContentType(null), is(nullValue()));
|
||||||
|
assertThat(AcmeUtils.getContentType("application/json"),
|
||||||
|
is("application/json"));
|
||||||
|
assertThat(AcmeUtils.getContentType("Application/Problem+JSON"),
|
||||||
|
is("application/problem+json"));
|
||||||
|
assertThat(AcmeUtils.getContentType("application/json; charset=utf-8"),
|
||||||
|
is("application/json"));
|
||||||
|
assertThat(AcmeUtils.getContentType("application/json; charset=utf-8 (Plain text)"),
|
||||||
|
is("application/json"));
|
||||||
|
assertThat(AcmeUtils.getContentType("application/json; charset=\"utf-8\""),
|
||||||
|
is("application/json"));
|
||||||
|
assertThat(AcmeUtils.getContentType("application/json; charset=\"UTF-8\"; foo=4"),
|
||||||
|
is("application/json"));
|
||||||
|
assertThat(AcmeUtils.getContentType(" application/json ;foo=4"),
|
||||||
|
is("application/json"));
|
||||||
|
|
||||||
|
try {
|
||||||
|
AcmeUtils.getContentType("application/json; charset=\"iso-8859-1\"");
|
||||||
|
fail("Accepted bad charset");
|
||||||
|
} catch (AcmeProtocolException ex) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the given time.
|
* Matches the given time.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue