From f9df8c738a4eb9fff292f58a82be7ba09e1c3097 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 20 Mar 2018 17:10:50 -0400 Subject: [PATCH] Avoid inifinite recursion in UndertowServerHttpRequest Undertow does not provide a way to check if data is available to read but instead we have to try to read and see if any data is returned. This makes it impossible to implement checkOnDataAvailable without trying to read and that can lead to infinite recursion like this: ... UndertowServerHttpRequest$RequestBodyPublisher.checkOnDataAvailable(UndertowServerHttpRequest.java:156) AbstractListenerReadPublisher.changeToDemandState(AbstractListenerReadPublisher.java:177) AbstractListenerReadPublisher.access$900(AbstractListenerReadPublisher.java:47) AbstractListenerReadPublisher$State$4.onDataAvailable(AbstractListenerReadPublisher.java:319) AbstractListenerReadPublisher.onDataAvailable(AbstractListenerReadPublisher.java:85) UndertowServerHttpRequest$RequestBodyPublisher.checkOnDataAvailable(UndertowServerHttpRequest.java:156) This commit prevent the call to checkOnDataAvailable() when switching states from READING->DEMAND which implies we exited the readAndPublish loop because there was no more data to read. Issue: SPR-16545 --- .../server/reactive/AbstractListenerReadPublisher.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) 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 0389e4cf72..e83dc84cfc 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -174,7 +174,12 @@ public abstract class AbstractListenerReadPublisher implements Publisher { private void changeToDemandState(State oldState) { if (changeState(oldState, State.DEMAND)) { - checkOnDataAvailable(); + // Protect from infinite recursion in Undertow, where we can't check if data + // is available, so all we can do is to try to read. + // Generally, no need to check if we just came out of readAndPublish()... + if (!oldState.equals(State.READING)) { + checkOnDataAvailable(); + } } }