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 ;
23
+ import java .util .function .Consumer ;
24
+ import java .util .stream .Stream ;
22
25
23
26
import org .eclipse .jetty .ee10 .servlet .ServletContextHandler ;
24
27
import org .eclipse .jetty .server .AbstractConnector ;
25
28
import org .eclipse .jetty .server .ConnectionFactory ;
29
+ import org .eclipse .jetty .server .Connector ;
26
30
import org .eclipse .jetty .server .CustomRequestLog ;
27
31
import org .eclipse .jetty .server .Handler ;
28
32
import org .eclipse .jetty .server .HttpConfiguration ;
29
33
import org .eclipse .jetty .server .RequestLogWriter ;
30
- import org .eclipse .jetty .server .Server ;
31
34
32
35
import org .springframework .boot .autoconfigure .web .ServerProperties ;
33
36
import org .springframework .boot .cloud .CloudPlatform ;
34
37
import org .springframework .boot .context .properties .PropertyMapper ;
35
38
import org .springframework .boot .web .embedded .jetty .ConfigurableJettyWebServerFactory ;
36
- import org .springframework .boot .web .embedded .jetty .JettyServerCustomizer ;
37
39
import org .springframework .boot .web .server .WebServerFactoryCustomizer ;
38
40
import org .springframework .core .Ordered ;
39
41
import org .springframework .core .env .Environment ;
@@ -83,18 +85,21 @@ public void customize(ConfigurableJettyWebServerFactory factory) {
83
85
map .from (this .serverProperties ::getMaxHttpRequestHeaderSize )
84
86
.asInt (DataSize ::toBytes )
85
87
.when (this ::isPositive )
86
- .to ((maxHttpRequestHeaderSize ) -> factory
87
- .addServerCustomizers (new MaxHttpRequestHeaderSizeCustomizer (maxHttpRequestHeaderSize )));
88
+ .to (customizeHttpConfigurations (factory , HttpConfiguration ::setRequestHeaderSize ));
88
89
map .from (properties ::getMaxHttpResponseHeaderSize )
89
90
.asInt (DataSize ::toBytes )
90
91
.when (this ::isPositive )
91
- .to ((maxHttpResponseHeaderSize ) -> factory
92
- .addServerCustomizers (new MaxHttpResponseHeaderSizeCustomizer (maxHttpResponseHeaderSize )));
92
+ .to (customizeHttpConfigurations (factory , HttpConfiguration ::setResponseHeaderSize ));
93
93
map .from (properties ::getMaxHttpFormPostSize )
94
94
.asInt (DataSize ::toBytes )
95
95
.when (this ::isPositive )
96
- .to ((maxHttpFormPostSize ) -> customizeMaxHttpFormPostSize (factory , maxHttpFormPostSize ));
97
- map .from (properties ::getConnectionIdleTimeout ).to ((idleTimeout ) -> customizeIdleTimeout (factory , idleTimeout ));
96
+ .to (customizeServletContextHandler (factory , ServletContextHandler ::setMaxFormContentSize ));
97
+ map .from (properties ::getMaxFormKeys )
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 ));
98
103
map .from (properties ::getAccesslog )
99
104
.when (ServerProperties .Jetty .Accesslog ::isEnabled )
100
105
.to ((accesslog ) -> customizeAccessLog (factory , accesslog ));
@@ -112,43 +117,63 @@ private boolean getOrDeduceUseForwardHeaders() {
112
117
return this .serverProperties .getForwardHeadersStrategy ().equals (ServerProperties .ForwardHeadersStrategy .NATIVE );
113
118
}
114
119
115
- private void customizeIdleTimeout (ConfigurableJettyWebServerFactory factory , Duration connectionTimeout ) {
116
- factory .addServerCustomizers ((server ) -> {
117
- for (org .eclipse .jetty .server .Connector connector : server .getConnectors ()) {
118
- if (connector instanceof AbstractConnector abstractConnector ) {
119
- abstractConnector .setIdleTimeout (connectionTimeout .toMillis ());
120
- }
121
- }
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 );
122
131
});
123
132
}
124
133
125
- private void customizeMaxHttpFormPostSize (ConfigurableJettyWebServerFactory factory , int maxHttpFormPostSize ) {
126
- 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
+ }
127
138
128
- @ Override
129
- public void customize (Server server ) {
130
- setHandlerMaxHttpFormPostSize (server .getHandlers ());
131
- }
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
+ }
132
146
133
- private void setHandlerMaxHttpFormPostSize (List <Handler > handlers ) {
134
- for (Handler handler : handlers ) {
135
- setHandlerMaxHttpFormPostSize (handler );
136
- }
137
- }
147
+ private <V > Consumer <V > customizeServletContextHandler (ConfigurableJettyWebServerFactory factory ,
148
+ BiConsumer <ServletContextHandler , V > action ) {
149
+ return customizeHandlers (factory , ServletContextHandler .class , action );
150
+ }
138
151
139
- private void setHandlerMaxHttpFormPostSize (Handler handler ) {
140
- if (handler instanceof ServletContextHandler contextHandler ) {
141
- contextHandler .setMaxFormContentSize (maxHttpFormPostSize );
142
- }
143
- else if (handler instanceof Handler .Wrapper wrapper ) {
144
- setHandlerMaxHttpFormPostSize (wrapper .getHandler ());
145
- }
146
- else if (handler instanceof Handler .Collection collection ) {
147
- setHandlerMaxHttpFormPostSize (collection .getHandlers ());
148
- }
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 );
165
+ }
166
+ if (handler instanceof Handler .Wrapper wrapper ) {
167
+ forEachHandler (wrapper .getHandlers (), handlerType , action , value );
149
168
}
169
+ if (handler instanceof Handler .Collection collection ) {
170
+ forEachHandler (collection .getHandlers (), handlerType , action , value );
171
+ }
172
+ }
173
+ }
150
174
151
- });
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 ));
152
177
}
153
178
154
179
private void customizeAccessLog (ConfigurableJettyWebServerFactory factory ,
@@ -176,61 +201,10 @@ private String getLogFormat(ServerProperties.Jetty.Accesslog properties) {
176
201
if (properties .getCustomFormat () != null ) {
177
202
return properties .getCustomFormat ();
178
203
}
179
- else if (ServerProperties .Jetty .Accesslog .FORMAT .EXTENDED_NCSA .equals (properties .getFormat ())) {
204
+ if (ServerProperties .Jetty .Accesslog .FORMAT .EXTENDED_NCSA .equals (properties .getFormat ())) {
180
205
return CustomRequestLog .EXTENDED_NCSA_FORMAT ;
181
206
}
182
207
return CustomRequestLog .NCSA_FORMAT ;
183
208
}
184
209
185
- private static class MaxHttpRequestHeaderSizeCustomizer implements JettyServerCustomizer {
186
-
187
- private final int maxRequestHeaderSize ;
188
-
189
- MaxHttpRequestHeaderSizeCustomizer (int maxRequestHeaderSize ) {
190
- this .maxRequestHeaderSize = maxRequestHeaderSize ;
191
- }
192
-
193
- @ Override
194
- public void customize (Server server ) {
195
- Arrays .stream (server .getConnectors ()).forEach (this ::customize );
196
- }
197
-
198
- private void customize (org .eclipse .jetty .server .Connector connector ) {
199
- connector .getConnectionFactories ().forEach (this ::customize );
200
- }
201
-
202
- private void customize (ConnectionFactory factory ) {
203
- if (factory instanceof HttpConfiguration .ConnectionFactory ) {
204
- ((HttpConfiguration .ConnectionFactory ) factory ).getHttpConfiguration ()
205
- .setRequestHeaderSize (this .maxRequestHeaderSize );
206
- }
207
- }
208
-
209
- }
210
-
211
- private static class MaxHttpResponseHeaderSizeCustomizer implements JettyServerCustomizer {
212
-
213
- private final int maxResponseHeaderSize ;
214
-
215
- MaxHttpResponseHeaderSizeCustomizer (int maxResponseHeaderSize ) {
216
- this .maxResponseHeaderSize = maxResponseHeaderSize ;
217
- }
218
-
219
- @ Override
220
- public void customize (Server server ) {
221
- Arrays .stream (server .getConnectors ()).forEach (this ::customize );
222
- }
223
-
224
- private void customize (org .eclipse .jetty .server .Connector connector ) {
225
- connector .getConnectionFactories ().forEach (this ::customize );
226
- }
227
-
228
- private void customize (ConnectionFactory factory ) {
229
- if (factory instanceof HttpConfiguration .ConnectionFactory httpConnectionFactory ) {
230
- httpConnectionFactory .getHttpConfiguration ().setResponseHeaderSize (this .maxResponseHeaderSize );
231
- }
232
- }
233
-
234
- }
235
-
236
210
}
0 commit comments