Skip to content

Commit 7d82072

Browse files
thanosploumisThanos Ploumisjstefl
authored
Noe core clean up (#107)
UpgradeProtocol for connctors + refactoring Co-authored-by: Thanos Ploumis <[email protected]> Co-authored-by: Jan Stefl <[email protected]>
1 parent 8860440 commit 7d82072

File tree

9 files changed

+361
-42
lines changed

9 files changed

+361
-42
lines changed

core/src/main/groovy/noe/server/Tomcat.groovy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ class Tomcat extends ServerAbstract implements WorkerServer {
628628
this.updateConfReplaceRegExp('server.xml', '<Connector port="8009" protocol="AJP/1.3"', '<Connector port="' + Integer.valueOf(8009 + offset) + '" protocol="AJP/1.3"', true, true)
629629
}
630630

631+
@Deprecated
631632
void enableSslJsse() {
632633
def nl = platform.nl
633634
def aprListener = '<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />'
@@ -642,6 +643,7 @@ class Tomcat extends ServerAbstract implements WorkerServer {
642643
updateConfReplaceRegExp('server.xml', dummyComment, enableJavaSsl, true, true)
643644
}
644645

646+
@Deprecated
645647
void enableSslOpenSsl() {
646648
def nl = platform.nl
647649
def dummyComment = '<!-- Define an AJP 1.3 Connector on port 8009 -->'
@@ -655,6 +657,7 @@ class Tomcat extends ServerAbstract implements WorkerServer {
655657
updateConfReplaceRegExp('server.xml', dummyComment, enableOpenSsl, true, true)
656658
}
657659

660+
@Deprecated
658661
void enableSslNIOProtocol() {
659662
def nl = platform.nl
660663
def aprListener = '<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />'

core/src/main/groovy/noe/tomcat/configure/AjpConnectorTomcat.groovy

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ public class AjpConnectorTomcat extends ConnectorTomcatAbstract<AjpConnectorTomc
1919
private String secret
2020
private String allowedRequestAttributesPattern
2121

22+
public AjpConnectorTomcat() {
23+
protocol = "AJP/1.3"
24+
}
25+
2226
Boolean getSecretRequired() {
2327
return secretRequired
2428
}

core/src/main/groovy/noe/tomcat/configure/ConnectorAttributesTransformer.groovy

Lines changed: 75 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,25 @@ class ConnectorAttributesTransformer {
1414

1515
/**
1616
* Provides attributes for non secure HTTP connector.
17-
* Returns map of key:value corresponding with attributes in Tomcat server.xml.
17+
* Returns Node applicable into Tomcat server.xml.
1818
*/
19-
Map<String, Object> nonSecureHttpConnector() {
19+
Node nonSecureHttpConnector() {
2020
return new CommonConnectorTransformer(connector).transform()
2121
}
2222

2323
/**
2424
* Provides attributes for secure HTTP connector.
25-
* Returns map of key:value corresponding with attributes in Tomcat server.xml.
25+
* Returns Node applicable into Tomcat server.xml.
2626
*/
27-
Map<String, Object> secureHttpConnector() {
27+
Node secureHttpConnector() {
2828
return new SecureHttpTransformer(connector).transform()
2929
}
3030

3131
/**
3232
* Provides attributes for AJP connector.
33-
* Returns map of key:value corresponding with attributes in Tomcat server.xml.
33+
* Returns Node applicable into Tomcat server.xml.
3434
*/
35-
Map<String, Object> ajpConnector() {
35+
Node ajpConnector() {
3636
return new CommonConnectorTransformer(connector).transform()
3737
}
3838

@@ -47,51 +47,65 @@ class ConnectorAttributesTransformer {
4747
this.connector = connector
4848
}
4949

50-
Map<String, Object> transform() {
51-
Map<String, Object> res = [:]
50+
Node transform() {
51+
Map<String, Object> attributes = [:]
5252

53+
// -- attributes -------------------------
5354
if (connector.getPort() != null && connector.getPort() > 0) {
54-
res.put('port', connector.getPort())
55+
attributes.put('port', connector.getPort())
5556
}
5657
if (connector.getProtocol() != null && !connector.getProtocol().isEmpty()) {
57-
res.put('protocol', connector.getProtocol())
58+
attributes.put('protocol', connector.getProtocol())
5859
}
5960
if (connector.getSecure() != null) {
60-
res.put('secure', connector.getSecure())
61+
attributes.put('secure', connector.getSecure())
6162
}
6263
if (connector.getScheme() != null && !connector.getScheme().isEmpty()) {
63-
res.put('scheme', connector.getScheme())
64+
attributes.put('scheme', connector.getScheme())
6465
}
6566

6667
if (connector.getMaxThreads() != null && connector.getMaxThreads() > 0) {
67-
res.put('maxThreads', connector.getMaxThreads())
68+
attributes.put('maxThreads', connector.getMaxThreads())
6869
}
6970
if (connector.getAddress() != null && !connector.getAddress().isEmpty()) {
70-
res.put('address', connector.getAddress())
71+
attributes.put('address', connector.getAddress())
7172
}
7273
if (connector.getConnectionTimeout() != null && connector.getConnectionTimeout() > 0) {
73-
res.put('connectionTimeout', connector.getConnectionTimeout())
74+
attributes.put('connectionTimeout', connector.getConnectionTimeout())
7475
}
7576
if (connector.getRedirectPort() != null && connector.getRedirectPort() > 0) {
76-
res.put('redirectPort', connector.getRedirectPort())
77+
attributes.put('redirectPort', connector.getRedirectPort())
7778
}
7879

7980
if(connector instanceof AjpConnectorTomcat) {
8081
if (connector.getSecretRequired() != null) {
81-
res.put('secretRequired', connector.getSecretRequired())
82+
attributes.put('secretRequired', connector.getSecretRequired())
8283
}
8384

8485
if (connector.getSecret() != null && !connector.getSecret().isEmpty()) {
85-
res.put('secret', connector.getSecret())
86+
attributes.put('secret', connector.getSecret())
8687
}
8788

8889
if (connector.getAllowedRequestAttributesPattern() != null
8990
&& !connector.getAllowedRequestAttributesPattern().isEmpty()) {
90-
res.put('allowedRequestAttributesPattern', connector.getAllowedRequestAttributesPattern())
91+
attributes.put('allowedRequestAttributesPattern', connector.getAllowedRequestAttributesPattern())
9192
}
9293
}
94+
// ---------------------
9395

94-
return res
96+
97+
Node node = new Node(null, "Connector", attributes)
98+
99+
100+
// -- sub elements -----
101+
if (connector instanceof NonSecureHttpConnectorTomcat) {
102+
if (connector.getUpgradeProtocol() != null) {
103+
node.appendNode("UpgradeProtocol", ['className': connector.getUpgradeProtocol().getClassName()])
104+
}
105+
}
106+
// --------------------
107+
108+
return node
95109
}
96110
}
97111

@@ -102,39 +116,69 @@ class ConnectorAttributesTransformer {
102116
this.connector = connector
103117
}
104118

105-
Map<String, Object> transform() {
106-
Map<String, Object> res = new CommonConnectorTransformer(connector).transform()
119+
Node transform() {
120+
Node node = new CommonConnectorTransformer(connector).transform()
121+
Map<String, Object> attributes = node.attributes()
107122

123+
// -- attributes -------------------------
108124
if (connector.getSslEnabled() != null) {
109-
res.put('SSLEnabled', connector.getSslEnabled())
125+
attributes.put('SSLEnabled', connector.getSslEnabled())
110126
}
111127

112128
// SSL BIO and NIO
113129
if (connector.getSslProtocol() != null && !connector.getSslProtocol().isEmpty()) {
114-
res.put('sslProtocol', connector.getSslProtocol())
130+
attributes.put('sslProtocol', connector.getSslProtocol())
115131
}
116132
if (connector.getKeystoreFile() != null && !connector.getKeystoreFile().isEmpty()) {
117-
res.put('keystoreFile', connector.getKeystoreFile())
133+
attributes.put('keystoreFile', connector.getKeystoreFile())
118134
}
119135
if (connector.getKeystorePass() != null && !connector.getKeystorePass().isEmpty()) {
120-
res.put('keystorePass', connector.getKeystorePass())
136+
attributes.put('keystorePass', connector.getKeystorePass())
137+
}
138+
if (connector.getKeystoreType() != null && !connector.getKeystoreType().isEmpty()) {
139+
attributes.put('keystoreType', connector.getKeystoreType())
140+
}
141+
if (connector.getTruststoreFile() != null && !connector.getTruststoreFile().isEmpty()) {
142+
attributes.put('truststoreFile', connector.getTruststoreFile())
143+
}
144+
if (connector.getTruststorePass() != null && !connector.getTruststorePass().isEmpty()) {
145+
attributes.put('truststorePass', connector.getTruststorePass())
146+
}
147+
if (connector.getTruststoreType() != null && !connector.getTruststoreType().isEmpty()) {
148+
attributes.put('truststoreType', connector.getTruststoreType())
121149
}
122150
if (connector.getClientAuth() != null) {
123-
res.put('clientAuth', connector.getClientAuth())
151+
attributes.put('clientAuth', connector.getClientAuth())
152+
}
153+
154+
// HTTP2
155+
if (connector.getSslImplementationName() != null && !connector.getSslImplementationName().isEmpty()) {
156+
attributes.put('sslImplementationName', connector.getSslImplementationName())
124157
}
125158

126159
// SSL APR
127160
if (connector.getSslCertificateFile() != null && !connector.getSslCertificateFile().isEmpty()) {
128-
res.put('SSLCertificateFile', connector.getSslCertificateFile())
161+
attributes.put('SSLCertificateFile', connector.getSslCertificateFile())
162+
}
163+
if (connector.getSslCACertificateFile() != null && !connector.getSslCACertificateFile().isEmpty()) {
164+
attributes.put('SSLCACertificateFile', connector.getSslCACertificateFile())
129165
}
130166
if (connector.getSslCertificateKeyFile() != null && !connector.getSslCertificateKeyFile().isEmpty()) {
131-
res.put('SSLCertificateKeyFile', connector.getSslCertificateKeyFile())
167+
attributes.put('SSLCertificateKeyFile', connector.getSslCertificateKeyFile())
132168
}
133169
if (connector.getSslPassword() != null && !connector.getSslPassword().isEmpty()) {
134-
res.put('SSLPassword', connector.getSslPassword())
170+
attributes.put('SSLPassword', connector.getSslPassword())
171+
}
172+
if (connector.getSslEnabledProtocols() != null && connector.getSslEnabledProtocols()) {
173+
attributes.put('sslEnabledProtocols', connector.getSslEnabledProtocols())
174+
}
175+
// ---------------------
176+
177+
if (connector.getUpgradeProtocol() != null) {
178+
node.appendNode("UpgradeProtocol", ['className': connector.getUpgradeProtocol().getClassName()])
135179
}
136180

137-
return res
181+
return node
138182
}
139183
}
140184

core/src/main/groovy/noe/tomcat/configure/ConnectorConfiguratorTomcat.groovy

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ class ConnectorConfiguratorTomcat {
2727
int httpConnectorSize = loadHttpConnectorSize()
2828

2929
if (httpConnectorSize > 1) {
30-
throw new IllegalStateException("Unexpected server.xml format - one secure connector expected at most")
30+
throw new IllegalStateException("Unexpected server.xml format - one non secure connector expected at most")
3131
}
3232
if (httpConnectorSize == 1) {
33-
Node Connector = loadExistingHttpConnector()
34-
updateExistingConnector(Connector, new ConnectorAttributesTransformer(connector).nonSecureHttpConnector())
33+
Node ConnectorElement = loadExistingHttpConnector()
34+
updateExistingConnector(ConnectorElement, new ConnectorAttributesTransformer(connector).nonSecureHttpConnector())
3535
} else {
3636
createNewConnector(new ConnectorAttributesTransformer(connector).nonSecureHttpConnector())
3737
}
@@ -104,7 +104,7 @@ class ConnectorConfiguratorTomcat {
104104
} else if (connectors.size() < 1) {
105105
return null
106106
} else {
107-
throw new IllegalStateException("Unexpected server.xml format - one http connector expected")
107+
throw new IllegalStateException("Unexpected server.xml format - one https connector expected at most")
108108
}
109109
}
110110

@@ -115,23 +115,44 @@ class ConnectorConfiguratorTomcat {
115115
} else if (connectors.size() < 1) {
116116
return null
117117
} else {
118-
throw new IllegalStateException("Unexpected server.xml format - one http connector expected at most")
118+
throw new IllegalStateException("Unexpected server.xml format - one ajp connector expected at most")
119119
}
120120
}
121121

122122
private boolean isSecured(Node connector) {
123123
return connector.@secure.toString().toLowerCase().trim() == "true"
124124
}
125125

126-
private void createNewConnector(Map<String, Object> attributes) {
127-
server.Service.each { service ->
128-
service.appendNode ("Connector", attributes)
126+
127+
private void createNewConnector(Node element) {
128+
server.Service.each { Node service ->
129+
service.appendNode(element, element.attributes(), element.value())
129130
}
130131
}
131132

132-
private void updateExistingConnector(Node Connector, Map<String, Object> attributes) {
133-
attributes.each { attribute ->
134-
Connector.@"${attribute.key}" = attribute.value
133+
private void updateExistingConnector(Node connector, Node newConnector) {
134+
// update attributes
135+
newConnector.attributes().each { attribute ->
136+
connector.@"${attribute.key}" = attribute.value
137+
}
138+
139+
// update nodes
140+
newConnector.each { Node newSubelement ->
141+
String UpgradeProtocol = ConnectorUpgradeProtocolTomcat.ELEMENT_NAME
142+
143+
if (newSubelement.name() == UpgradeProtocol) {
144+
if (connector.find { it.name() == UpgradeProtocol } == null) {
145+
// create new element
146+
connector.appendNode(newSubelement, newSubelement.attributes(), newSubelement.value())
147+
} else {
148+
// upgrade existing element
149+
connector.findAll { it.name() == UpgradeProtocol }.each { upgradeProtocol ->
150+
newSubelement.attributes() { attribute ->
151+
upgradeProtocol.@"${attribute.key}" = attribute.value
152+
}
153+
}
154+
}
155+
}
135156
}
136157
}
137158

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package noe.tomcat.configure
2+
3+
/**
4+
* Abstraction for HTTP connector, the element UpgradeProtocol.
5+
*
6+
* @link https://tomcat.apache.org/tomcat-8.5-doc/config/http2.html
7+
*/
8+
class ConnectorUpgradeProtocolTomcat {
9+
10+
public static String ELEMENT_NAME = "UpgradeProtocol"
11+
12+
public static String PROTOCOL_CLASS_HTTP2 = "org.apache.coyote.http2.Http2Protocol"
13+
14+
public String className
15+
16+
17+
public String getClassName() {
18+
return this.className
19+
}
20+
21+
public setClassName(String className) {
22+
this.className = className
23+
return this
24+
}
25+
26+
}

core/src/main/groovy/noe/tomcat/configure/NonSecureHttpConnectorTomcat.groovy

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,27 @@ package noe.tomcat.configure
1717
*/
1818
public class NonSecureHttpConnectorTomcat extends ConnectorTomcatAbstract<NonSecureHttpConnectorTomcat> {
1919

20+
private ConnectorUpgradeProtocolTomcat upgradeProtocol
21+
22+
2023
public NonSecureHttpConnectorTomcat() {
2124
super.setSecure(false)
2225
}
2326

27+
public ConnectorUpgradeProtocolTomcat getUpgradeProtocol() {
28+
return upgradeProtocol
29+
}
30+
31+
public NonSecureHttpConnectorTomcat setUpgradeProtocol(ConnectorUpgradeProtocolTomcat upgradeProtocol) {
32+
this.upgradeProtocol = upgradeProtocol
33+
return this
34+
}
35+
36+
public NonSecureHttpConnectorTomcat setUpgradeProtocolToHttp2Protocol() {
37+
setUpgradeProtocol(new ConnectorUpgradeProtocolTomcat().setClassName(ConnectorUpgradeProtocolTomcat.PROTOCOL_CLASS_HTTP2))
38+
return this
39+
}
40+
2441
/**
2542
* Input argument secure is ignored secure is set 'false' always.
2643
*/

0 commit comments

Comments
 (0)