1
1
/*
2
- * Copyright 2012-2023 the original author or authors.
2
+ * Copyright 2012-2024 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
19
19
import java .time .Duration ;
20
20
import java .util .Arrays ;
21
21
import java .util .List ;
22
+ import java .util .function .BiConsumer ;
22
23
import java .util .function .Consumer ;
24
+ import java .util .stream .Stream ;
23
25
24
26
import org .eclipse .jetty .ee10 .servlet .ServletContextHandler ;
25
27
import org .eclipse .jetty .server .AbstractConnector ;
26
28
import org .eclipse .jetty .server .ConnectionFactory ;
29
+ import org .eclipse .jetty .server .Connector ;
27
30
import org .eclipse .jetty .server .CustomRequestLog ;
28
31
import org .eclipse .jetty .server .Handler ;
29
32
import org .eclipse .jetty .server .HttpConfiguration ;
30
33
import org .eclipse .jetty .server .RequestLogWriter ;
31
- import org .eclipse .jetty .server .Server ;
32
34
33
35
import org .springframework .boot .autoconfigure .web .ServerProperties ;
34
36
import org .springframework .boot .cloud .CloudPlatform ;
35
37
import org .springframework .boot .context .properties .PropertyMapper ;
36
38
import org .springframework .boot .web .embedded .jetty .ConfigurableJettyWebServerFactory ;
37
- import org .springframework .boot .web .embedded .jetty .JettyServerCustomizer ;
38
39
import org .springframework .boot .web .server .WebServerFactoryCustomizer ;
39
40
import org .springframework .core .Ordered ;
40
41
import org .springframework .core .env .Environment ;
@@ -84,22 +85,21 @@ public void customize(ConfigurableJettyWebServerFactory factory) {
84
85
map .from (this .serverProperties ::getMaxHttpRequestHeaderSize )
85
86
.asInt (DataSize ::toBytes )
86
87
.when (this ::isPositive )
87
- .to ((maxHttpRequestHeaderSize ) -> factory
88
- .addServerCustomizers (new MaxHttpRequestHeaderSizeCustomizer (maxHttpRequestHeaderSize )));
88
+ .to (customizeHttpConfigurations (factory , HttpConfiguration ::setRequestHeaderSize ));
89
89
map .from (properties ::getMaxHttpResponseHeaderSize )
90
90
.asInt (DataSize ::toBytes )
91
91
.when (this ::isPositive )
92
- .to ((maxHttpResponseHeaderSize ) -> factory
93
- .addServerCustomizers (new MaxHttpResponseHeaderSizeCustomizer (maxHttpResponseHeaderSize )));
92
+ .to (customizeHttpConfigurations (factory , HttpConfiguration ::setResponseHeaderSize ));
94
93
map .from (properties ::getMaxHttpFormPostSize )
95
94
.asInt (DataSize ::toBytes )
96
95
.when (this ::isPositive )
97
- .to (( maxHttpFormPostSize ) -> customizeServletContextHandler (factory , contextHandler -> contextHandler . setMaxFormContentSize ( maxHttpFormPostSize ) ));
96
+ .to (customizeServletContextHandler (factory , ServletContextHandler :: setMaxFormContentSize ));
98
97
map .from (properties ::getMaxFormKeys )
99
- .when (this ::isPositive )
100
- .to ((maxFormKeys ) -> customizeServletContextHandler (factory , contextHandler -> contextHandler .setMaxFormKeys (maxFormKeys )));
101
-
102
- map .from (properties ::getConnectionIdleTimeout ).to ((idleTimeout ) -> customizeIdleTimeout (factory , idleTimeout ));
98
+ .when (this ::isPositive )
99
+ .to (customizeServletContextHandler (factory , ServletContextHandler ::setMaxFormKeys ));
100
+ map .from (properties ::getConnectionIdleTimeout )
101
+ .as (Duration ::toMillis )
102
+ .to (customizeAbstractConnectors (factory , AbstractConnector ::setIdleTimeout ));
103
103
map .from (properties ::getAccesslog )
104
104
.when (ServerProperties .Jetty .Accesslog ::isEnabled )
105
105
.to ((accesslog ) -> customizeAccessLog (factory , accesslog ));
@@ -117,43 +117,63 @@ private boolean getOrDeduceUseForwardHeaders() {
117
117
return this .serverProperties .getForwardHeadersStrategy ().equals (ServerProperties .ForwardHeadersStrategy .NATIVE );
118
118
}
119
119
120
- private void customizeIdleTimeout (ConfigurableJettyWebServerFactory factory , Duration connectionTimeout ) {
121
- factory .addServerCustomizers ((server ) -> {
122
- for (org .eclipse .jetty .server .Connector connector : server .getConnectors ()) {
123
- if (connector instanceof AbstractConnector abstractConnector ) {
124
- abstractConnector .setIdleTimeout (connectionTimeout .toMillis ());
125
- }
126
- }
120
+ private <T > Consumer <T > customizeHttpConfigurations (ConfigurableJettyWebServerFactory factory ,
121
+ BiConsumer <HttpConfiguration , T > action ) {
122
+ return customizeConnectionFactories (factory , HttpConfiguration .ConnectionFactory .class ,
123
+ (connectionFactory , value ) -> action .accept (connectionFactory .getHttpConfiguration (), value ));
124
+ }
125
+
126
+ private <V , F > Consumer <V > customizeConnectionFactories (ConfigurableJettyWebServerFactory factory ,
127
+ Class <F > connectionFactoryType , BiConsumer <F , V > action ) {
128
+ return customizeConnectors (factory , Connector .class , (connector , value ) -> {
129
+ Stream <ConnectionFactory > connectionFactories = connector .getConnectionFactories ().stream ();
130
+ forEach (connectionFactories , connectionFactoryType , action , value );
127
131
});
128
132
}
129
133
130
- private void customizeServletContextHandler (ConfigurableJettyWebServerFactory factory , Consumer <ServletContextHandler > customFunc ) {
131
- factory .addServerCustomizers (new JettyServerCustomizer () {
134
+ private <V > Consumer <V > customizeAbstractConnectors (ConfigurableJettyWebServerFactory factory ,
135
+ BiConsumer <AbstractConnector , V > action ) {
136
+ return customizeConnectors (factory , AbstractConnector .class , action );
137
+ }
132
138
133
- @ Override
134
- public void customize (Server server ) {
135
- acceptCustomizeServletContextHandler (server .getHandlers ());
136
- }
139
+ private <V , C > Consumer <V > customizeConnectors (ConfigurableJettyWebServerFactory factory , Class <C > connectorType ,
140
+ BiConsumer <C , V > action ) {
141
+ return (value ) -> factory .addServerCustomizers ((server ) -> {
142
+ Stream <Connector > connectors = Arrays .stream (server .getConnectors ());
143
+ forEach (connectors , connectorType , action , value );
144
+ });
145
+ }
137
146
138
- private void acceptCustomizeServletContextHandler (List <Handler > handlers ) {
139
- for (Handler handler : handlers ) {
140
- acceptCustomizeServletContextHandler (handler );
141
- }
142
- }
147
+ private <V > Consumer <V > customizeServletContextHandler (ConfigurableJettyWebServerFactory factory ,
148
+ BiConsumer <ServletContextHandler , V > action ) {
149
+ return customizeHandlers (factory , ServletContextHandler .class , action );
150
+ }
143
151
144
- private void acceptCustomizeServletContextHandler (Handler handler ) {
145
- if (handler instanceof ServletContextHandler contextHandler ) {
146
- customFunc .accept (contextHandler );
147
- }
148
- else if (handler instanceof Handler .Wrapper wrapper ) {
149
- acceptCustomizeServletContextHandler (wrapper .getHandler ());
150
- }
151
- else if (handler instanceof Handler .Collection collection ) {
152
- acceptCustomizeServletContextHandler (collection .getHandlers ());
153
- }
152
+ private <V , H > Consumer <V > customizeHandlers (ConfigurableJettyWebServerFactory factory , Class <H > handlerType ,
153
+ BiConsumer <H , V > action ) {
154
+ return (value ) -> factory .addServerCustomizers ((server ) -> {
155
+ List <Handler > handlers = server .getHandlers ();
156
+ forEachHandler (handlers , handlerType , action , value );
157
+ });
158
+ }
159
+
160
+ @ SuppressWarnings ("unchecked" )
161
+ private <V , H > void forEachHandler (List <Handler > handlers , Class <H > handlerType , BiConsumer <H , V > action , V value ) {
162
+ for (Handler handler : handlers ) {
163
+ if (handlerType .isInstance (handler )) {
164
+ action .accept ((H ) handler , value );
154
165
}
166
+ if (handler instanceof Handler .Wrapper wrapper ) {
167
+ forEachHandler (wrapper .getHandlers (), handlerType , action , value );
168
+ }
169
+ if (handler instanceof Handler .Collection collection ) {
170
+ forEachHandler (collection .getHandlers (), handlerType , action , value );
171
+ }
172
+ }
173
+ }
155
174
156
- });
175
+ private <T , V > void forEach (Stream <?> elements , Class <T > type , BiConsumer <T , V > action , V value ) {
176
+ elements .filter (type ::isInstance ).map (type ::cast ).forEach ((element ) -> action .accept (element , value ));
157
177
}
158
178
159
179
private void customizeAccessLog (ConfigurableJettyWebServerFactory factory ,
@@ -181,61 +201,10 @@ private String getLogFormat(ServerProperties.Jetty.Accesslog properties) {
181
201
if (properties .getCustomFormat () != null ) {
182
202
return properties .getCustomFormat ();
183
203
}
184
- else if (ServerProperties .Jetty .Accesslog .FORMAT .EXTENDED_NCSA .equals (properties .getFormat ())) {
204
+ if (ServerProperties .Jetty .Accesslog .FORMAT .EXTENDED_NCSA .equals (properties .getFormat ())) {
185
205
return CustomRequestLog .EXTENDED_NCSA_FORMAT ;
186
206
}
187
207
return CustomRequestLog .NCSA_FORMAT ;
188
208
}
189
209
190
- private static class MaxHttpRequestHeaderSizeCustomizer implements JettyServerCustomizer {
191
-
192
- private final int maxRequestHeaderSize ;
193
-
194
- MaxHttpRequestHeaderSizeCustomizer (int maxRequestHeaderSize ) {
195
- this .maxRequestHeaderSize = maxRequestHeaderSize ;
196
- }
197
-
198
- @ Override
199
- public void customize (Server server ) {
200
- Arrays .stream (server .getConnectors ()).forEach (this ::customize );
201
- }
202
-
203
- private void customize (org .eclipse .jetty .server .Connector connector ) {
204
- connector .getConnectionFactories ().forEach (this ::customize );
205
- }
206
-
207
- private void customize (ConnectionFactory factory ) {
208
- if (factory instanceof HttpConfiguration .ConnectionFactory ) {
209
- ((HttpConfiguration .ConnectionFactory ) factory ).getHttpConfiguration ()
210
- .setRequestHeaderSize (this .maxRequestHeaderSize );
211
- }
212
- }
213
-
214
- }
215
-
216
- private static class MaxHttpResponseHeaderSizeCustomizer implements JettyServerCustomizer {
217
-
218
- private final int maxResponseHeaderSize ;
219
-
220
- MaxHttpResponseHeaderSizeCustomizer (int maxResponseHeaderSize ) {
221
- this .maxResponseHeaderSize = maxResponseHeaderSize ;
222
- }
223
-
224
- @ Override
225
- public void customize (Server server ) {
226
- Arrays .stream (server .getConnectors ()).forEach (this ::customize );
227
- }
228
-
229
- private void customize (org .eclipse .jetty .server .Connector connector ) {
230
- connector .getConnectionFactories ().forEach (this ::customize );
231
- }
232
-
233
- private void customize (ConnectionFactory factory ) {
234
- if (factory instanceof HttpConfiguration .ConnectionFactory httpConnectionFactory ) {
235
- httpConnectionFactory .getHttpConfiguration ().setResponseHeaderSize (this .maxResponseHeaderSize );
236
- }
237
- }
238
-
239
- }
240
-
241
210
}
0 commit comments