Skip to content

Commit

Permalink
Add support for Proxy connections
Browse files Browse the repository at this point in the history
  • Loading branch information
shred committed Mar 6, 2018
1 parent b4374db commit 49677d8
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 11 deletions.
17 changes: 17 additions & 0 deletions acme4j-client/src/main/java/org/shredzone/acme4j/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*/
package org.shredzone.acme4j;

import java.net.Proxy;
import java.net.URI;
import java.net.URL;
import java.security.KeyPair;
Expand Down Expand Up @@ -42,6 +43,7 @@ public class Session {

private String nonce;
private Locale locale = Locale.getDefault();
private Proxy proxy = Proxy.NO_PROXY;
protected Instant directoryCacheExpiry;

/**
Expand Down Expand Up @@ -128,6 +130,21 @@ public void setLocale(Locale locale) {
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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public void resetNonce(Session session) throws AcmeException {

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();
Expand Down Expand Up @@ -132,7 +132,7 @@ public void sendRequest(URL url, Session session) throws AcmeException {
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());
Expand Down Expand Up @@ -311,7 +311,7 @@ private int performRequest(URL url, JSONBuilder claims, Session session, KeyPair
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;
import java.util.Properties;

Expand Down Expand Up @@ -63,10 +64,12 @@ public static String defaultUserAgent() {
*
* @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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
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;
Expand All @@ -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());
}
Expand Down
10 changes: 10 additions & 0 deletions acme4j-client/src/test/java/org/shredzone/acme4j/SessionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
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;
Expand Down Expand Up @@ -79,6 +82,13 @@ public void testGettersAndSetters() throws IOException {
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));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
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;
Expand Down Expand Up @@ -78,7 +79,7 @@ public void setup() throws AcmeException, IOException {
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(
Expand Down Expand Up @@ -158,7 +159,7 @@ public void testInvalidNonceFromHeader() {
*/
@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);
Expand Down Expand Up @@ -813,7 +814,7 @@ public String getNonce() {
*/
@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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URISyntaxException;
import java.net.URL;

Expand Down Expand Up @@ -59,7 +60,7 @@ public void testMockOpenConnection() throws IOException, URISyntaxException {
@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));
Expand Down
8 changes: 8 additions & 0 deletions src/site/markdown/usage/session.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

0 comments on commit 49677d8

Please sign in to comment.