Polish "Merge pull request #33553 from michaelweidmann"

See gh-33553
This commit is contained in:
Moritz Halbritter 2023-01-31 11:33:11 +01:00
parent 93d46d11e9
commit 64c2320ce1
12 changed files with 141 additions and 55 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2022 the original author or authors. * Copyright 2012-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -654,7 +654,7 @@ public class ServerProperties {
} }
public DataSize getMaxHttpResponseHeaderSize() { public DataSize getMaxHttpResponseHeaderSize() {
return maxHttpResponseHeaderSize; return this.maxHttpResponseHeaderSize;
} }
public void setMaxHttpResponseHeaderSize(DataSize maxHttpResponseHeaderSize) { public void setMaxHttpResponseHeaderSize(DataSize maxHttpResponseHeaderSize) {
@ -1141,7 +1141,7 @@ public class ServerProperties {
} }
public DataSize getMaxHttpResponseHeaderSize() { public DataSize getMaxHttpResponseHeaderSize() {
return maxHttpResponseHeaderSize; return this.maxHttpResponseHeaderSize;
} }
public void setMaxHttpResponseHeaderSize(DataSize maxHttpResponseHeaderSize) { public void setMaxHttpResponseHeaderSize(DataSize maxHttpResponseHeaderSize) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2022 the original author or authors. * Copyright 2012-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -197,7 +197,13 @@ public class JettyWebServerFactoryCustomizer
return CustomRequestLog.NCSA_FORMAT; return CustomRequestLog.NCSA_FORMAT;
} }
private record MaxHttpRequestHeaderSizeCustomizer(int maxRequestHeaderSize) implements JettyServerCustomizer { private static class MaxHttpRequestHeaderSizeCustomizer implements JettyServerCustomizer {
private final int maxRequestHeaderSize;
MaxHttpRequestHeaderSizeCustomizer(int maxRequestHeaderSize) {
this.maxRequestHeaderSize = maxRequestHeaderSize;
}
@Override @Override
public void customize(Server server) { public void customize(Server server) {
@ -214,9 +220,16 @@ public class JettyWebServerFactoryCustomizer
.setRequestHeaderSize(this.maxRequestHeaderSize); .setRequestHeaderSize(this.maxRequestHeaderSize);
} }
} }
} }
private record MaxHttpResponseHeaderSizeCustomizer(int maxResponseHeaderSize) implements JettyServerCustomizer { private static class MaxHttpResponseHeaderSizeCustomizer implements JettyServerCustomizer {
private final int maxResponseHeaderSize;
MaxHttpResponseHeaderSizeCustomizer(int maxResponseHeaderSize) {
this.maxResponseHeaderSize = maxResponseHeaderSize;
}
@Override @Override
public void customize(Server server) { public void customize(Server server) {
@ -233,6 +246,7 @@ public class JettyWebServerFactoryCustomizer
.setResponseHeaderSize(this.maxResponseHeaderSize); .setResponseHeaderSize(this.maxResponseHeaderSize);
} }
} }
} }
} }

View File

@ -16,6 +16,11 @@
package org.springframework.boot.autoconfigure.web.embedded; package org.springframework.boot.autoconfigure.web.embedded;
import java.time.Duration;
import java.util.List;
import java.util.function.ObjIntConsumer;
import java.util.stream.Collectors;
import org.apache.catalina.Lifecycle; import org.apache.catalina.Lifecycle;
import org.apache.catalina.valves.AccessLogValve; import org.apache.catalina.valves.AccessLogValve;
import org.apache.catalina.valves.ErrorReportValve; import org.apache.catalina.valves.ErrorReportValve;
@ -25,6 +30,7 @@ import org.apache.coyote.ProtocolHandler;
import org.apache.coyote.UpgradeProtocol; import org.apache.coyote.UpgradeProtocol;
import org.apache.coyote.http11.AbstractHttp11Protocol; import org.apache.coyote.http11.AbstractHttp11Protocol;
import org.apache.coyote.http2.Http2Protocol; import org.apache.coyote.http2.Http2Protocol;
import org.springframework.boot.autoconfigure.web.ErrorProperties; import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ErrorProperties.IncludeAttribute; import org.springframework.boot.autoconfigure.web.ErrorProperties.IncludeAttribute;
import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.ServerProperties;
@ -39,11 +45,6 @@ import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.util.unit.DataSize; import org.springframework.util.unit.DataSize;
import java.time.Duration;
import java.util.List;
import java.util.function.ObjIntConsumer;
import java.util.stream.Collectors;
/** /**
* Customization for Tomcat-specific features common for both Servlet and Reactive * Customization for Tomcat-specific features common for both Servlet and Reactive
* servers. * servers.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2022 the original author or authors. * Copyright 2012-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,6 +16,16 @@
package org.springframework.boot.autoconfigure.web.embedded; package org.springframework.boot.autoconfigure.web.embedded;
import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.function.Function;
import org.eclipse.jetty.server.AbstractConnector; import org.eclipse.jetty.server.AbstractConnector;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.CustomRequestLog; import org.eclipse.jetty.server.CustomRequestLog;
@ -29,6 +39,7 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ThreadPool; import org.eclipse.jetty.util.thread.ThreadPool;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties.ForwardHeadersStrategy; import org.springframework.boot.autoconfigure.web.ServerProperties.ForwardHeadersStrategy;
import org.springframework.boot.autoconfigure.web.ServerProperties.Jetty; import org.springframework.boot.autoconfigure.web.ServerProperties.Jetty;
@ -43,17 +54,6 @@ import org.springframework.boot.web.embedded.jetty.JettyWebServer;
import org.springframework.mock.env.MockEnvironment; import org.springframework.mock.env.MockEnvironment;
import org.springframework.test.context.support.TestPropertySourceUtils; import org.springframework.test.context.support.TestPropertySourceUtils;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.util.unit.DataSize;
import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.function.Function;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.then; import static org.mockito.BDDMockito.then;

View File

@ -1,8 +1,25 @@
/*
* Copyright 2012-2023 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
*
* https://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 smoketest.jetty.service; package smoketest.jetty.service;
import smoketest.jetty.util.RandomStringUtil;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import smoketest.jetty.util.RandomStringUtil;
@Component @Component
public class HttpHeaderService { public class HttpHeaderService {
@ -11,7 +28,7 @@ public class HttpHeaderService {
private int maxHttpResponseHeaderSize; private int maxHttpResponseHeaderSize;
/** /**
* generate a random byte array that * Generates random data. The data is:
* <ol> * <ol>
* <li>is longer than configured * <li>is longer than configured
* <code>server.jetty.max-http-response-header-size</code></li> * <code>server.jetty.max-http-response-header-size</code></li>
@ -20,7 +37,7 @@ public class HttpHeaderService {
* @return a base64 encoded string of random bytes * @return a base64 encoded string of random bytes
*/ */
public String getHeaderValue() { public String getHeaderValue() {
return RandomStringUtil.getRandomBase64EncodedString(maxHttpResponseHeaderSize + 1); return RandomStringUtil.getRandomBase64EncodedString(this.maxHttpResponseHeaderSize + 1);
} }
} }

View File

@ -1,9 +1,25 @@
/*
* Copyright 2012-2023 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
*
* https://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 smoketest.jetty.util; package smoketest.jetty.util;
import java.util.Base64; import java.util.Base64;
import java.util.Random; import java.util.Random;
public class RandomStringUtil { public final class RandomStringUtil {
private RandomStringUtil() { private RandomStringUtil() {
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,7 +20,6 @@ import jakarta.servlet.http.HttpServletResponse;
import smoketest.jetty.service.HelloWorldService; import smoketest.jetty.service.HelloWorldService;
import smoketest.jetty.service.HttpHeaderService; import smoketest.jetty.service.HttpHeaderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
@ -28,11 +27,14 @@ import org.springframework.web.bind.annotation.ResponseBody;
@Controller @Controller
public class SampleController { public class SampleController {
@Autowired private final HelloWorldService helloWorldService;
private HelloWorldService helloWorldService;
@Autowired private final HttpHeaderService httpHeaderService;
private HttpHeaderService httpHeaderService;
public SampleController(HelloWorldService helloWorldService, HttpHeaderService httpHeaderService) {
this.helloWorldService = helloWorldService;
this.httpHeaderService = httpHeaderService;
}
@GetMapping("/") @GetMapping("/")
@ResponseBody @ResponseBody
@ -43,7 +45,7 @@ public class SampleController {
@GetMapping("/max-http-response-header") @GetMapping("/max-http-response-header")
@ResponseBody @ResponseBody
public String maxHttpResponseHeader(HttpServletResponse response) { public String maxHttpResponseHeader(HttpServletResponse response) {
String headerValue = httpHeaderService.getHeaderValue(); String headerValue = this.httpHeaderService.getHeaderValue();
response.addHeader("x-max-header", headerValue); response.addHeader("x-max-header", headerValue);
return this.helloWorldService.getHelloMessage(); return this.helloWorldService.getHelloMessage();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,8 +21,9 @@ import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import smoketest.jetty.util.RandomStringUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
@ -36,7 +37,6 @@ import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.util.StreamUtils; import org.springframework.util.StreamUtils;
import smoketest.jetty.util.RandomStringUtil;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -72,6 +72,7 @@ class SampleJettyApplicationTests {
HttpEntity<?> requestEntity = new HttpEntity<>(requestHeaders); HttpEntity<?> requestEntity = new HttpEntity<>(requestHeaders);
ResponseEntity<byte[]> entity = this.restTemplate.exchange("/", HttpMethod.GET, requestEntity, byte[].class); ResponseEntity<byte[]> entity = this.restTemplate.exchange("/", HttpMethod.GET, requestEntity, byte[].class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).isNotNull();
try (GZIPInputStream inflater = new GZIPInputStream(new ByteArrayInputStream(entity.getBody()))) { try (GZIPInputStream inflater = new GZIPInputStream(new ByteArrayInputStream(entity.getBody()))) {
assertThat(StreamUtils.copyToString(inflater, StandardCharsets.UTF_8)).isEqualTo("Hello World"); assertThat(StreamUtils.copyToString(inflater, StandardCharsets.UTF_8)).isEqualTo("Hello World");
} }
@ -87,7 +88,7 @@ class SampleJettyApplicationTests {
@Test @Test
void testMaxHttpRequestHeaderSize() { void testMaxHttpRequestHeaderSize() {
String headerValue = RandomStringUtil.getRandomBase64EncodedString(maxHttpRequestHeaderSize + 1); String headerValue = RandomStringUtil.getRandomBase64EncodedString(this.maxHttpRequestHeaderSize + 1);
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.add("x-max-request-header", headerValue); headers.add("x-max-request-header", headerValue);
HttpEntity<?> httpEntity = new HttpEntity<>(headers); HttpEntity<?> httpEntity = new HttpEntity<>(headers);

View File

@ -1,8 +1,25 @@
/*
* Copyright 2012-2023 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
*
* https://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 smoketest.tomcat.service; package smoketest.tomcat.service;
import smoketest.tomcat.util.RandomStringUtil;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import smoketest.tomcat.util.RandomStringUtil;
@Component @Component
public class HttpHeaderService { public class HttpHeaderService {
@ -11,16 +28,16 @@ public class HttpHeaderService {
private int maxHttpResponseHeaderSize; private int maxHttpResponseHeaderSize;
/** /**
* generate a random byte array that * Generates random data. The data is:
* <ol> * <ol>
* <li>is longer than configured * <li>is longer than configured
* <code>server.jetty.max-http-response-header-size</code></li> * <code>server.tomcat.max-http-response-header-size</code></li>
* <li>is url encoded by base 64 encode the random value</li> * <li>is url encoded by base 64 encode the random value</li>
* </ol> * </ol>
* @return a base64 encoded string of random bytes * @return a base64 encoded string of random bytes
*/ */
public String getHeaderValue() { public String getHeaderValue() {
return RandomStringUtil.getRandomBase64EncodedString(maxHttpResponseHeaderSize + 1); return RandomStringUtil.getRandomBase64EncodedString(this.maxHttpResponseHeaderSize + 1);
} }
} }

View File

@ -1,9 +1,25 @@
/*
* Copyright 2012-2023 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
*
* https://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 smoketest.tomcat.util; package smoketest.tomcat.util;
import java.util.Base64; import java.util.Base64;
import java.util.Random; import java.util.Random;
public class RandomStringUtil { public final class RandomStringUtil {
private RandomStringUtil() { private RandomStringUtil() {
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,21 +18,23 @@ package smoketest.tomcat.web;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import smoketest.tomcat.service.HelloWorldService; import smoketest.tomcat.service.HelloWorldService;
import smoketest.tomcat.service.HttpHeaderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import smoketest.tomcat.service.HttpHeaderService;
@Controller @Controller
public class SampleController { public class SampleController {
@Autowired private final HelloWorldService helloWorldService;
private HelloWorldService helloWorldService;
@Autowired private final HttpHeaderService httpHeaderService;
private HttpHeaderService httpHeaderService;
public SampleController(HelloWorldService helloWorldService, HttpHeaderService httpHeaderService) {
this.helloWorldService = helloWorldService;
this.httpHeaderService = httpHeaderService;
}
@GetMapping("/") @GetMapping("/")
@ResponseBody @ResponseBody
@ -43,7 +45,7 @@ public class SampleController {
@GetMapping("/max-http-response-header") @GetMapping("/max-http-response-header")
@ResponseBody @ResponseBody
public String maxHttpResponseHeader(HttpServletResponse response) { public String maxHttpResponseHeader(HttpServletResponse response) {
String headerValue = httpHeaderService.getHeaderValue(); String headerValue = this.httpHeaderService.getHeaderValue();
response.addHeader("x-max-header", headerValue); response.addHeader("x-max-header", headerValue);
return this.helloWorldService.getHelloMessage(); return this.helloWorldService.getHelloMessage();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,8 +23,9 @@ import java.util.zip.GZIPInputStream;
import org.apache.coyote.AbstractProtocol; import org.apache.coyote.AbstractProtocol;
import org.apache.coyote.ProtocolHandler; import org.apache.coyote.ProtocolHandler;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import smoketest.tomcat.util.RandomStringUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
@ -41,7 +42,6 @@ import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.util.StreamUtils; import org.springframework.util.StreamUtils;
import smoketest.tomcat.util.RandomStringUtil;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -104,7 +104,7 @@ class SampleTomcatApplicationTests {
@Test @Test
void testMaxHttpRequestHeaderSize(CapturedOutput output) { void testMaxHttpRequestHeaderSize(CapturedOutput output) {
String headerValue = RandomStringUtil.getRandomBase64EncodedString(maxHttpRequestHeaderSize + 1); String headerValue = RandomStringUtil.getRandomBase64EncodedString(this.maxHttpRequestHeaderSize + 1);
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.add("x-max-request-header", headerValue); headers.add("x-max-request-header", headerValue);
HttpEntity<?> httpEntity = new HttpEntity<>(headers); HttpEntity<?> httpEntity = new HttpEntity<>(headers);