Skip to content

Commit bfb6cb4

Browse files
committed
HTTPS: configure okhttp to accept test certificates
1 parent ce85fe8 commit bfb6cb4

File tree

8 files changed

+93
-14
lines changed

8 files changed

+93
-14
lines changed

examples/src/main/java/examples/HttpsApp.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
public class HttpsApp extends Jooby {
1313

1414
{
15-
before(new SSLHandler("localhost", 8443));
15+
before(new SSLHandler(true));
1616
setServerOptions(new ServerOptions().setSecurePort(8443));
1717

18-
get("/path", ctx -> {
18+
get("/secure", ctx -> {
1919
return ctx.getScheme() + "; secure: " + ctx.isSecure();
2020
});
2121
}

jooby/src/main/java/io/jooby/SSLHandler.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,16 @@ public SSLHandler(boolean useProxy) {
6262
@Override public void apply(@Nonnull Context ctx) {
6363
if (!ctx.isSecure()) {
6464
String host;
65-
if (this.host == null) {
65+
if (this.host == null) {
6666
String hostAndPort = ctx.getHostAndPort(useProxy);
6767
int i = hostAndPort.lastIndexOf(':');
6868
host = i > 0 ? hostAndPort.substring(0, i) : hostAndPort;
6969
} else {
7070
host = this.host;
7171
}
7272
StringBuilder buff = new StringBuilder("https://");
73-
String contextPath = ctx.getContextPath();
74-
if (!contextPath.equals("/")) {
75-
buff.append(contextPath);
76-
}
7773
buff.append(host);
74+
7875
if (host.equals("localhost")) {
7976
int securePort = ctx.getRouter().getServerOptions().getSecurePort();
8077
buff.append(":").append(securePort);
@@ -83,6 +80,10 @@ public SSLHandler(boolean useProxy) {
8380
buff.append(":").append(port);
8481
}
8582
}
83+
String contextPath = ctx.getContextPath();
84+
if (!contextPath.equals("/")) {
85+
buff.append(contextPath);
86+
}
8687
buff.append(ctx.pathString());
8788
buff.append(ctx.queryString());
8889
ctx.sendRedirect(buff.toString());

modules/jooby-utow/src/main/java/io/jooby/internal/utow/UtowWebSocket.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,11 @@ void fireConnect() {
151151
if (timeout > 0) {
152152
channel.setIdleTimeout(TimeUnit.MINUTES.toMillis(timeout));
153153
}
154-
channel.getReceiveSetter().set(this);
155-
channel.resumeReceives();
156154
if (onConnectCallback != null) {
157155
onConnectCallback.onConnect(this);
158156
}
157+
channel.getReceiveSetter().set(this);
158+
channel.resumeReceives();
159159
} catch (Throwable x) {
160160
onError(channel, x);
161161
}

tests/src/test/java/io/jooby/HttpsTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ public void forceSSL() {
5656
app.before(new SSLHandler(true));
5757

5858
app.get("/{path}", ctx -> ctx.pathString());
59-
}).dontFollowRedirects().ready(http -> {
59+
}).dontFollowRedirects().ready((http, https, server) -> {
6060
http.get("/path", rsp -> {
61-
assertEquals("https://localhost:9443/path",
61+
assertEquals("https://localhost:" + https.getPort() + "/path",
6262
rsp.header("Location"));
6363
assertEquals(302, rsp.code());
6464
});

tests/src/test/java/io/jooby/WebClient.java

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,18 @@
99
import org.jetbrains.annotations.NotNull;
1010
import org.jetbrains.annotations.Nullable;
1111

12+
import javax.net.ssl.HostnameVerifier;
13+
import javax.net.ssl.SSLContext;
14+
import javax.net.ssl.SSLSession;
15+
import javax.net.ssl.SSLSocketFactory;
16+
import javax.net.ssl.TrustManager;
17+
import javax.net.ssl.X509TrustManager;
1218
import java.io.IOException;
1319
import java.net.SocketTimeoutException;
20+
import java.security.KeyManagementException;
21+
import java.security.NoSuchAlgorithmException;
22+
import java.security.cert.CertificateException;
23+
import java.security.cert.X509Certificate;
1424
import java.util.ArrayList;
1525
import java.util.HashMap;
1626
import java.util.List;
@@ -120,12 +130,15 @@ public WebClient(String scheme, int port, boolean followRedirects) {
120130
try {
121131
this.scheme = scheme;
122132
this.port = port;
123-
client = new OkHttpClient.Builder()
133+
OkHttpClient.Builder builder = new OkHttpClient.Builder()
124134
.connectTimeout(5, TimeUnit.MINUTES)
125135
.writeTimeout(5, TimeUnit.MINUTES)
126136
.readTimeout(5, TimeUnit.MINUTES)
127-
.followRedirects(followRedirects)
128-
.build();
137+
.followRedirects(followRedirects);
138+
if (scheme.equalsIgnoreCase("https")) {
139+
configureSelfSigned(builder);
140+
}
141+
this.client = builder.build();
129142
header("Accept",
130143
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
131144
} catch (Exception x) {
@@ -261,4 +274,30 @@ public void close() {
261274
client.dispatcher().executorService().shutdown();
262275
client.connectionPool().evictAll();
263276
}
277+
278+
private static void configureSelfSigned(OkHttpClient.Builder builder)
279+
throws NoSuchAlgorithmException, KeyManagementException {
280+
X509TrustManager trustManager = new X509TrustManager() {
281+
@Override
282+
public X509Certificate[] getAcceptedIssuers() {
283+
return new X509Certificate[0];
284+
}
285+
286+
@Override
287+
public void checkServerTrusted(final X509Certificate[] chain,
288+
final String authType) throws CertificateException {
289+
}
290+
291+
@Override
292+
public void checkClientTrusted(final X509Certificate[] chain,
293+
final String authType) throws CertificateException {
294+
}
295+
};
296+
297+
SSLContext sslContext = SSLContext.getInstance("SSL");
298+
299+
sslContext.init(null, new TrustManager[]{trustManager}, new java.security.SecureRandom());
300+
builder.sslSocketFactory(sslContext.getSocketFactory(), trustManager);
301+
builder.hostnameVerifier((hostname, session) -> true);
302+
}
264303
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIICqzCCAZOgAwIBAgIJANequC4DK++VMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNVBAMTCWxvY2Fs
3+
aG9zdDAgFw0xODExMDUyMzM3MTVaGA85OTk5MTIzMTIzNTk1OVowFDESMBAGA1UEAxMJbG9jYWxo
4+
b3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqjsyE1+40JMEXTeZ58ffSc5zaYPF
5+
32UMU7tYLubwajh4uARcEDczM8FqdiakwhUozRuW6KfTnR/awdFE099UHhW0/imd7HQrKQFlunTe
6+
UlfJ2ERZuN7ohIcYaTUSDAhYHEtZPv6m3rvE8xYuq2QCK7GCHhDe07FcIyIx92Gf6pWkmNDIgBlS
7+
EzYSbwwS8M4dm7kQATAT4MDvn9dx0Cr7UejasHRs9idlg3xwjj8UMqYC/Al+Hmk0SSgsRCEPELZu
8+
MqfXjZhOAXOs9Tgc+DMwfsCZM+X7X1gAoGalUxctdRLFnS13DUNoEUMh0uyDTO0btWnueDMPhttP
9+
kR8v5QqmzwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBbWgJjr+nbt/dd9w/MfY0Szsrz4Tscu1p+
10+
A+WxpWLMNjKztCWGtMo+PcUl3vNERIykefx70wDlfsaYPoOMBJU05BDCSMEkVpX8VZeV8YWaDLSp
11+
KG+RtWwk8PRihe/ADODZwRGVcDhQq2/wsFM28Rd1GcnD54+IvkV46WPUYwPthd0Kfj38Cx3S9tN4
12+
mUC2AzVcvmJl9Aj+YdAJ6BQ5MemgLaWIJwiPgCbGg8AIXFi51aq6xJNX6jFfcYgSFHD25mMuEWEz
13+
sbAj5kjKQUZLhXVDYoNfSCU3K5uYyDFUa7uyhvxVHjJWdlLRB8IsuPSncXgXNot4kp/0W19xaF4j
14+
xwtm
15+
-----END CERTIFICATE-----
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCqOzITX7jQkwRdN5nnx99JznNp
3+
g8XfZQxTu1gu5vBqOHi4BFwQNzMzwWp2JqTCFSjNG5bop9OdH9rB0UTT31QeFbT+KZ3sdCspAWW6
4+
dN5SV8nYRFm43uiEhxhpNRIMCFgcS1k+/qbeu8TzFi6rZAIrsYIeEN7TsVwjIjH3YZ/qlaSY0MiA
5+
GVITNhJvDBLwzh2buRABMBPgwO+f13HQKvtR6NqwdGz2J2WDfHCOPxQypgL8CX4eaTRJKCxEIQ8Q
6+
tm4yp9eNmE4Bc6z1OBz4MzB+wJkz5ftfWACgZqVTFy11EsWdLXcNQ2gRQyHS7INM7Ru1ae54Mw+G
7+
20+RHy/lCqbPAgMBAAECggEAc0ITPKTiCG6SVN8xmIput5VN9VIgJopPV14Qbek1PGYx7j4da2lE
8+
hLVfdNHjWfljn8QfYDVJhSgtQG+Fj4K1fI0r966L264oDuKAU0ePw+bmpkRZD1/1xM2HjKw/JOB9
9+
b+LgcVOP/lzaE9CgFrFm+th8BglcJa7/eFZNyHZUBUri/IBWuPczFlIrc5HKIlPVM8Bf4E9nLtLj
10+
90Gg5zuNHvmN4+gIig8kEhTbWFKL/L+8adElOO22jvJMC3cBMhrbtD5K73wQ50MbSglhHP7PY4Uq
11+
asR0CQu6tKhLyLni4tlWMiEAs8b7IsG7BIkeD7UUKX7PVoCay9vJLvYL9qOyMQKBgQDilmnfAK/J
12+
mVVWCRfj1kgkBAIgswH49c+UCz0U6EzpNFXxhkEnuP0yvMrFCKEXXOP6J8WqgDJ3bWJQHARLbhfd
13+
p4VzWbwHH0V+4IaoYdX8uhxoyW/PNoqvla8233REWMQcbYBVvPtlygmbswgBmNMA2t6cIGcdmxkY
14+
P+fTWUkNtwKBgQDAVAqHBSxd8SZ+WG9fCjJM1Yjo3908ANNCucDw7cXHs0zJOrB2DV5FZG6iZNev
15+
MjfKSvVx7qe55SGpJWl8aDpvJ/df6tPD1SLRLuM54IdN3c3B0bt8Vn77mMASPz3hnK8SKsJ9LFoh
16+
dPbbAaHJjhlVIymIjhX6+dx11CvzSBQvqQKBgQCtRH3zBHBoBfPGla+KDzsdJ1+FJ72zZiz0tV9h
17+
FH5zugyaY6KBQKmF2e5omz+sQOEoUq+JwPxWbPPH9JSoJajkW4zl91GcVKJs8j6mliHvX1YIHzl7
18+
x+ZnfFv+5wLenM5iOq3vYlMPtF6CjHXr2rRHrBacZv7TGd4nt/6LlHQTowKBgQCXt/RSDOex99Eo
19+
7DR3IcEKUYzeP/LzKad+RLCKntddsPjK6UxY5DTQwuhvnON0ZkYSg81Zoi2X/MPv/f5X0JUAKOQB
20+
O2rwWktL/xPrDU9PQsDUu9GNxWIIsbga7N6xAnws9aRVQE6dg/pUS9ZH/JvJSKK0AXofcUnTfZtq
21+
IBskeQKBgQCerwVey5BIjiePoeikal/BiNwLgjeOSPax6qs4/9wRDXnN/Qj3q486pXy4OohhIeXc
22+
G7aeI3PACO/a680Mtbzi3q/1PsHWuuWrIzin3kF0ri8X3pYrzyV2rwmJqe1HmmBKOVPEg/KtHwpW
23+
ORBoSiB2Hz9RmSdyBUK1grLz3GJNXQ==
24+
-----END PRIVATE KEY-----
2.23 KB
Binary file not shown.

0 commit comments

Comments
 (0)