From c3559d494b19fb28d745889b0f4e0aaeb6f0c824 Mon Sep 17 00:00:00 2001
From: Simone Bordet <simone.bordet@gmail.com>
Date: Mon, 11 Aug 2025 19:20:40 +0200
Subject: HTTP2Session cleanups.

Various cleanups.
Updated mismatch in parameter configuration between code and XML files.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
---
 .../org/eclipse/jetty/http2/HTTP2Session.java | 35 +++++++++++++++----
 .../jetty/http2/parser/BodyParser.java        |  4 +--
 .../jetty/http2/parser/HeaderParser.java      |  5 +++
 .../eclipse/jetty/http2/parser/Parser.java    |  5 +++
 .../http2/parser/WindowUpdateBodyParser.java  |  7 ++--
 .../src/main/config/etc/jetty-http2.xml       |  2 +-
 .../src/main/config/etc/jetty-http2c.xml      |  2 +-
 .../src/main/config/modules/http2.mod         |  2 +-
 .../src/main/config/modules/http2c.mod        |  2 +-
 9 files changed, 48 insertions(+), 16 deletions(-)

diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
index 07281e28ec5..bcef69bbdf2 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
@@ -548,8 +548,17 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements Session
             }
             else
             {
-                if (!isStreamClosed(streamId))
+                if (isStreamClosed(streamId))
+                {
+                    // SPEC: this case must not be treated as an error.
+                    // However, we want to rate control it.
+                    if (!rateControlOnEvent(frame))
+                        onConnectionFailure(ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_window_update_frame_rate");
+                }
+                else
+                {
                     onConnectionFailure(ErrorCode.PROTOCOL_ERROR.code, "unexpected_window_update_frame");
+                }
             }
         }
         else
@@ -726,14 +735,26 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements Session
 
     void reset(HTTP2Stream stream, ResetFrame frame, Callback callback)
     {
-        control(stream, Callback.from(() ->
+        if (rateControlOnEvent(frame))
         {
-            if (stream != null)
+            control(stream, Callback.from(() ->
             {
-                stream.close();
-                removeStream(stream);
-            }
-        }, callback), frame);
+                if (stream != null)
+                {
+                    stream.close();
+                    removeStream(stream);
+                }
+            }, callback), frame);
+        }
+        else
+        {
+            onConnectionFailure(ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_rst_stream_frame_rate");
+        }
+    }
+
+    private boolean rateControlOnEvent(Object event)
+    {
+        return getParser().rateControlOnEvent(event);
     }
 
     /**
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/BodyParser.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/BodyParser.java
index 02da72d8484..cab182a455a 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/BodyParser.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/BodyParser.java
@@ -226,7 +226,7 @@ public abstract class BodyParser
     protected boolean streamFailure(int streamId, int error, String reason)
     {
         notifyStreamFailure(streamId, error, reason);
-        return false;
+        return true;
     }
 
     private void notifyStreamFailure(int streamId, int error, String reason)
@@ -243,6 +243,6 @@ public abstract class BodyParser
 
     protected boolean rateControlOnEvent(Object o)
     {
-        return headerParser.getRateControl().onEvent(o);
+        return headerParser.rateControlOnEvent(o);
     }
 }
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderParser.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderParser.java
index 273afdd8d7a..0ebe562e45e 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderParser.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderParser.java
@@ -45,6 +45,11 @@ public class HeaderParser
         return rateControl;
     }
 
+    boolean rateControlOnEvent(Object event)
+    {
+        return getRateControl().onEvent(event);
+    }
+
     protected void reset()
     {
         state = State.LENGTH;
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java
index 74dc1d0f427..edddeb061f1 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java
@@ -90,6 +90,11 @@ public class Parser
         bodyParsers[FrameType.CONTINUATION.getType()] = new ContinuationBodyParser(headerParser, listener, headerBlockParser, headerBlockFragments);
     }
 
+    public boolean rateControlOnEvent(Object event)
+    {
+        return headerParser.rateControlOnEvent(event);
+    }
+
     protected Listener getListener()
     {
         return listener;
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/WindowUpdateBodyParser.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/WindowUpdateBodyParser.java
index 8a64cbac0d1..509263e27c1 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/WindowUpdateBodyParser.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/WindowUpdateBodyParser.java
@@ -89,15 +89,16 @@ public class WindowUpdateBodyParser extends BodyParser
     private boolean onWindowUpdate(ByteBuffer buffer, int windowDelta)
     {
         int streamId = getStreamId();
+        WindowUpdateFrame frame = new WindowUpdateFrame(streamId, windowDelta);
+        reset();
         if (windowDelta == 0)
         {
             if (streamId == 0)
                 return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_window_update_frame");
-            else
+            if (rateControlOnEvent(frame))
                 return streamFailure(streamId, ErrorCode.PROTOCOL_ERROR.code, "invalid_window_update_frame");
+            return connectionFailure(buffer, ErrorCode.ENHANCE_YOUR_CALM_ERROR.code, "invalid_window_update_frame_rate");
         }
-        WindowUpdateFrame frame = new WindowUpdateFrame(streamId, windowDelta);
-        reset();
         notifyWindowUpdate(frame);
         return true;
     }
diff --git a/jetty-core/jetty-http2/jetty-http2-server/src/main/config/etc/jetty-http2.xml b/jetty-core/jetty-http2/jetty-http2-server/src/main/config/etc/jetty-http2.xml
index a185f7fadca..cafea3dad89 100644
--- a/jetty-core/jetty-http2/jetty-http2-server/src/main/config/etc/jetty-http2.xml
+++ b/jetty-core/jetty-http2/jetty-http2-server/src/main/config/etc/jetty-http2.xml
@@ -12,7 +12,7 @@
         <Set name="maxSettingsKeys"><Property name="jetty.http2.maxSettingsKeys" default="64"/></Set>
         <Set name="rateControlFactory">
           <New class="org.eclipse.jetty.http2.WindowRateControl$Factory">
-            <Arg type="int"><Property name="jetty.http2.rateControl.maxEventsPerSecond" default="50"/></Arg>
+            <Arg type="int"><Property name="jetty.http2.rateControl.maxEventsPerSecond" default="128"/></Arg>
           </New>
         </Set>
       </New>
diff --git a/jetty-core/jetty-http2/jetty-http2-server/src/main/config/etc/jetty-http2c.xml b/jetty-core/jetty-http2/jetty-http2-server/src/main/config/etc/jetty-http2c.xml
index 71020ac9c88..cf52d701c9d 100644
--- a/jetty-core/jetty-http2/jetty-http2-server/src/main/config/etc/jetty-http2c.xml
+++ b/jetty-core/jetty-http2/jetty-http2-server/src/main/config/etc/jetty-http2c.xml
@@ -12,7 +12,7 @@
         <Set name="maxSettingsKeys" property="jetty.http2c.maxSettingsKeys"/>
         <Set name="rateControlFactory">
           <New class="org.eclipse.jetty.http2.WindowRateControl$Factory">
-            <Arg type="int"><Property name="jetty.http2c.rateControl.maxEventsPerSecond" default="50"/></Arg>
+            <Arg type="int"><Property name="jetty.http2c.rateControl.maxEventsPerSecond" default="128"/></Arg>
           </New>
         </Set>
       </New>
diff --git a/jetty-core/jetty-http2/jetty-http2-server/src/main/config/modules/http2.mod b/jetty-core/jetty-http2/jetty-http2-server/src/main/config/modules/http2.mod
index 34081544e88..f0ede3ca8b3 100644
--- a/jetty-core/jetty-http2/jetty-http2-server/src/main/config/modules/http2.mod
+++ b/jetty-core/jetty-http2/jetty-http2-server/src/main/config/modules/http2.mod
@@ -35,5 +35,5 @@ etc/jetty-http2.xml
 
 ## Specifies the maximum number of bad frames and pings per second,
 ## after which a session is closed to avoid denial of service attacks.
-# jetty.http2.rateControl.maxEventsPerSecond=50
+# jetty.http2.rateControl.maxEventsPerSecond=128
 # end::documentation[]
diff --git a/jetty-core/jetty-http2/jetty-http2-server/src/main/config/modules/http2c.mod b/jetty-core/jetty-http2/jetty-http2-server/src/main/config/modules/http2c.mod
index 573d4158a50..20d3ea4af31 100644
--- a/jetty-core/jetty-http2/jetty-http2-server/src/main/config/modules/http2c.mod
+++ b/jetty-core/jetty-http2/jetty-http2-server/src/main/config/modules/http2c.mod
@@ -33,5 +33,5 @@ etc/jetty-http2c.xml
 
 ## Specifies the maximum number of bad frames and pings per second,
 ## after which a session is closed to avoid denial of service attacks.
-# jetty.http2c.rateControl.maxEventsPerSecond=50
+# jetty.http2c.rateControl.maxEventsPerSecond=128
 # end::documentation[]
-- 
2.30.2

