Add support for Proxy connections

pull/61/head
Richard Körber 2018-03-06 22:11:05 +01:00
parent b4374dbf6d
commit 49677d8dbc
No known key found for this signature in database
GPG Key ID: AAB9FD19C78AA3E0
8 changed files with 52 additions and 11 deletions

View File

@ -13,6 +13,7 @@
*/
package org.shredzone.acme4j;
import java.net.Proxy;
import java.net.URI;
import java.net.URL;
import java.security.KeyPair;
@ -42,6 +43,7 @@ public class Session {
private String nonce;
private Locale locale = Locale.getDefault();
private Proxy proxy = Proxy.NO_PROXY;
protected Instant directoryCacheExpiry;
/**
@ -128,6 +130,21 @@ public class Session {
this.locale = locale;
}
/**
* Gets the {@link Proxy} to be used for connections.
*/
public Proxy getProxy() {
return proxy;
}
/**
* Sets a {@link Proxy} that is to be used for all connections. If {@code null},
* {@link Proxy#NO_PROXY} is used, which is also the default.
*/
public void setProxy(Proxy proxy) {
this.proxy = proxy != null ? proxy : Proxy.NO_PROXY;
}
/**
* Returns the {@link AcmeProvider} that is used for this session.
*

View File

@ -101,7 +101,7 @@ public class DefaultConnection implements Connection {
URL newNonceUrl = session.resourceUrl(Resource.NEW_NONCE);
conn = httpConnector.openConnection(newNonceUrl);
conn = httpConnector.openConnection(newNonceUrl, session.getProxy());
conn.setRequestMethod("HEAD");
conn.setRequestProperty(ACCEPT_LANGUAGE_HEADER, session.getLocale().toLanguageTag());
conn.connect();
@ -132,7 +132,7 @@ public class DefaultConnection implements Connection {
LOG.debug("GET {}", url);
try {
conn = httpConnector.openConnection(url);
conn = httpConnector.openConnection(url, session.getProxy());
conn.setRequestMethod("GET");
conn.setRequestProperty(ACCEPT_CHARSET_HEADER, DEFAULT_CHARSET);
conn.setRequestProperty(ACCEPT_LANGUAGE_HEADER, session.getLocale().toLanguageTag());
@ -311,7 +311,7 @@ public class DefaultConnection implements Connection {
resetNonce(session);
}
conn = httpConnector.openConnection(url);
conn = httpConnector.openConnection(url, session.getProxy());
conn.setRequestMethod("POST");
conn.setRequestProperty(ACCEPT_HEADER, "application/json");
conn.setRequestProperty(ACCEPT_CHARSET_HEADER, DEFAULT_CHARSET);

View File

@ -16,6 +16,7 @@ package org.shredzone.acme4j.connector;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;
import java.util.Properties;
@ -63,10 +64,12 @@ public class HttpConnector {
*
* @param url
* {@link URL} to connect to
* @param proxy
* {@link Proxy} to be used
* @return {@link HttpURLConnection} connected to the {@link URL}
*/
public HttpURLConnection openConnection(URL url) throws IOException {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
public HttpURLConnection openConnection(URL url, Proxy proxy) throws IOException {
HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
configure(conn);
return conn;
}

View File

@ -16,6 +16,7 @@ package org.shredzone.acme4j.provider.pebble;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
@ -39,8 +40,8 @@ public class PebbleHttpConnector extends HttpConnector {
private static SSLSocketFactory sslSocketFactory;
@Override
public HttpURLConnection openConnection(URL url) throws IOException {
HttpURLConnection conn = super.openConnection(url);
public HttpURLConnection openConnection(URL url, Proxy proxy) throws IOException {
HttpURLConnection conn = super.openConnection(url, proxy);
if (conn instanceof HttpsURLConnection) {
((HttpsURLConnection) conn).setSSLSocketFactory(createSocketFactory());
}

View File

@ -19,6 +19,9 @@ import static org.mockito.Mockito.*;
import static org.shredzone.acme4j.toolbox.TestUtils.*;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Proxy.Type;
import java.net.URI;
import java.net.URL;
import java.security.KeyPair;
@ -79,6 +82,13 @@ public class SessionTest {
session.setNonce(DUMMY_NONCE);
assertThat(session.getNonce(), is(equalTo(DUMMY_NONCE)));
assertThat(session.getProxy(), is(Proxy.NO_PROXY));
Proxy proxy = new Proxy(Type.HTTP, new InetSocketAddress("10.0.0.1", 8080));
session.setProxy(proxy);
assertThat(session.getProxy(), is(proxy));
session.setProxy(null);
assertThat(session.getProxy(), is(Proxy.NO_PROXY));
assertThat(session.getServerUri(), is(serverUri));
}

View File

@ -24,6 +24,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URI;
import java.net.URL;
import java.security.KeyPair;
@ -78,7 +79,7 @@ public class DefaultConnectionTest {
mockUrlConnection = mock(HttpURLConnection.class);
mockHttpConnection = mock(HttpConnector.class);
when(mockHttpConnection.openConnection(requestUrl)).thenReturn(mockUrlConnection);
when(mockHttpConnection.openConnection(requestUrl, Proxy.NO_PROXY)).thenReturn(mockUrlConnection);
final AcmeProvider mockProvider = mock(AcmeProvider.class);
when(mockProvider.directory(
@ -158,7 +159,7 @@ public class DefaultConnectionTest {
*/
@Test
public void testResetNonce() throws AcmeException, IOException {
when(mockHttpConnection.openConnection(new URL("https://example.com/acme/new-nonce")))
when(mockHttpConnection.openConnection(new URL("https://example.com/acme/new-nonce"), Proxy.NO_PROXY))
.thenReturn(mockUrlConnection);
when(mockUrlConnection.getResponseCode())
.thenReturn(HttpURLConnection.HTTP_NO_CONTENT);
@ -813,7 +814,7 @@ public class DefaultConnectionTest {
*/
@Test(expected = AcmeException.class)
public void testSendSignedRequestNoNonce() throws Exception {
when(mockHttpConnection.openConnection(new URL("https://example.com/acme/new-nonce")))
when(mockHttpConnection.openConnection(new URL("https://example.com/acme/new-nonce"), Proxy.NO_PROXY))
.thenReturn(mockUrlConnection);
when(mockUrlConnection.getResponseCode())
.thenReturn(HttpURLConnection.HTTP_NOT_FOUND);

View File

@ -20,6 +20,7 @@ import static org.mockito.Mockito.*;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URISyntaxException;
import java.net.URL;
@ -59,7 +60,7 @@ public class HttpConnectorTest {
@Category(HttpURLConnection.class)
public void testOpenConnection() throws IOException {
HttpConnector connector = new HttpConnector();
HttpURLConnection conn = connector.openConnection(new URL("http://example.com"));
HttpURLConnection conn = connector.openConnection(new URL("http://example.com"), Proxy.NO_PROXY);
assertThat(conn, not(nullValue()));
conn.connect();
assertThat(conn.getResponseCode(), is(HttpURLConnection.HTTP_OK));

View File

@ -34,3 +34,11 @@ URL website = meta.getWebsite();
`Session.setLocale()` allows to select a different locale. Errors will be returned in that language, if supported by the CA.
By default, the system's default locale is used.
## Proxy
_acme4j_ uses a standard `HttpURLConnection` for HTTP connections.
If a proxy must be used for internet connections, you can set a `Proxy` instance by invoking `Session.setProxy()`. An alternative is to use the system properties `http.proxyHost` and `http.proxyPort` to globally set a proxy for the Java process.
If the proxy needs authentication, you need to set a default `Authenticator`. Be careful: Most code snippets I have found in the internet will send out the proxy credentials to anyone who is asking. See [this blog article](http://rolandtapken.de/blog/2012-04/java-process-httpproxyuser-and-httpproxypassword) for a good way to implement a proxy `Authenticator`.