OkHttp proxy
An OkHttp proxy is an OkHttpClient that tunnels traffic through a java.net.Proxy and authenticates with a proxyAuthenticator. Configure both and every Java call exits through an Aethyn residential IP.
Why a residential OkHttp proxy
Java services that scrape or call geo-fenced APIs from a cloud VM share one datacenter ASN. Targets score that ASN, then either challenge the client or return the wrong locale. An OkHttp proxy replaces that ASN with a residential exit without changing how you build Request objects. Aethyn does not take credentials in the proxy URL the way Requests does: OkHttp wants a Proxy of type HTTP plus a proxyAuthenticator that sets Proxy-Authorization with Credentials.basic(). Country, city, and sticky session still live on the username you pass to Credentials.basic(). Skip the session suffix and each newCall() rotates. Add -session-<id>-lifetime-<minutes> when a cookie jar or login must hold one IP. HTTPS uses CONNECT on port 2099; you do not point OkHttp at an HTTPS proxy URL. Always set call and connect timeouts. Residential hops are slower than a local JVM talking to a CDN, and OkHttp's defaults can stall a thread pool on a dead exit.
Setup steps
- 1Create a Proxy with the Aethyn host and port.
- 2Add a proxyAuthenticator that sets the Proxy-Authorization header.
- 3Build the OkHttpClient with both.
- 4Put targeting suffixes in the username.
Code
import okhttp3.*;
import java.net.*;
Proxy proxy = new Proxy(Proxy.Type.HTTP,
new InetSocketAddress("proxy.aethyn.io", 2099));
OkHttpClient client = new OkHttpClient.Builder()
.proxy(proxy)
.proxyAuthenticator((route, response) -> {
String cred = Credentials.basic("aethyn-XXXXX-country-us", "PASSWORD");
return response.request().newBuilder()
.header("Proxy-Authorization", cred).build();
})
.build();
Request req = new Request.Builder().url("https://httpbin.org/ip").build();
try (Response res = client.newCall(req).execute()) {
System.out.println(res.body().string());
}import okhttp3.*;
import java.net.*;
import java.util.concurrent.TimeUnit;
String user = "aethyn-XXXXX-country-us-session-abc123-lifetime-10";
Proxy proxy = new Proxy(Proxy.Type.HTTP,
new InetSocketAddress("proxy.aethyn.io", 2099));
OkHttpClient client = new OkHttpClient.Builder()
.proxy(proxy)
.connectTimeout(30, TimeUnit.SECONDS)
.callTimeout(30, TimeUnit.SECONDS)
.proxyAuthenticator((route, response) -> {
String cred = Credentials.basic(user, "PASSWORD");
return response.request().newBuilder()
.header("Proxy-Authorization", cred).build();
})
.build();
Request req = new Request.Builder().url("https://example.com/account").build();
try (Response res = client.newCall(req).execute()) {
System.out.println(res.code());
}import okhttp3.*;
import java.net.*;
Proxy proxy = new Proxy(Proxy.Type.SOCKS,
new InetSocketAddress("proxy.aethyn.io", 1099));
OkHttpClient client = new OkHttpClient.Builder()
.proxy(proxy)
.proxyAuthenticator((route, response) -> {
String cred = Credentials.basic("aethyn-XXXXX", "PASSWORD");
return response.request().newBuilder()
.header("Proxy-Authorization", cred).build();
})
.build();Request req = new Request.Builder().url("https://httpbin.org/ip").build();
try (Response res = client.newCall(req).execute()) {
if (res.code() == 407) {
System.err.println("proxy auth failed — check username suffixes");
} else {
System.out.println(res.body().string());
}
}Replace aethyn-XXXXX and PASSWORD with your dashboard credentials. See the full targeting reference and protocol/port list.
Troubleshooting
The OkHttp failures that get misread as network bugs are 407, stalled calls, and SOCKS vs HTTP confusion. A 407 means the authenticator never sent acceptable credentials, or the username is missing aethyn-XXXXX / targeting suffixes — OkHttp will not pull user:pass out of a proxy URL, so an Authenticator is required. Stalls are timeouts: set connectTimeout and callTimeout on the builder (30 seconds is a sane residential default) or a bad exit holds a dispatcher thread. If HTTP works and HTTPS fails with a handshake or CONNECT error, the Proxy.Type is wrong or the port is the SOCKS port; Type.HTTP must hit 2099. SOCKS5 is Proxy.Type.SOCKS on port 1099 with the same authenticator. Reuse one OkHttpClient for the process: building a new client per request throws away the connection pool and the proxy TCP session with it.
Tips
- Reuse a single OkHttpClient — it pools connections and threads.
- Credentials.basic() builds the Proxy-Authorization value for you.
- Targeting goes in the username passed to Credentials.basic().
- Set connectTimeout and callTimeout; residential hops are slower than datacenter.