Skip to content

Commit 7001e2b

Browse files
committed
添加 solon-server-tomcat-jakarta ssl 支持
1 parent 6a63739 commit 7001e2b

File tree

3 files changed

+155
-12
lines changed

3 files changed

+155
-12
lines changed

solon-jakarta-projects/solon-server/solon-server-tomcat-jakarta/src/main/java/org/noear/solon/server/tomcat/TomcatServer.java

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,25 @@
1919
import org.apache.catalina.Wrapper;
2020
import org.apache.catalina.connector.Connector;
2121
import org.apache.catalina.startup.Tomcat;
22+
import org.apache.coyote.http11.Http11NioProtocol;
23+
import org.apache.tomcat.util.net.SSLHostConfig;
24+
import org.apache.tomcat.util.net.SSLHostConfigCertificate;
2225
import org.noear.solon.core.util.IoUtil;
2326
import org.noear.solon.server.ServerProps;
2427
import org.noear.solon.server.handle.SessionProps;
2528
import org.noear.solon.server.prop.impl.HttpServerProps;
2629
import org.noear.solon.server.tomcat.http.TCHttpContextHandler;
2730

2831
import jakarta.servlet.MultipartConfigElement;
32+
import org.noear.solon.server.tomcat.ssl.TomcatSslContext;
33+
34+
import javax.net.ssl.SSLContext;
2935

3036
/**
3137
* @author Yukai
38+
* @author noear
3239
* @since 2019/3/28 15:49
40+
* @since 3.6
3341
*/
3442
public class TomcatServer extends TomcatServerBase {
3543
protected boolean isSecure;
@@ -81,32 +89,59 @@ protected Context initContext() {
8189

8290
@Override
8391
protected void addConnector(int port, boolean isMain) throws Throwable {
84-
Connector connector = new Connector("HTTP/1.1");
92+
//::protocol
93+
final Http11NioProtocol protocol = new Http11NioProtocol();
94+
95+
if (ServerProps.request_maxHeaderSize > 0) {
96+
protocol.setMaxHttpHeaderSize(ServerProps.request_maxHeaderSize);
97+
}
98+
99+
if (ServerProps.request_maxBodySize > 0) {
100+
protocol.setMaxSwallowSize(ServerProps.request_maxBodySizeAsInt());
101+
}
102+
103+
protocol.setRelaxedQueryChars("[]|{}");
104+
105+
if (isMain) {
106+
//for protocol ssl
107+
if (sslConfig.isSslEnable()) {
108+
protocol.setSSLEnabled(true);
109+
protocol.setSecure(true);
110+
protocol.addSslHostConfig(createSSLHostConfig(sslConfig.getSslContext()));
111+
isSecure = true;
112+
}
113+
}
114+
115+
116+
//::connector
117+
final Connector connector = new Connector(protocol);
85118

86119
connector.setPort(port);
87120

88121
if (isMain) {
89-
//for ssl
122+
//for connector ssl
90123
if (sslConfig.isSslEnable()) {
91-
// 1. 标识 ssl
92124
connector.setSecure(true);
93125
connector.setScheme("https");
94-
95-
isSecure = true;
96126
}
97127
}
98128

99129
connector.setMaxPostSize(ServerProps.request_maxBodySizeAsInt());
100130
connector.setMaxPartHeaderSize(ServerProps.request_maxHeaderSize);
101-
102-
connector.setProperty("maxHttpHeaderSize", String.valueOf(ServerProps.request_maxHeaderSize));
103-
connector.setProperty("maxSwallowSize", String.valueOf(ServerProps.request_maxBodySize));
104-
105-
connector.setProperty("relaxedQueryChars", "[]|{}");
106131
connector.setURIEncoding(ServerProps.request_encoding);
107132
connector.setUseBodyEncodingForURI(true);
108133

109-
110134
_server.getService().addConnector(connector);
111135
}
136+
137+
private static SSLHostConfig createSSLHostConfig(final SSLContext sslContext) {
138+
final SSLHostConfig sslHostConfig = new SSLHostConfig();
139+
140+
final SSLHostConfigCertificate sslHostConfigCertificate =
141+
new SSLHostConfigCertificate(sslHostConfig, SSLHostConfigCertificate.Type.RSA);
142+
sslHostConfigCertificate.setSslContext(new TomcatSslContext(sslContext));
143+
144+
sslHostConfig.addCertificate(sslHostConfigCertificate);
145+
return sslHostConfig;
146+
}
112147
}

solon-jakarta-projects/solon-server/solon-server-tomcat-jakarta/src/main/java/org/noear/solon/server/tomcat/TomcatServerBase.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package org.noear.solon.server.tomcat;
1717

1818
import org.apache.catalina.Context;
19-
import org.apache.catalina.connector.Connector;
2019
import org.apache.catalina.startup.Tomcat;
2120
import org.noear.solon.Utils;
2221
import org.noear.solon.lang.Nullable;
@@ -33,9 +32,12 @@
3332
import java.util.Set;
3433
import java.util.concurrent.Executor;
3534

35+
3636
/**
3737
* @author Yukai
38+
* @author noear
3839
* @since 2022/8/26 17:01
40+
* @since 3.6
3941
**/
4042
public abstract class TomcatServerBase implements ServerLifecycle, HttpServerConfigure {
4143
static final Logger log = LoggerFactory.getLogger(TomcatServerBase.class);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright 2017-2025 noear.org and authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.noear.solon.server.tomcat.ssl;
17+
18+
import org.apache.tomcat.util.net.SSLContext;
19+
20+
import javax.net.ssl.*;
21+
import java.security.KeyManagementException;
22+
import java.security.SecureRandom;
23+
import java.security.cert.X509Certificate;
24+
import java.util.Arrays;
25+
import java.util.HashSet;
26+
import java.util.Set;
27+
28+
/**
29+
* Tomcat SSLContext 实现
30+
*
31+
* @author Looly
32+
* @since 3.6.0
33+
*/
34+
public class TomcatSslContext implements SSLContext {
35+
private final javax.net.ssl.SSLContext context;
36+
private KeyManager[] kms;
37+
private TrustManager[] tms;
38+
39+
/**
40+
* 构造
41+
*
42+
* @param context SSLContext
43+
*/
44+
public TomcatSslContext(final javax.net.ssl.SSLContext context) {
45+
this.context = context;
46+
}
47+
48+
@Override
49+
public void init(final KeyManager[] kms, final TrustManager[] tms, final SecureRandom sr)
50+
throws KeyManagementException {
51+
this.kms = kms;
52+
this.tms = tms;
53+
context.init(kms, tms, sr);
54+
}
55+
56+
@Override
57+
public void destroy() {
58+
}
59+
60+
@Override
61+
public SSLSessionContext getServerSessionContext() {
62+
return context.getServerSessionContext();
63+
}
64+
65+
@Override
66+
public SSLEngine createSSLEngine() {
67+
return context.createSSLEngine();
68+
}
69+
70+
@Override
71+
public SSLServerSocketFactory getServerSocketFactory() {
72+
return context.getServerSocketFactory();
73+
}
74+
75+
@Override
76+
public SSLParameters getSupportedSSLParameters() {
77+
return context.getSupportedSSLParameters();
78+
}
79+
80+
@Override
81+
public X509Certificate[] getCertificateChain(final String alias) {
82+
X509Certificate[] result = null;
83+
if (kms != null) {
84+
for (int i = 0; i < kms.length && result == null; i++) {
85+
if (kms[i] instanceof X509KeyManager) {
86+
result = ((X509KeyManager) kms[i]).getCertificateChain(alias);
87+
}
88+
}
89+
}
90+
return result;
91+
}
92+
93+
@Override
94+
public X509Certificate[] getAcceptedIssuers() {
95+
final Set<X509Certificate> certs = new HashSet<>();
96+
if (tms != null) {
97+
for (final TrustManager tm : tms) {
98+
if (tm instanceof X509TrustManager) {
99+
final X509Certificate[] accepted = ((X509TrustManager) tm).getAcceptedIssuers();
100+
certs.addAll(Arrays.asList(accepted));
101+
}
102+
}
103+
}
104+
return certs.toArray(new X509Certificate[0]);
105+
}
106+
}

0 commit comments

Comments
 (0)