Skip to content
This repository was archived by the owner on Mar 11, 2022. It is now read-only.

Commit 04fcded

Browse files
authored
Merge pull request #511 from cloudant/okhttp-3.12.12
Limitations of customSSLSocketFactory and disableSSLAuthentication
2 parents d119b92 + 6b9b7be commit 04fcded

File tree

10 files changed

+70
-13
lines changed

10 files changed

+70
-13
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Unreleased
22
- [FIXED] Connection leak regression introduced in 2.18.0 caused by not closing streams from
33
successful session response bodies.
4+
- [UPGRADED] Optional OkHttp dependency to version 3.12.12.
45

56
# 2.19.0 (2020-03-02)
67
- [NEW] Add getter for total row count to `AllDocsResponse`

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Gradle with [optional `okhttp-urlconnection` dependency](#optional-okhttp-depend
3030
```groovy
3131
dependencies {
3232
compile group: 'com.cloudant', name: 'cloudant-client', version: '2.19.0'
33-
compile group: 'com.squareup.okhttp3', name: 'okhttp-urlconnection', version: '3.12.5'
33+
compile group: 'com.squareup.okhttp3', name: 'okhttp-urlconnection', version: '3.12.12'
3434
}
3535
```
3636

@@ -55,7 +55,7 @@ Maven with [optional `okhttp-urlconnection` dependency](#optional-okhttp-depende
5555
<dependency>
5656
<groupId>com.squareup.okhttp3</groupId>
5757
<artifactId>okhttp-urlconnection</artifactId>
58-
<version>3.12.5</version>
58+
<version>3.12.12</version>
5959
</dependency>
6060
~~~
6161

@@ -68,6 +68,10 @@ The main use case that is supported by this optional dependency is configuration
6868
([see the javadoc](http://www.javadoc.io/doc/com.cloudant/cloudant-client/) for ClientBuilder.maxConnections). If the OkHttp dependency is
6969
available at runtime it will be used automatically. Not using OkHttp will result in a smaller application size.
7070

71+
**Note:** The configuration options `ClientBuilder.customSSLSocketFactory` and
72+
`ClientBuilder.disableSSLAuthentication` are not usable with the combination of the optional OkHttp
73+
dependency and Java versions of 8u252 or newer.
74+
7175
## Getting Started
7276

7377
This section contains a simple example of creating a `com.cloudant.client.api.CloudantClient` instance and interacting with Cloudant.

cloudant-client/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ dependencies {
2020
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.1.0'
2121
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.1.0'
2222
testCompile group: 'org.hamcrest', name: 'hamcrest-library', version: '1.3'
23-
testCompile group: 'com.squareup.okhttp3', name: 'mockwebserver', version: '3.12.5'
23+
testCompile group: 'com.squareup.okhttp3', name: 'mockwebserver', version: '3.12.12'
2424
testCompile group: 'org.jmockit', name: 'jmockit', version: '1.34'
2525
testCompile group: 'org.littleshoot', name: 'littleproxy', version: '1.1.0'
2626
}

cloudant-client/src/main/java/com/cloudant/client/api/ClientBuilder.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2015, 2019 IBM Corp. All rights reserved.
2+
* Copyright © 2015, 2020 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -514,6 +514,9 @@ public ClientBuilder proxyPassword(String proxyPassword) {
514514
* The SSL authentication is enabled by default meaning that hostname verification
515515
* and certificate chain validation is done using the JVM default settings.
516516
* </P>
517+
* <P>
518+
* <B>Not supported with Java 8u252 or newer and the optional OkHttp dependency.</B>
519+
* </P>
517520
*
518521
* @return this ClientBuilder object for setting additional options
519522
* @throws IllegalStateException if {@link #customSSLSocketFactory(SSLSocketFactory)}
@@ -534,6 +537,9 @@ public ClientBuilder disableSSLAuthentication() {
534537
/**
535538
* Specifies the custom SSLSocketFactory to use when connecting to Cloudant over a
536539
* <code>https</code> URL, when SSL authentication is enabled.
540+
* <P>
541+
* <B>Not supported with Java 8u252 or newer and the optional OkHttp dependency.</B>
542+
* </P>
537543
*
538544
* @param factory An SSLSocketFactory, or <code>null</code> for the
539545
* default SSLSocketFactory of the JRE.

cloudant-client/src/test/java/com/cloudant/tests/CloudFoundryServiceTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2016, 2019 IBM Corp. All rights reserved.
2+
* Copyright © 2016, 2020 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -24,6 +24,7 @@
2424
import com.cloudant.client.api.ClientBuilder;
2525
import com.cloudant.client.api.CloudantClient;
2626
import com.cloudant.tests.extensions.MockWebServerExtension;
27+
import com.cloudant.tests.util.HttpFactoryParameterizedTest;
2728
import com.cloudant.tests.util.MockWebServerResources;
2829
import com.google.gson.GsonBuilder;
2930

@@ -63,6 +64,11 @@ public class CloudFoundryServiceTest {
6364

6465
@BeforeEach
6566
public void beforeEach() {
67+
// Default test running uses OkHttp because it is in the classpath
68+
// These tests need to use disableSSLAuthentication because the mock server https does not
69+
// have a trusted certificate. That option is not valid with OkHttp and Java 8_252 or newer
70+
// but we want to run these tests, so use the OkHelperMock to disable OkHttp.
71+
new HttpFactoryParameterizedTest.OkHelperMock();
6672
server = mockWebServerExt.get();
6773
server.useHttps(MockWebServerResources.getSSLSocketFactory(), false);
6874
mockServerHostPort = String.format("%s:%s/", server.getHostName(), server.getPort());

cloudant-client/src/test/java/com/cloudant/tests/HttpProxyTest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2015, 2018 IBM Corp. All rights reserved.
2+
* Copyright © 2015, 2020 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -23,6 +23,7 @@
2323
import com.cloudant.tests.extensions.MockWebServerExtension;
2424
import com.cloudant.tests.util.HttpFactoryParameterizedTest;
2525
import com.cloudant.tests.util.MockWebServerResources;
26+
import com.cloudant.tests.util.Utils;
2627

2728
import org.junit.jupiter.api.AfterEach;
2829
import org.junit.jupiter.api.BeforeEach;
@@ -300,6 +301,10 @@ public void proxiedRequest(final boolean okUsable,
300301
final boolean useHttpsServer,
301302
final boolean useProxyAuth) throws Exception {
302303

304+
// Test uses disableSSLAuthentication because the mock server doesn't have a trusted cert
305+
// - need to disable the test for OkHttp and Java 8_252 or newer
306+
Utils.assumeCustomSslAuthUsable(okUsable);
307+
303308
//mock a 200 OK
304309
server.setDispatcher(new Dispatcher() {
305310
@Override

cloudant-client/src/test/java/com/cloudant/tests/SslAuthenticationTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2015, 2019 IBM Corp. All rights reserved.
2+
* Copyright © 2015, 2020 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -24,6 +24,7 @@
2424
import com.cloudant.tests.extensions.MockWebServerExtension;
2525
import com.cloudant.tests.util.HttpFactoryParameterizedTest;
2626
import com.cloudant.tests.util.MockWebServerResources;
27+
import com.cloudant.tests.util.Utils;
2728

2829
import org.junit.jupiter.api.BeforeEach;
2930
import org.junit.jupiter.api.TestTemplate;
@@ -136,7 +137,8 @@ private static void validateClientAuthenticationException(CouchDbException e) {
136137
*/
137138
@TestTemplate
138139
public void localSslAuthenticationDisabled() throws Exception {
139-
140+
// disableSSLAuthentication not usable with OkHttp and 8_252 or newer
141+
Utils.assumeCustomSslAuthUsable(isOkUsable);
140142
// Build a client that connects to the mock server with SSL authentication disabled
141143
CloudantClient dbClient = CloudantClientHelper.newMockWebServerClientBuilder(server)
142144
.disableSSLAuthentication()
@@ -251,7 +253,8 @@ public void execute() throws Throwable {
251253
*/
252254
@TestTemplate
253255
public void localSSLAuthenticationDisabledWithCookieAuth() throws Exception {
254-
256+
// disableSSLAuthentication not usable with OkHttp and 8_252 or newer
257+
Utils.assumeCustomSslAuthUsable(isOkUsable);
255258
// Mock up an OK cookie response then an OK response for the getAllDbs()
256259
server.enqueue(MockWebServerResources.OK_COOKIE);
257260
server.enqueue(new MockResponse()); //OK 200

cloudant-client/src/test/java/com/cloudant/tests/util/HttpFactoryParameterizedTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2016, 2018 IBM Corp. All rights reserved.
2+
* Copyright © 2016, 2020 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -37,7 +37,7 @@ public abstract class HttpFactoryParameterizedTest extends TestWithDbPerClass {
3737
* A mock OkHelper that always returns false to force use of the JVM HttpURLConnection
3838
* via the {@link DefaultHttpUrlConnectionFactory}
3939
*/
40-
static class OkHelperMock extends MockUp<OkHelper> {
40+
public static class OkHelperMock extends MockUp<OkHelper> {
4141
@Mock
4242
public static boolean isOkUsable() {
4343
return false;

cloudant-client/src/test/java/com/cloudant/tests/util/Utils.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2015, 2018 IBM Corp. All rights reserved.
2+
* Copyright © 2015, 2020 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -35,6 +35,8 @@
3535
import com.cloudant.http.HttpConnectionInterceptorContext;
3636
import com.cloudant.http.HttpConnectionResponseInterceptor;
3737

38+
import org.junit.jupiter.api.Assumptions;
39+
3840
import java.io.File;
3941
import java.io.FileNotFoundException;
4042
import java.net.URI;
@@ -225,4 +227,34 @@ public static void assertOKResponse(Response r) throws Exception {
225227
assertTrue(r.getStatusCode()
226228
/ 100 == 2, "The response code should be 2XX was " + r.getStatusCode());
227229
}
230+
231+
/**
232+
* Utility to ignore tests when running with optional OkHttp dependency and Java 8_252 or newer.
233+
* This should be applied to any test that uses the customSSLSocketFactory or
234+
* disableSSLAuthentication options.
235+
*
236+
* These options cannot be used with OkHttp and Java 8_252 or newer
237+
* (see https://github.com/square/okhttp/issues/5970.
238+
* OkHttp treats 8_252 and newer as equivalent to 9+ because of the availability of ALPN
239+
* support. In 9+ reflection cannot be used to infer the TrustManager from the SslSocketFactory
240+
* so setting the SslSocketFactory without a TrustManager is prevented. This blocks the route we
241+
* currently use to supply custom SslSocketFactory via the deprecated OkHttp OkUrlFactory path
242+
* via javax.net.ssl.HttpsURLConnection#setSSLSocketFactory(javax.net.ssl.SSLSocketFactory).
243+
*
244+
*/
245+
public static void assumeCustomSslAuthUsable(boolean isOkUsable) {
246+
String version = System.getProperty("java.version");
247+
boolean java8_252OrHigher = false;
248+
// Java 1.8 or lower, 9+ are 9, 10 etc
249+
if (version.startsWith("1.")) {
250+
if (version.startsWith("1.8.")) {
251+
int update = Integer.parseInt(version.split("_")[1]);
252+
if (update >= 252) java8_252OrHigher = true;
253+
}
254+
} else {
255+
java8_252OrHigher = true;
256+
}
257+
Assumptions.assumeFalse(isOkUsable && java8_252OrHigher, "Test uses custom " +
258+
"SslSocketFactory, incompatible with OkHttp and Java 8_252 or newer.");
259+
}
228260
}

cloudant-http/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
dependencies {
1616
compile group: 'commons-io', name: 'commons-io', version: '2.4'
1717
//needed to compile, but optional for consumers of java-cloudant
18-
compile(group: 'com.squareup.okhttp3', name: 'okhttp-urlconnection', version: '3.12.5') {
18+
compile(group: 'com.squareup.okhttp3', name: 'okhttp-urlconnection', version: '3.12.12') {
1919
ext.optional = true
2020
}
2121
}

0 commit comments

Comments
 (0)