Get link relations from response header

pull/17/merge
Richard Körber 2015-12-16 00:50:12 +01:00
parent 575902bd60
commit 943f604a21
3 changed files with 57 additions and 0 deletions

View File

@ -91,6 +91,15 @@ public interface Connection extends AutoCloseable {
*/ */
URI getLocation() throws AcmeException; URI getLocation() throws AcmeException;
/**
* Gets a link relation from the header.
*
* @param relation
* Link relation
* @return Link, or {@code null} if there was no such link relation
*/
URI getLink(String relation) throws AcmeException;
/** /**
* Closes the {@link Connection}, releasing all resources. * Closes the {@link Connection}, releasing all resources.
*/ */

View File

@ -26,7 +26,9 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.jose4j.base64url.Base64Url; import org.jose4j.base64url.Base64Url;
@ -248,6 +250,25 @@ public class DefaultConnection implements Connection {
} }
} }
@Override
public URI getLink(String relation) throws AcmeException {
List<String> links = conn.getHeaderFields().get("Link");
if (links != null) {
Pattern p = Pattern.compile("<(.*?)>\\s*;\\s*rel=\"?"+ Pattern.quote(relation) + "\"?");
for (String link : links) {
Matcher m = p.matcher(link);
if (m.matches()) {
try {
return new URI(m.group(1));
} catch (URISyntaxException ex) {
throw new AcmeException("Bad Link header: " + link);
}
}
}
}
return null;
}
@Override @Override
public void close() { public void close() {
conn = null; conn = null;

View File

@ -27,8 +27,10 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -144,6 +146,31 @@ public class DefaultConnectionTest {
verifyNoMoreInteractions(mockUrlConnection); verifyNoMoreInteractions(mockUrlConnection);
} }
/**
* Test that Link headers are evaluated.
*/
@Test
public void testGetLink() throws Exception {
Map<String, List<String>> headers = new HashMap<String, List<String>>();
headers.put("Content-Type", Arrays.asList("application/json"));
headers.put("Location", Arrays.asList("https://example.com/acme/reg/asdf"));
headers.put("Link", Arrays.asList(
"<https://example.com/acme/new-authz>;rel=\"next\"",
"<https://example.com/acme/recover-reg>;rel=recover",
"<https://example.com/acme/terms>; rel=\"terms-of-service\""
));
when(mockUrlConnection.getHeaderFields()).thenReturn(headers);
try (DefaultConnection conn = new DefaultConnection(mockHttpConnection)) {
conn.conn = mockUrlConnection;
assertThat(conn.getLink("next"), is(new URI("https://example.com/acme/new-authz")));
assertThat(conn.getLink("recover"), is(new URI("https://example.com/acme/recover-reg")));
assertThat(conn.getLink("terms-of-service"), is(new URI("https://example.com/acme/terms")));
assertThat(conn.getLink("secret-stuff"), is(nullValue()));
}
}
/** /**
* Test that no Location header returns {@code null}. * Test that no Location header returns {@code null}.
*/ */