@@ -65,6 +65,7 @@ public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
6565 public void channelRead (ChannelHandlerContext ctx , Object msg ) {
6666 if (isHttpRequest (msg )) {
6767 this .read = true ;
68+ this .chunkSize = 0 ;
6869 var req = (HttpRequest ) msg ;
6970 var path = pathOnly (req .uri ());
7071 var app = contextSelector .select (path );
@@ -140,8 +141,14 @@ public void writeChunks(Object header, Object body, Object last, ChannelPromise
140141 channelContext .write (header , voidPromise );
141142 // Body
142143 channelContext .write (body , voidPromise );
144+
143145 // Finish
144- channelContext .writeAndFlush (last , promise );
146+ if (this .read ) {
147+ this .flush = true ;
148+ channelContext .write (last , promise ); // Defer flush
149+ } else {
150+ channelContext .writeAndFlush (last , promise ); // Immediate flush
151+ }
145152 } else {
146153 this .channelContext .executor ().execute (() -> writeChunks (header , body , last , promise ));
147154 }
@@ -159,8 +166,14 @@ public void writeChunks(Object header, Object body, ChannelPromise promise) {
159166 if (this .channelContext .executor ().inEventLoop ()) {
160167 // Headers
161168 channelContext .write (header , channelContext .voidPromise ());
169+
162170 // Body + Last
163- channelContext .writeAndFlush (body , promise );
171+ if (this .read ) {
172+ this .flush = true ;
173+ channelContext .write (body , promise ); // Defer flush
174+ } else {
175+ channelContext .writeAndFlush (body , promise ); // Immediate flush
176+ }
164177 } else {
165178 this .channelContext .executor ().execute (() -> writeChunks (header , body , promise ));
166179 }
@@ -217,7 +230,13 @@ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
217230 }
218231 }
219232 } finally {
220- ctx .close ();
233+ try {
234+ if (context != null ) {
235+ resetDecoderState (context , true ); // Force decoder cleanup on failure
236+ }
237+ } finally {
238+ ctx .close ();
239+ }
221240 }
222241 }
223242
0 commit comments