Skip to content

Commit 0b57b6c

Browse files
committed
Fixed spring-projects#32113 DataBufferLimitException in WebFlux result in 413 instead of 500
1 parent d360def commit 0b57b6c

File tree

3 files changed

+69
-3
lines changed

3 files changed

+69
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2002-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.web.server;
18+
19+
20+
import org.springframework.http.HttpStatus;
21+
import org.springframework.lang.Nullable;
22+
23+
/**
24+
* Exception for errors that fit response status 413 (payload too large) for use in
25+
* Spring Web applications.
26+
*
27+
* @author Kim Bosung
28+
* @since 6.2
29+
*/
30+
@SuppressWarnings("serial")
31+
public class ServerWebInputTooLargeException extends ResponseStatusException {
32+
33+
public ServerWebInputTooLargeException(@Nullable Throwable cause) {
34+
super(HttpStatus.PAYLOAD_TOO_LARGE, null, cause);
35+
}
36+
37+
}

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@
3434
import org.springframework.core.codec.DecodingException;
3535
import org.springframework.core.codec.Hints;
3636
import org.springframework.core.io.buffer.DataBuffer;
37+
import org.springframework.core.io.buffer.DataBufferLimitException;
3738
import org.springframework.core.io.buffer.DataBufferUtils;
3839
import org.springframework.http.HttpHeaders;
3940
import org.springframework.http.HttpMethod;
@@ -54,6 +55,7 @@
5455
import org.springframework.web.server.ResponseStatusException;
5556
import org.springframework.web.server.ServerWebExchange;
5657
import org.springframework.web.server.ServerWebInputException;
58+
import org.springframework.web.server.ServerWebInputTooLargeException;
5759
import org.springframework.web.server.UnsupportedMediaTypeStatusException;
5860

5961
/**
@@ -64,6 +66,7 @@
6466
* {@linkplain org.springframework.validation.annotation.ValidationAnnotationUtils#determineValidationHints
6567
* annotations that trigger validation}. Validation failure results in a
6668
* {@link ServerWebInputException}.
69+
* {@link ServerWebInputTooLargeException}.
6770
*
6871
* @author Rossen Stoyanchev
6972
* @author Sebastien Deleuze
@@ -233,8 +236,15 @@ protected Mono<Object> readBody(MethodParameter bodyParam, @Nullable MethodParam
233236
}
234237

235238
private Throwable handleReadError(MethodParameter parameter, Throwable ex) {
236-
return (ex instanceof DecodingException ?
237-
new ServerWebInputException("Failed to read HTTP message", parameter, ex) : ex);
239+
if (ex instanceof DataBufferLimitException) {
240+
return new ServerWebInputTooLargeException(ex);
241+
}
242+
243+
if (ex instanceof DecodingException) {
244+
return new ServerWebInputException("Failed to read HTTP message", parameter, ex);
245+
}
246+
247+
return ex;
238248
}
239249

240250
private ServerWebInputException handleMissingBody(MethodParameter parameter) {

spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageReaderArgumentResolverTests.java

+19
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import org.springframework.web.reactive.BindingContext;
5555
import org.springframework.web.server.ServerWebExchange;
5656
import org.springframework.web.server.ServerWebInputException;
57+
import org.springframework.web.server.ServerWebInputTooLargeException;
5758
import org.springframework.web.server.UnsupportedMediaTypeStatusException;
5859
import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest;
5960
import org.springframework.web.testfixture.method.ResolvableMethod;
@@ -112,6 +113,24 @@ public void emptyBody() {
112113
StepVerifier.create(result).expectError(ServerWebInputException.class).verify();
113114
}
114115

116+
@Test @SuppressWarnings("unchecked")
117+
public void tooLargeBody() {
118+
StringBuilder bodyBuilder = new StringBuilder();
119+
while (bodyBuilder.toString().getBytes().length < 256 * 1024) {
120+
bodyBuilder.append("The default maximum input length is 256kb.");
121+
}
122+
String body = "{\"bar\":\"BARBAR\",\"foo\":\"" + bodyBuilder + "\"}";
123+
124+
MockServerHttpRequest request = post("/path").contentType(MediaType.APPLICATION_JSON).body(body);
125+
ServerWebExchange exchange = MockServerWebExchange.from(request);
126+
ResolvableType type = forClassWithGenerics(Mono.class, TestBean.class);
127+
MethodParameter param = this.testMethod.arg(type);
128+
Mono<TestBean> result = (Mono<TestBean>) this.resolver.readBody(
129+
param, true, this.bindingContext, exchange).block();
130+
131+
StepVerifier.create(result).expectError(ServerWebInputTooLargeException.class).verify();
132+
}
133+
115134
@Test
116135
void monoTestBean() {
117136
String body = "{\"bar\":\"BARBAR\",\"foo\":\"FOOFOO\"}";

0 commit comments

Comments
 (0)