mirror of https://github.com/shred/acme4j
Accept Content-Type header with charset parameter
parent
a32c7bac03
commit
42541ac299
|
@ -232,7 +232,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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +250,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);
|
||||||
|
@ -275,7 +276,7 @@ public class DefaultConnection implements Connection {
|
||||||
public List<X509Certificate> readCertificates() throws AcmeException {
|
public List<X509Certificate> readCertificates() throws AcmeException {
|
||||||
assertConnectionIsOpen();
|
assertConnectionIsOpen();
|
||||||
|
|
||||||
String contentType = conn.getHeaderField(CONTENT_TYPE_HEADER);
|
String contentType = AcmeUtils.getContentType(conn.getHeaderField(CONTENT_TYPE_HEADER));
|
||||||
if (!("application/pem-certificate-chain".equals(contentType))) {
|
if (!("application/pem-certificate-chain".equals(contentType))) {
|
||||||
throw new AcmeProtocolException("Unexpected content type: " + contentType);
|
throw new AcmeProtocolException("Unexpected content type: " + contentType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,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 static final Base64.Encoder PEM_ENCODER = Base64.getMimeEncoder(64, "\n".getBytes());
|
private static final Base64.Encoder PEM_ENCODER = Base64.getMimeEncoder(64, "\n".getBytes());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -326,4 +329,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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,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}.
|
||||||
|
@ -299,6 +300,35 @@ public class AcmeUtilsTest {
|
||||||
assertThat(AcmeUtils.toURL(null), is(nullValue()));
|
assertThat(AcmeUtils.toURL(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