Skip to content

Commit

Permalink
Fixed DataBufferLimitException in WebFlux result in 413 instead of 500
Browse files Browse the repository at this point in the history
  • Loading branch information
mysend12 committed Apr 1, 2024
1 parent d360def commit 3ca0ba9
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2002-2024 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 org.springframework.web.server;


import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;

/**
* Exception for errors that fit response status 413 (payload too large) for use in
* Spring Web applications.
*
* @author Kim Bosung
* @since 6.2
*/
@SuppressWarnings("serial")
public class ServerWebInputTooLargeException extends ResponseStatusException {

public ServerWebInputTooLargeException(@Nullable Throwable cause) {
super(HttpStatus.PAYLOAD_TOO_LARGE, null, cause);
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
Expand Down Expand Up @@ -34,6 +34,7 @@
import org.springframework.core.codec.DecodingException;
import org.springframework.core.codec.Hints;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferLimitException;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
Expand All @@ -54,6 +55,7 @@
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.ServerWebInputTooLargeException;
import org.springframework.web.server.UnsupportedMediaTypeStatusException;

/**
Expand All @@ -64,6 +66,7 @@
* {@linkplain org.springframework.validation.annotation.ValidationAnnotationUtils#determineValidationHints
* annotations that trigger validation}. Validation failure results in a
* {@link ServerWebInputException}.
* {@link ServerWebInputTooLargeException}.
*
* @author Rossen Stoyanchev
* @author Sebastien Deleuze
Expand Down Expand Up @@ -233,8 +236,15 @@ protected Mono<Object> readBody(MethodParameter bodyParam, @Nullable MethodParam
}

private Throwable handleReadError(MethodParameter parameter, Throwable ex) {
return (ex instanceof DecodingException ?
new ServerWebInputException("Failed to read HTTP message", parameter, ex) : ex);
if (ex instanceof DataBufferLimitException) {
return new ServerWebInputTooLargeException(ex);
}

if (ex instanceof DecodingException) {
return new ServerWebInputException("Failed to read HTTP message", parameter, ex);
}

return ex;
}

private ServerWebInputException handleMissingBody(MethodParameter parameter) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import org.springframework.web.reactive.BindingContext;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.server.ServerWebInputTooLargeException;
import org.springframework.web.server.UnsupportedMediaTypeStatusException;
import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest;
import org.springframework.web.testfixture.method.ResolvableMethod;
Expand Down Expand Up @@ -112,6 +113,24 @@ public void emptyBody() {
StepVerifier.create(result).expectError(ServerWebInputException.class).verify();
}

@Test @SuppressWarnings("unchecked")
public void tooLargeBody() {
StringBuilder bodyBuilder = new StringBuilder();
while (bodyBuilder.toString().getBytes().length < 256 * 1024) {
bodyBuilder.append("The default maximum input length is 256kb.");
}
String body = "{\"bar\":\"BARBAR\",\"foo\":\"" + bodyBuilder + "\"}";

MockServerHttpRequest request = post("/path").contentType(MediaType.APPLICATION_JSON).body(body);
ServerWebExchange exchange = MockServerWebExchange.from(request);
ResolvableType type = forClassWithGenerics(Mono.class, TestBean.class);
MethodParameter param = this.testMethod.arg(type);
Mono<TestBean> result = (Mono<TestBean>) this.resolver.readBody(
param, true, this.bindingContext, exchange).block();

StepVerifier.create(result).expectError(ServerWebInputTooLargeException.class).verify();
}

@Test
void monoTestBean() {
String body = "{\"bar\":\"BARBAR\",\"foo\":\"FOOFOO\"}";
Expand Down

0 comments on commit 3ca0ba9

Please sign in to comment.