Browse Source

Fix MockHttpServletRequest InputStream for empty body

Prior to this commit, a recent change applied in gh-29125 changed the
behavior of `MockHttpServletRequest` instances. In case of an empty
request body, the returned `InputStream` would be static and could not
be reused across requests.
This could result in `java.io.IOException: Stream closed` exceptions if
a previous request was read.

This commit ensures that a new instance of an empty stream is returned
for each request instance.

Fixes gh-29901
pull/29918/head
Brian Clozel 2 years ago
parent
commit
5fd73f0bae
  1. 9
      spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java
  2. 11
      spring-test/src/test/java/org/springframework/mock/web/MockHttpServletRequestTests.java

9
spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-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.
@ -101,9 +101,6 @@ public class MockHttpServletRequest implements HttpServletRequest { @@ -101,9 +101,6 @@ public class MockHttpServletRequest implements HttpServletRequest {
private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
private static final ServletInputStream EMPTY_SERVLET_INPUT_STREAM =
new DelegatingServletInputStream(InputStream.nullInputStream());
private static final BufferedReader EMPTY_BUFFERED_READER =
new BufferedReader(new StringReader(""));
@ -513,12 +510,12 @@ public class MockHttpServletRequest implements HttpServletRequest { @@ -513,12 +510,12 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
else if (this.reader != null) {
throw new IllegalStateException(
"Cannot call getInputStream() after getReader() has already been called for the current request") ;
"Cannot call getInputStream() after getReader() has already been called for the current request");
}
this.inputStream = (this.content != null ?
new DelegatingServletInputStream(new ByteArrayInputStream(this.content)) :
EMPTY_SERVLET_INPUT_STREAM);
new DelegatingServletInputStream(InputStream.nullInputStream()));
return this.inputStream;
}

11
spring-test/src/test/java/org/springframework/mock/web/MockHttpServletRequestTests.java

@ -82,6 +82,17 @@ class MockHttpServletRequestTests { @@ -82,6 +82,17 @@ class MockHttpServletRequestTests {
assertThat(StreamUtils.copyToString(request.getInputStream(), Charset.defaultCharset())).isEqualTo("body");
}
@Test
void readEmptyInputStreamWorksAcrossRequests() throws IOException {
MockHttpServletRequest firstRequest = new MockHttpServletRequest();
firstRequest.getInputStream().readAllBytes();
firstRequest.getInputStream().close();
MockHttpServletRequest secondRequest = new MockHttpServletRequest();
secondRequest.getInputStream().readAllBytes();
secondRequest.getInputStream().close();
}
@Test
void setContentAndGetReader() throws IOException {
byte[] bytes = "body".getBytes(Charset.defaultCharset());

Loading…
Cancel
Save