Skip to content

Commit 103df3f

Browse files
authored
Support both okhttp 4.x and 5.x while staying on 4.x for now (#3170)
Support both okhttp 4.x and 5.x while staying on 4.x for now
1 parent 2c55f9b commit 103df3f

File tree

5 files changed

+45
-6
lines changed

5 files changed

+45
-6
lines changed

changelog/@unreleased/pr-3170.v2.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type: improvement
2+
improvement:
3+
description: Support both okhttp 4.x and 5.x while staying on 4.x for now
4+
links:
5+
- https://github.com/palantir/conjure-java-runtime/pull/3170

okhttp-clients/src/main/java/com/palantir/conjure/java/okhttp/ConcurrencyLimitingInterceptor.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ public Response intercept(Chain chain) throws IOException {
8585

8686
private static Response wrapResponse(Limiter.Listener listener, Response response) throws IOException {
8787
// OkHttp guarantees not-null to execute() and callbacks, but not at this level.
88-
if (response.body() == null) {
88+
// In OkHttp 5.x, response.body() is guaranteed to be non-null, but in 4.x it can be null.
89+
// If it is empty however, the content type is null
90+
if (response.body() == null || response.body().contentType() == null) {
8991
listener.onIgnore();
9092
return response;
9193
} else if (response.body().source().exhausted()) {

okhttp-clients/src/main/java/com/palantir/conjure/java/okhttp/OkHttpClients.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
import okhttp3.OkHttpClient;
5454
import okhttp3.Protocol;
5555
import okhttp3.TlsVersion;
56-
import okhttp3.internal.Util;
5756

5857
public final class OkHttpClients {
5958
private static final SafeLogger log = SafeLoggerFactory.get(OkHttpClients.class);
@@ -119,7 +118,7 @@ public final class OkHttpClients {
119118
/** The {@link ScheduledExecutorService} used for recovering leaked limits. */
120119
private static final Supplier<ScheduledExecutorService> limitReviver =
121120
Suppliers.memoize(() -> Tracers.wrap(Executors.newSingleThreadScheduledExecutor(instrument(
122-
Util.threadFactory("conjure-java-runtime/leaked limit reviver", true),
121+
threadFactory("conjure-java-runtime/leaked limit reviver", true),
123122
"conjure-java-runtime/leaked limit reviver"))));
124123

125124
/**
@@ -134,7 +133,7 @@ public final class OkHttpClients {
134133
Suppliers.memoize(() -> Tracers.wrap(Executors.newScheduledThreadPool(
135134
NUM_SCHEDULING_THREADS,
136135
instrument(
137-
Util.threadFactory("conjure-java-runtime/OkHttp Scheduler", true),
136+
threadFactory("conjure-java-runtime/OkHttp Scheduler", true),
138137
"conjure-java-runtime/OkHttp Scheduler"))));
139138

140139
private OkHttpClients() {}
@@ -340,4 +339,14 @@ private static ImmutableList<ConnectionSpec> createConnectionSpecs() {
340339
private static ThreadFactory instrument(ThreadFactory threadFactory, String name) {
341340
return MetricRegistries.instrument(SharedTaggedMetricRegistries.getSingleton(), threadFactory, name);
342341
}
342+
343+
private static ThreadFactory threadFactory(String name, boolean daemon) {
344+
// Inspired by OkHttp's internal thread factory
345+
// Extracted to be compatible with OkHttp 4.x and 5.x
346+
return runnable -> {
347+
Thread thread = new Thread(runnable, name);
348+
thread.setDaemon(daemon);
349+
return thread;
350+
};
351+
}
343352
}

okhttp-clients/src/main/java/com/palantir/conjure/java/okhttp/Okhttp39HostnameVerifier.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@
4040
import java.util.Collections;
4141
import java.util.List;
4242
import java.util.Locale;
43+
import java.util.regex.Pattern;
4344
import javax.net.ssl.HostnameVerifier;
4445
import javax.net.ssl.SSLException;
4546
import javax.net.ssl.SSLSession;
4647
import javax.security.auth.x500.X500Principal;
47-
import okhttp3.internal.Util;
4848

4949
/**
5050
* A HostnameVerifier consistent with <a href="http://www.ietf.org/rfc/rfc2818.txt">RFC 2818</a>.
@@ -60,6 +60,21 @@
6060
* </ol>
6161
*/
6262
final class Okhttp39HostnameVerifier implements HostnameVerifier {
63+
/**
64+
* Regex extracted from Okhttp 4.x okhttp3.internal.Util to be compatible with Okhttp 5.x.
65+
* Comment below copied over from Okhttp 4.x.
66+
*
67+
* Quick and dirty pattern to differentiate IP addresses from hostnames. This is an approximation
68+
* of Android's private InetAddress#isNumeric API.
69+
*
70+
* This matches IPv6 addresses as a hex string containing at least one colon, and possibly
71+
* including dots after the first colon. It matches IPv4 addresses as strings containing only
72+
* decimal digits and dots. This pattern matches strings like "a:.23" and "54" that are neither IP
73+
* addresses nor hostnames; they will be verified as IP addresses (which is a more strict
74+
* verification).
75+
*/
76+
private static final Pattern VERIFY_AS_IP_ADDRESS = Pattern.compile("([0-9a-fA-F]*:[0-9a-fA-F:.]*)|([\\d.]+)");
77+
6378
public static final Okhttp39HostnameVerifier INSTANCE = new Okhttp39HostnameVerifier();
6479

6580
private static final int ALT_DNS_NAME = 2;
@@ -78,7 +93,9 @@ public boolean verify(String host, SSLSession session) {
7893
}
7994

8095
public boolean verify(String host, X509Certificate certificate) {
81-
return Util.canParseAsIpAddress(host) ? verifyIpAddress(host, certificate) : verifyHostname(host, certificate);
96+
return VERIFY_AS_IP_ADDRESS.matcher(host).matches()
97+
? verifyIpAddress(host, certificate)
98+
: verifyHostname(host, certificate);
8299
}
83100

84101
/** Returns true if {@code certificate} matches {@code ipAddress}. */

versions.props

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@ com.palantir.safe-logging:* = 3.9.0
1313
com.palantir.tokens:* = 3.18.0
1414
com.palantir.tracing:* = 6.24.0
1515
com.palantir.tritium:* = 0.101.0
16+
# dependency-upgrader:OFF
17+
# We don't want to prematurely force upgrades to oktthp 5.x for consumers on 4.x.
18+
# There are some ABI breaks in 5.x that would require consumers to fix their code, which would be disruptive to
19+
# conjure upgrades.
20+
# Instead, conjure-java-runtime was made to be compatible with both 4.x and 5.x
1621
com.squareup.okhttp3:* = 4.12.0
22+
# dependency-upgrader:ON
1723
io.dropwizard.metrics:* = 4.2.33
1824
io.reactivex.rxjava2:rxjava = 2.2.21
1925
org.apache.commons:commons-lang3 = 3.17.0

0 commit comments

Comments
 (0)