16
16
17
17
package org .springframework .cloud .gateway .server .mvc ;
18
18
19
+ import java .util .Map ;
20
+
19
21
import org .springframework .beans .factory .ObjectProvider ;
22
+ import org .springframework .boot .SpringApplication ;
20
23
import org .springframework .boot .autoconfigure .AutoConfiguration ;
21
24
import org .springframework .boot .autoconfigure .condition .ConditionalOnMissingBean ;
22
25
import org .springframework .boot .autoconfigure .condition .ConditionalOnProperty ;
23
26
import org .springframework .boot .autoconfigure .http .client .HttpClientAutoConfiguration ;
24
- import org .springframework .boot .autoconfigure .http .client .HttpClientProperties ;
27
+ import org .springframework .boot .autoconfigure .http .client .HttpClientProperties . Factory ;
25
28
import org .springframework .boot .autoconfigure .web .client .RestClientAutoConfiguration ;
26
29
import org .springframework .boot .autoconfigure .web .client .RestTemplateAutoConfiguration ;
27
- import org .springframework .boot .http .client .ClientHttpRequestFactoryBuilder ;
28
- import org .springframework .boot .http .client .ClientHttpRequestFactorySettings ;
29
- import org .springframework .boot .http .client .JdkClientHttpRequestFactoryBuilder ;
30
- import org .springframework .boot .ssl .SslBundle ;
31
- import org .springframework .boot .ssl .SslBundles ;
30
+ import org .springframework .boot .env .EnvironmentPostProcessor ;
31
+ import org .springframework .boot .http .client .ClientHttpRequestFactorySettings .Redirects ;
32
32
import org .springframework .boot .web .client .RestClientCustomizer ;
33
33
import org .springframework .cloud .gateway .server .mvc .common .ArgumentSupplierBeanPostProcessor ;
34
34
import org .springframework .cloud .gateway .server .mvc .config .GatewayMvcAotRuntimeHintsRegistrar ;
55
55
import org .springframework .context .annotation .Bean ;
56
56
import org .springframework .context .annotation .Import ;
57
57
import org .springframework .context .annotation .ImportRuntimeHints ;
58
+ import org .springframework .core .env .ConfigurableEnvironment ;
58
59
import org .springframework .core .env .Environment ;
60
+ import org .springframework .core .env .MapPropertySource ;
59
61
import org .springframework .http .client .ClientHttpRequestFactory ;
62
+ import org .springframework .util .ClassUtils ;
60
63
import org .springframework .util .StringUtils ;
61
64
import org .springframework .web .client .RestClient ;
62
65
@@ -85,8 +88,12 @@ public RouterFunctionHolderFactory routerFunctionHolderFactory(Environment env)
85
88
}
86
89
87
90
@ Bean
88
- public RestClientCustomizer gatewayRestClientCustomizer (ClientHttpRequestFactory requestFactory ) {
89
- return restClientBuilder -> restClientBuilder .requestFactory (requestFactory );
91
+ public RestClientCustomizer gatewayRestClientCustomizer (
92
+ ObjectProvider <ClientHttpRequestFactory > requestFactoryProvider ) {
93
+ return restClientBuilder -> {
94
+ // for backwards compatibility if user overrode
95
+ requestFactoryProvider .ifAvailable (restClientBuilder ::requestFactory );
96
+ };
90
97
}
91
98
92
99
@ Bean
@@ -111,36 +118,6 @@ public ForwardedRequestHeadersFilter forwardedRequestHeadersFilter() {
111
118
return new ForwardedRequestHeadersFilter ();
112
119
}
113
120
114
- @ Bean
115
- @ ConditionalOnMissingBean
116
- public ClientHttpRequestFactory gatewayClientHttpRequestFactory (HttpClientProperties properties ,
117
- SslBundles sslBundles ) {
118
-
119
- SslBundle sslBundle = null ;
120
- if (StringUtils .hasText (properties .getSsl ().getBundle ())) {
121
- sslBundle = sslBundles .getBundle (properties .getSsl ().getBundle ());
122
- }
123
- ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings .ofSslBundle (sslBundle )
124
- .withConnectTimeout (properties .getConnectTimeout ())
125
- .withReadTimeout (properties .getReadTimeout ())
126
- .withRedirects (ClientHttpRequestFactorySettings .Redirects .DONT_FOLLOW );
127
-
128
- ClientHttpRequestFactoryBuilder <?> builder = ClientHttpRequestFactoryBuilder .detect ();
129
- if (builder instanceof JdkClientHttpRequestFactoryBuilder ) {
130
- // TODO: customize restricted headers
131
- String restrictedHeaders = System .getProperty ("jdk.httpclient.allowRestrictedHeaders" );
132
- if (!StringUtils .hasText (restrictedHeaders )) {
133
- System .setProperty ("jdk.httpclient.allowRestrictedHeaders" , "host" );
134
- }
135
- else if (StringUtils .hasText (restrictedHeaders ) && !restrictedHeaders .contains ("host" )) {
136
- System .setProperty ("jdk.httpclient.allowRestrictedHeaders" , restrictedHeaders + ",host" );
137
- }
138
- }
139
-
140
- // Autodetect
141
- return builder .build (settings );
142
- }
143
-
144
121
@ Bean
145
122
@ ConditionalOnMissingBean
146
123
public GatewayMvcProperties gatewayMvcProperties () {
@@ -222,4 +199,46 @@ public XForwardedRequestHeadersFilterProperties xForwardedRequestHeadersFilterPr
222
199
return new XForwardedRequestHeadersFilterProperties ();
223
200
}
224
201
202
+ static class GatewayHttpClientEnvironmentPostProcessor implements EnvironmentPostProcessor {
203
+
204
+ static final boolean APACHE = ClassUtils .isPresent ("org.apache.hc.client5.http.impl.classic.HttpClients" , null );
205
+ static final boolean JETTY = ClassUtils .isPresent ("org.eclipse.jetty.client.HttpClient" , null );
206
+ static final boolean REACTOR_NETTY = ClassUtils .isPresent ("reactor.netty.http.client.HttpClient" , null );
207
+ static final boolean JDK = ClassUtils .isPresent ("java.net.http.HttpClient" , null );
208
+ static final boolean HIGHER_PRIORITY = APACHE || JETTY || REACTOR_NETTY ;
209
+
210
+ @ Override
211
+ public void postProcessEnvironment (ConfigurableEnvironment environment , SpringApplication application ) {
212
+ Redirects redirects = environment .getProperty ("spring.http.client.redirects" , Redirects .class );
213
+ if (redirects == null ) {
214
+ // the user hasn't set anything, change the default
215
+ environment .getPropertySources ()
216
+ .addFirst (new MapPropertySource ("gatewayHttpClientProperties" ,
217
+ Map .of ("spring.http.client.redirects" , Redirects .DONT_FOLLOW )));
218
+ }
219
+ Factory factory = environment .getProperty ("spring.http.client.factory" , Factory .class );
220
+ boolean setJdkHttpClientProperties = false ;
221
+
222
+ if (factory == null && !HIGHER_PRIORITY ) {
223
+ // autodetect
224
+ setJdkHttpClientProperties = JDK ;
225
+ }
226
+ else if (factory == Factory .JDK ) {
227
+ setJdkHttpClientProperties = JDK ;
228
+ }
229
+
230
+ if (setJdkHttpClientProperties ) {
231
+ // TODO: customize restricted headers
232
+ String restrictedHeaders = System .getProperty ("jdk.httpclient.allowRestrictedHeaders" );
233
+ if (!StringUtils .hasText (restrictedHeaders )) {
234
+ System .setProperty ("jdk.httpclient.allowRestrictedHeaders" , "host" );
235
+ }
236
+ else if (StringUtils .hasText (restrictedHeaders ) && !restrictedHeaders .contains ("host" )) {
237
+ System .setProperty ("jdk.httpclient.allowRestrictedHeaders" , restrictedHeaders + ",host" );
238
+ }
239
+ }
240
+ }
241
+
242
+ }
243
+
225
244
}
0 commit comments