Browse Source
This commit applies `server.jetty.*` configuration properties to Jetty when configured as a reactive web server. It also removes some infrastructure support for Jetty 8, which is not supported anymore in Spring Boot 2.0 (partial fix for gh-11504). See gh-11500pull/11497/merge
10 changed files with 470 additions and 251 deletions
@ -0,0 +1,184 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2012-2018 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.springframework.boot.autoconfigure.web.embedded.jetty; |
||||||
|
|
||||||
|
import java.time.Duration; |
||||||
|
|
||||||
|
import org.eclipse.jetty.server.AbstractConnector; |
||||||
|
import org.eclipse.jetty.server.ConnectionFactory; |
||||||
|
import org.eclipse.jetty.server.Handler; |
||||||
|
import org.eclipse.jetty.server.HttpConfiguration; |
||||||
|
import org.eclipse.jetty.server.NCSARequestLog; |
||||||
|
import org.eclipse.jetty.server.Server; |
||||||
|
import org.eclipse.jetty.server.handler.ContextHandler; |
||||||
|
import org.eclipse.jetty.server.handler.HandlerCollection; |
||||||
|
import org.eclipse.jetty.server.handler.HandlerWrapper; |
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.web.ServerProperties; |
||||||
|
import org.springframework.boot.cloud.CloudPlatform; |
||||||
|
import org.springframework.boot.web.embedded.jetty.ConfigurableJettyWebServerFactory; |
||||||
|
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer; |
||||||
|
import org.springframework.core.env.Environment; |
||||||
|
|
||||||
|
/** |
||||||
|
* Customization for Jetty-specific features common |
||||||
|
* for both Servlet and Reactive servers. |
||||||
|
* |
||||||
|
* @author Brian Clozel |
||||||
|
* @since 2.0.0 |
||||||
|
*/ |
||||||
|
public final class JettyCustomizer { |
||||||
|
|
||||||
|
private JettyCustomizer() { |
||||||
|
} |
||||||
|
|
||||||
|
public static void customizeJetty(ServerProperties serverProperties, |
||||||
|
Environment environment, ConfigurableJettyWebServerFactory factory) { |
||||||
|
ServerProperties.Jetty jettyProperties = serverProperties.getJetty(); |
||||||
|
factory.setUseForwardHeaders( |
||||||
|
getOrDeduceUseForwardHeaders(serverProperties, environment)); |
||||||
|
if (jettyProperties.getAcceptors() != null) { |
||||||
|
factory.setAcceptors(jettyProperties.getAcceptors()); |
||||||
|
} |
||||||
|
if (jettyProperties.getSelectors() != null) { |
||||||
|
factory.setSelectors(jettyProperties.getSelectors()); |
||||||
|
} |
||||||
|
if (serverProperties.getMaxHttpHeaderSize() > 0) { |
||||||
|
customizeMaxHttpHeaderSize(factory, |
||||||
|
serverProperties.getMaxHttpHeaderSize()); |
||||||
|
} |
||||||
|
if (jettyProperties.getMaxHttpPostSize() > 0) { |
||||||
|
customizeMaxHttpPostSize(factory, jettyProperties.getMaxHttpPostSize()); |
||||||
|
} |
||||||
|
|
||||||
|
if (serverProperties.getConnectionTimeout() != null) { |
||||||
|
customizeConnectionTimeout(factory, |
||||||
|
serverProperties.getConnectionTimeout()); |
||||||
|
} |
||||||
|
if (jettyProperties.getAccesslog().isEnabled()) { |
||||||
|
customizeAccessLog(factory, jettyProperties.getAccesslog()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean getOrDeduceUseForwardHeaders(ServerProperties serverProperties, |
||||||
|
Environment environment) { |
||||||
|
if (serverProperties.isUseForwardHeaders() != null) { |
||||||
|
return serverProperties.isUseForwardHeaders(); |
||||||
|
} |
||||||
|
CloudPlatform platform = CloudPlatform.getActive(environment); |
||||||
|
return platform != null && platform.isUsingForwardHeaders(); |
||||||
|
} |
||||||
|
|
||||||
|
private static void customizeConnectionTimeout( |
||||||
|
ConfigurableJettyWebServerFactory factory, Duration connectionTimeout) { |
||||||
|
factory.addServerCustomizers((server) -> { |
||||||
|
for (org.eclipse.jetty.server.Connector connector : server |
||||||
|
.getConnectors()) { |
||||||
|
if (connector instanceof AbstractConnector) { |
||||||
|
((AbstractConnector) connector) |
||||||
|
.setIdleTimeout(connectionTimeout.toMillis()); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private static void customizeMaxHttpHeaderSize( |
||||||
|
ConfigurableJettyWebServerFactory factory, int maxHttpHeaderSize) { |
||||||
|
factory.addServerCustomizers(new JettyServerCustomizer() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void customize(Server server) { |
||||||
|
for (org.eclipse.jetty.server.Connector connector : server |
||||||
|
.getConnectors()) { |
||||||
|
for (ConnectionFactory connectionFactory : connector |
||||||
|
.getConnectionFactories()) { |
||||||
|
if (connectionFactory instanceof HttpConfiguration.ConnectionFactory) { |
||||||
|
customize( |
||||||
|
(HttpConfiguration.ConnectionFactory) connectionFactory); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void customize(HttpConfiguration.ConnectionFactory factory) { |
||||||
|
HttpConfiguration configuration = factory.getHttpConfiguration(); |
||||||
|
configuration.setRequestHeaderSize(maxHttpHeaderSize); |
||||||
|
configuration.setResponseHeaderSize(maxHttpHeaderSize); |
||||||
|
} |
||||||
|
|
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private static void customizeMaxHttpPostSize(ConfigurableJettyWebServerFactory factory, |
||||||
|
int maxHttpPostSize) { |
||||||
|
factory.addServerCustomizers(new JettyServerCustomizer() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void customize(Server server) { |
||||||
|
setHandlerMaxHttpPostSize(maxHttpPostSize, server.getHandlers()); |
||||||
|
} |
||||||
|
|
||||||
|
private void setHandlerMaxHttpPostSize(int maxHttpPostSize, |
||||||
|
Handler... handlers) { |
||||||
|
for (Handler handler : handlers) { |
||||||
|
if (handler instanceof ContextHandler) { |
||||||
|
((ContextHandler) handler) |
||||||
|
.setMaxFormContentSize(maxHttpPostSize); |
||||||
|
} |
||||||
|
else if (handler instanceof HandlerWrapper) { |
||||||
|
setHandlerMaxHttpPostSize(maxHttpPostSize, |
||||||
|
((HandlerWrapper) handler).getHandler()); |
||||||
|
} |
||||||
|
else if (handler instanceof HandlerCollection) { |
||||||
|
setHandlerMaxHttpPostSize(maxHttpPostSize, |
||||||
|
((HandlerCollection) handler).getHandlers()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private static void customizeAccessLog(ConfigurableJettyWebServerFactory factory, |
||||||
|
ServerProperties.Jetty.Accesslog properties) { |
||||||
|
factory.addServerCustomizers((server) -> { |
||||||
|
NCSARequestLog log = new NCSARequestLog(); |
||||||
|
if (properties.getFilename() != null) { |
||||||
|
log.setFilename(properties.getFilename()); |
||||||
|
} |
||||||
|
if (properties.getFileDateFormat() != null) { |
||||||
|
log.setFilenameDateFormat(properties.getFileDateFormat()); |
||||||
|
} |
||||||
|
log.setRetainDays(properties.getRetentionPeriod()); |
||||||
|
log.setAppend(properties.isAppend()); |
||||||
|
log.setExtended(properties.isExtendedFormat()); |
||||||
|
if (properties.getDateFormat() != null) { |
||||||
|
log.setLogDateFormat(properties.getDateFormat()); |
||||||
|
} |
||||||
|
if (properties.getLocale() != null) { |
||||||
|
log.setLogLocale(properties.getLocale()); |
||||||
|
} |
||||||
|
if (properties.getTimeZone() != null) { |
||||||
|
log.setLogTimeZone(properties.getTimeZone().getID()); |
||||||
|
} |
||||||
|
log.setLogCookies(properties.isLogCookies()); |
||||||
|
log.setLogServer(properties.isLogServer()); |
||||||
|
log.setLogLatency(properties.isLogLatency()); |
||||||
|
server.setRequestLog(log); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2012-2018 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* Configuration for embedded reactive and servlet Jetty web servers. |
||||||
|
* |
||||||
|
* @see org.springframework.boot.web.embedded.jetty.ConfigurableJettyWebServerFactory |
||||||
|
*/ |
||||||
|
package org.springframework.boot.autoconfigure.web.embedded.jetty; |
||||||
@ -0,0 +1,56 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2012-2018 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.springframework.boot.web.embedded.jetty; |
||||||
|
|
||||||
|
import org.eclipse.jetty.server.Server; |
||||||
|
|
||||||
|
/** |
||||||
|
* Web Server Factory configuration for Jetty-specific features. |
||||||
|
* |
||||||
|
* @author Brian Clozel |
||||||
|
* @since 2.0.0 |
||||||
|
* @see JettyServletWebServerFactory |
||||||
|
* @see JettyReactiveWebServerFactory |
||||||
|
*/ |
||||||
|
public interface ConfigurableJettyWebServerFactory { |
||||||
|
|
||||||
|
/** |
||||||
|
* Set the number of acceptor threads to use. |
||||||
|
* @param acceptors the number of acceptor threads to use |
||||||
|
*/ |
||||||
|
void setAcceptors(int acceptors); |
||||||
|
|
||||||
|
/** |
||||||
|
* Set the number of selector threads to use. |
||||||
|
* @param selectors the number of selector threads to use |
||||||
|
*/ |
||||||
|
void setSelectors(int selectors); |
||||||
|
|
||||||
|
/** |
||||||
|
* Set if x-forward-* headers should be processed. |
||||||
|
* @param useForwardHeaders if x-forward headers should be used |
||||||
|
*/ |
||||||
|
void setUseForwardHeaders(boolean useForwardHeaders); |
||||||
|
|
||||||
|
/** |
||||||
|
* Add {@link JettyServerCustomizer}s that will be applied to the {@link Server} |
||||||
|
* before it is started. |
||||||
|
* @param customizers the customizers to add |
||||||
|
*/ |
||||||
|
void addServerCustomizers(JettyServerCustomizer... customizers); |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,45 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2012-2018 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.springframework.boot.web.embedded.jetty; |
||||||
|
|
||||||
|
import org.eclipse.jetty.server.ConnectionFactory; |
||||||
|
import org.eclipse.jetty.server.Connector; |
||||||
|
import org.eclipse.jetty.server.ForwardedRequestCustomizer; |
||||||
|
import org.eclipse.jetty.server.HttpConfiguration; |
||||||
|
import org.eclipse.jetty.server.Server; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link JettyServerCustomizer} to add {@link ForwardedRequestCustomizer}. |
||||||
|
* @author Phillip Webb |
||||||
|
*/ |
||||||
|
class ForwardHeadersCustomizer implements JettyServerCustomizer { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void customize(Server server) { |
||||||
|
ForwardedRequestCustomizer customizer = new ForwardedRequestCustomizer(); |
||||||
|
for (Connector connector : server.getConnectors()) { |
||||||
|
for (ConnectionFactory connectionFactory : connector |
||||||
|
.getConnectionFactories()) { |
||||||
|
if (connectionFactory instanceof HttpConfiguration.ConnectionFactory) { |
||||||
|
((HttpConfiguration.ConnectionFactory) connectionFactory) |
||||||
|
.getHttpConfiguration().addCustomizer(customizer); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue