diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerReadPublisher.java b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerReadPublisher.java index 513eb7810d..6398e71f89 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerReadPublisher.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerReadPublisher.java @@ -113,6 +113,12 @@ public abstract class AbstractListenerReadPublisher implements Publisher { @Nullable protected abstract T read() throws IOException; + /** + * Suspend reading. Defaults to no-op. + */ + protected void suspendReading() { + } + /** * Read and publish data from the input. Continue till there is no more @@ -256,6 +262,7 @@ public abstract class AbstractListenerReadPublisher implements Publisher { } else { publisher.changeState(READING, NO_DEMAND); + publisher.suspendReading(); } } catch (IOException ex) { diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java index 586e3c8453..b14d467ea6 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java @@ -152,7 +152,28 @@ class UndertowServerHttpRequest extends AbstractServerHttpRequest { protected void checkOnDataAvailable() { // TODO: The onDataAvailable() call below can cause a StackOverflowError // since this method is being called from onDataAvailable() itself. - onDataAvailable(); + if (isReadPossible()) { + onDataAvailable(); + } + } + + private boolean isReadPossible() { + if (!this.channel.isReadResumed()) { + this.channel.resumeReads(); + } + return this.channel.isReadResumed(); + } + + @Override + protected void suspendReading() { + this.channel.suspendReads(); + } + + @Override + public void onAllDataRead() { + this.channel.getReadSetter().set(null); + this.channel.resumeReads(); + super.onAllDataRead(); } @Override diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java index 17b0cd703e..26384224d7 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java @@ -152,12 +152,10 @@ class UndertowServerHttpResponse extends AbstractListenerServerHttpResponse impl if (this.responseChannel == null) { this.responseChannel = this.exchange.getResponseChannel(); } - if (this.responseChannel.isWriteResumed()) { - return true; - } else { + if (!this.responseChannel.isWriteResumed()) { this.responseChannel.resumeWrites(); - return false; } + return this.responseChannel.isWriteResumed(); }