You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2022/01/14 22:00:53 UTC

[tomcat] branch 8.5.x updated (f754ff3 -> 6c71b4f)

This is an automated email from the ASF dual-hosted git repository.

markt pushed a change to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git.


    from f754ff3  Extend default timeout as buildbot tests are occasionally timing out
     new 70a9a31  Don't include a cookie header in push request when there are no cookies
     new f5459e6  Refactor the handling of push promise frames for benefit of sub-classes
     new 6bfd0f7  Back-port creation of dedicated test parser
     new dc4bb27  Add support to HTTP/2 test parser for push promise frames.
     new 368399e  Add a simple test for server push
     new 6c71b4f  Fix server push. Validation will see pseudo headers so should allow them

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../catalina/core/ApplicationPushBuilder.java      |  10 +-
 java/org/apache/coyote/http2/Http2Parser.java      |  21 +++-
 java/org/apache/coyote/http2/StreamProcessor.java  |  19 ++-
 test/org/apache/coyote/http2/Http2TestBase.java    |  24 +++-
 .../apache/coyote/http2/TestHttp2Section_6_6.java  | 129 +++++++++++++++++++++
 .../org/apache/coyote/http2/TesterHttp2Parser.java |  76 ++++++++++++
 webapps/docs/changelog.xml                         |   8 ++
 7 files changed, 274 insertions(+), 13 deletions(-)
 create mode 100644 test/org/apache/coyote/http2/TestHttp2Section_6_6.java
 create mode 100644 test/org/apache/coyote/http2/TesterHttp2Parser.java

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[tomcat] 02/06: Refactor the handling of push promise frames for benefit of sub-classes

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit f5459e6bd0f8d991193d85589ef9c2b72992772a
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Jan 14 19:22:41 2022 +0000

    Refactor the handling of push promise frames for benefit of sub-classes
    
    To correctly handle a push-promise frame, sub-classes need access to the
    flags and payload size from the frame header.
---
 java/org/apache/coyote/http2/Http2Parser.java | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/coyote/http2/Http2Parser.java b/java/org/apache/coyote/http2/Http2Parser.java
index f4298d7..8fc7385 100644
--- a/java/org/apache/coyote/http2/Http2Parser.java
+++ b/java/org/apache/coyote/http2/Http2Parser.java
@@ -107,7 +107,7 @@ class Http2Parser {
             readSettingsFrame(flags, payloadSize);
             break;
         case PUSH_PROMISE:
-            readPushPromiseFrame(streamId);
+            readPushPromiseFrame(streamId, flags, payloadSize);
             break;
         case PING:
             readPingFrame(flags);
@@ -316,7 +316,20 @@ class Http2Parser {
     }
 
 
-    private void readPushPromiseFrame(int streamId) throws Http2Exception {
+    /**
+     * This default server side implementation always throws an exception. If
+     * re-used for client side parsing, this method should be overridden with an
+     * appropriate implementation.
+     *
+     * @param streamId      The pushed stream
+     * @param flags         The flags set in the frame header
+     * @param payloadSize   The size of the payload in bytes
+     *
+     * @throws Http2Exception Always
+     * @throws IOException May be thrown by sub-classes that parse this frame
+     */
+    protected void readPushPromiseFrame(int streamId, int flags, int payloadSize)
+            throws Http2Exception, IOException {
         throw new ConnectionException(sm.getString("http2Parser.processFramePushPromise",
                 connectionId, Integer.valueOf(streamId)), Http2Error.PROTOCOL_ERROR);
     }

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[tomcat] 05/06: Add a simple test for server push

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 368399e6048ff6af79d00c910cd4ce4a351bdd15
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Jan 14 19:24:58 2022 +0000

    Add a simple test for server push
---
 .../apache/coyote/http2/TestHttp2Section_6_6.java  | 129 +++++++++++++++++++++
 1 file changed, 129 insertions(+)

diff --git a/test/org/apache/coyote/http2/TestHttp2Section_6_6.java b/test/org/apache/coyote/http2/TestHttp2Section_6_6.java
new file mode 100644
index 0000000..6106cf5
--- /dev/null
+++ b/test/org/apache/coyote/http2/TestHttp2Section_6_6.java
@@ -0,0 +1,129 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.coyote.http2;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.connector.RequestFacade;
+import org.apache.catalina.core.ApplicationPushBuilder;
+import org.apache.catalina.startup.Tomcat;
+
+/**
+ * Unit tests for Section 6.5 of
+ * <a href="https://tools.ietf.org/html/rfc7540">RFC 7540</a>.
+ */
+public class TestHttp2Section_6_6  extends Http2TestBase {
+
+
+    @Test
+    public void testPushPromise() throws Exception {
+        http2Connect();
+
+        // Build the push request
+        byte[] frameHeader = new byte[9];
+        ByteBuffer headersPayload = ByteBuffer.allocate(128);
+
+        List<Header> headers = new ArrayList<>(4);
+        headers.add(new Header(":method", "GET"));
+        headers.add(new Header(":scheme", "http"));
+        headers.add(new Header(":path", "/push"));
+        headers.add(new Header(":authority", "localhost:" + getPort()));
+
+        buildGetRequest(frameHeader, headersPayload, null, headers, 3);
+
+        // Send the request
+        writeFrame(frameHeader, headersPayload);
+
+        // Read the response
+        // push promise
+        parser.readFrame(true);
+        // stream 3 response headers
+        parser.readFrame(true);
+        // stream 3 response body
+        parser.readFrame(true);
+        // stream 2 response headers
+        parser.readFrame(true);
+        // stream 2 response body
+        parser.readFrame(true);
+
+        String trace = output.getTrace();
+
+        Assert.assertTrue(trace, trace.contains("3-PushPromise-2"));
+        Assert.assertTrue(trace, trace.contains("2-Header-[:status]-[200]"));
+        Assert.assertTrue(trace, trace.contains("2-Body-8192"));
+        Assert.assertTrue(trace, trace.contains("3-Header-[:status]-[200]"));
+        Assert.assertTrue(trace, trace.contains("3-Body-1024"));
+    }
+
+
+    @Override
+    protected void configureAndStartWebApplication() throws LifecycleException {
+        Tomcat tomcat = getTomcatInstance();
+
+        Context ctxt = tomcat.addContext("", null);
+
+        Tomcat.addServlet(ctxt, "simple", new SimpleServlet());
+        ctxt.addServletMappingDecoded("/simple", "simple");
+
+        Tomcat.addServlet(ctxt, "push", new PushServlet());
+        ctxt.addServletMappingDecoded("/push", "push");
+
+        tomcat.start();
+    }
+
+
+    private static class PushServlet extends HttpServlet {
+
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+            ApplicationPushBuilder pb = ((RequestFacade) req).newPushBuilder();
+            pb.path("/simple").push();
+
+            // Generate content with a simple known format.
+            resp.setContentType("application/octet-stream");
+
+            int count = 512;
+
+            // Two bytes per entry (1k data)
+            resp.setContentLengthLong(count * 2);
+
+            OutputStream os = resp.getOutputStream();
+            byte[] data = new byte[2];
+            for (int i = 0; i < count; i++) {
+                data[0] = (byte) (i & 0xFF);
+                data[1] = (byte) ((i >> 8) & 0xFF);
+                os.write(data);
+            }
+        }
+    }
+}

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[tomcat] 03/06: Back-port creation of dedicated test parser

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 6bfd0f7e73975d4eec87805e3a780ee0ede67f8c
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Jan 14 19:47:17 2022 +0000

    Back-port creation of dedicated test parser
---
 test/org/apache/coyote/http2/Http2TestBase.java    |  4 +--
 .../org/apache/coyote/http2/TesterHttp2Parser.java | 34 ++++++++++++++++++++++
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/test/org/apache/coyote/http2/Http2TestBase.java b/test/org/apache/coyote/http2/Http2TestBase.java
index 9437635..9b0a43a 100644
--- a/test/org/apache/coyote/http2/Http2TestBase.java
+++ b/test/org/apache/coyote/http2/Http2TestBase.java
@@ -94,7 +94,7 @@ public abstract class Http2TestBase extends TomcatBaseTest {
     protected HpackEncoder hpackEncoder;
     protected Input input;
     protected TestOutput output;
-    protected Http2Parser parser;
+    protected TesterHttp2Parser parser;
     protected OutputStream os;
 
     // Server
@@ -633,7 +633,7 @@ public abstract class Http2TestBase extends TomcatBaseTest {
 
         input = new TestInput(is);
         output = new TestOutput();
-        parser = new Http2Parser("-1", input, output);
+        parser = new TesterHttp2Parser("-1", input, output);
         hpackEncoder = new HpackEncoder();
     }
 
diff --git a/test/org/apache/coyote/http2/TesterHttp2Parser.java b/test/org/apache/coyote/http2/TesterHttp2Parser.java
new file mode 100644
index 0000000..9618d6f
--- /dev/null
+++ b/test/org/apache/coyote/http2/TesterHttp2Parser.java
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.coyote.http2;
+
+import java.io.IOException;
+
+/**
+ * Expose the parser outside of this package for use in other tests.
+ */
+public class TesterHttp2Parser extends Http2Parser {
+
+    TesterHttp2Parser(String connectionId, Input input, Output output) {
+        super(connectionId, input, output);
+    }
+
+    @Override
+    public boolean readFrame(boolean block) throws Http2Exception, IOException {
+        return super.readFrame(block);
+    }
+}
\ No newline at end of file

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[tomcat] 01/06: Don't include a cookie header in push request when there are no cookies

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 70a9a31060d0e71c10c41f11053a343e4d63bd43
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Jan 14 19:20:04 2022 +0000

    Don't include a cookie header in push request when there are no cookies
---
 java/org/apache/catalina/core/ApplicationPushBuilder.java | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/java/org/apache/catalina/core/ApplicationPushBuilder.java b/java/org/apache/catalina/core/ApplicationPushBuilder.java
index 57e62bc..9037e9c 100644
--- a/java/org/apache/catalina/core/ApplicationPushBuilder.java
+++ b/java/org/apache/catalina/core/ApplicationPushBuilder.java
@@ -157,10 +157,12 @@ public class ApplicationPushBuilder {
                 cookies.add(new Cookie(responseCookie.getName(), responseCookie.getValue()));
             }
         }
-        List<String> cookieValues = new ArrayList<>(1);
-        cookieValues.add(generateCookieHeader(cookies,
-                catalinaRequest.getContext().getCookieProcessor()));
-        headers.put("cookie", cookieValues);
+        if (cookies.size() > 0) {
+            List<String> cookieValues = new ArrayList<>(1);
+            cookieValues.add(generateCookieHeader(cookies,
+                    catalinaRequest.getContext().getCookieProcessor()));
+            headers.put("cookie", cookieValues);
+        }
 
         // Authentication
         if (catalinaRequest.getPrincipal() != null) {

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[tomcat] 04/06: Add support to HTTP/2 test parser for push promise frames.

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit dc4bb27f91cfd582696c8f521b0ea4741921eefd
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Jan 14 19:24:42 2022 +0000

    Add support to HTTP/2 test parser for push promise frames.
---
 java/org/apache/coyote/http2/Http2Parser.java      |  4 +-
 test/org/apache/coyote/http2/Http2TestBase.java    | 20 +++++++++-
 .../org/apache/coyote/http2/TesterHttp2Parser.java | 46 +++++++++++++++++++++-
 3 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/java/org/apache/coyote/http2/Http2Parser.java b/java/org/apache/coyote/http2/Http2Parser.java
index 8fc7385..df173e1 100644
--- a/java/org/apache/coyote/http2/Http2Parser.java
+++ b/java/org/apache/coyote/http2/Http2Parser.java
@@ -36,7 +36,7 @@ class Http2Parser {
             "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1);
 
     private final String connectionId;
-    private final Input input;
+    protected final Input input;
     private final Output output;
     private final byte[] frameHeaderBuffer = new byte[9];
 
@@ -408,7 +408,7 @@ class Http2Parser {
     }
 
 
-    private void readHeaderPayload(int streamId, int payloadSize)
+    protected void readHeaderPayload(int streamId, int payloadSize)
             throws Http2Exception, IOException {
 
         if (log.isDebugEnabled()) {
diff --git a/test/org/apache/coyote/http2/Http2TestBase.java b/test/org/apache/coyote/http2/Http2TestBase.java
index 9b0a43a..e4054c5 100644
--- a/test/org/apache/coyote/http2/Http2TestBase.java
+++ b/test/org/apache/coyote/http2/Http2TestBase.java
@@ -200,7 +200,7 @@ public abstract class Http2TestBase extends TomcatBaseTest {
 
     protected void buildGetRequest(byte[] frameHeader, ByteBuffer headersPayload, byte[] padding,
             int streamId, String url) {
-        List<Header> headers = new ArrayList<>(3);
+        List<Header> headers = new ArrayList<>(4);
         headers.add(new Header(":method", "GET"));
         headers.add(new Header(":scheme", "http"));
         headers.add(new Header(":path", url));
@@ -1017,6 +1017,7 @@ public abstract class Http2TestBase extends TomcatBaseTest {
         private boolean traceBody = false;
         private ByteBuffer bodyBuffer = null;
         private long bytesRead;
+        private volatile HpackDecoder hpackDecoder = null;
 
         public void setTraceBody(boolean traceBody) {
             this.traceBody = traceBody;
@@ -1025,7 +1026,14 @@ public abstract class Http2TestBase extends TomcatBaseTest {
 
         @Override
         public HpackDecoder getHpackDecoder() {
-            return new HpackDecoder(remoteSettings.getHeaderTableSize());
+            if (hpackDecoder == null) {
+                synchronized (this) {
+                    if (hpackDecoder == null) {
+                        hpackDecoder = new HpackDecoder(remoteSettings.getHeaderTableSize());
+                    }
+                }
+            }
+            return hpackDecoder;
         }
 
 
@@ -1205,6 +1213,14 @@ public abstract class Http2TestBase extends TomcatBaseTest {
         }
 
 
+        public void pushPromise(int streamId, int pushedStreamId) {
+            trace.append(streamId);
+            trace.append("-PushPromise-");
+            trace.append(pushedStreamId);
+            trace.append("\n");
+        }
+
+
         public void clearTrace() {
             trace = new StringBuffer();
             bytesRead = 0;
diff --git a/test/org/apache/coyote/http2/TesterHttp2Parser.java b/test/org/apache/coyote/http2/TesterHttp2Parser.java
index 9618d6f..2951896 100644
--- a/test/org/apache/coyote/http2/TesterHttp2Parser.java
+++ b/test/org/apache/coyote/http2/TesterHttp2Parser.java
@@ -18,17 +18,59 @@ package org.apache.coyote.http2;
 
 import java.io.IOException;
 
+import org.apache.coyote.http2.Http2TestBase.TestOutput;
+
 /**
  * Expose the parser outside of this package for use in other tests.
  */
 public class TesterHttp2Parser extends Http2Parser {
 
-    TesterHttp2Parser(String connectionId, Input input, Output output) {
+    private final TestOutput output;
+
+    TesterHttp2Parser(String connectionId, Input input, TestOutput output) {
         super(connectionId, input, output);
+        this.output = output;
     }
 
     @Override
     public boolean readFrame(boolean block) throws Http2Exception, IOException {
         return super.readFrame(block);
     }
-}
\ No newline at end of file
+
+    @Override
+    protected void readPushPromiseFrame(int streamId, int flags, int payloadSize) throws Http2Exception, IOException {
+
+        // Parse flags used in this method
+        boolean hasPadding = Flags.hasPadding(flags);
+        boolean headersEndStream = Flags.isEndOfStream(flags);
+
+        // Padding size
+        int paddingSize = 0;
+        if (hasPadding) {
+            byte[] bPadSize = new byte[1];
+            input.fill(true, bPadSize);
+            paddingSize = ByteUtil.getOneByte(bPadSize, 0);
+        }
+
+        // Pushed stream ID
+        byte[] bPushedStreamId = new byte[4];
+        input.fill(true, bPushedStreamId);
+        int pushedStreamId = ByteUtil.get31Bits(bPushedStreamId, 0);
+
+        output.pushPromise(streamId, pushedStreamId);
+
+        int headerSize = payloadSize - 4 - paddingSize;
+        if (hasPadding) {
+            headerSize--;
+        }
+
+        HpackDecoder hpackDecoder = output.getHpackDecoder();
+        hpackDecoder.setHeaderEmitter(output.headersStart(pushedStreamId, headersEndStream));
+
+        readHeaderPayload(pushedStreamId, headerSize);
+
+        if (hasPadding) {
+            swallowPayload(streamId, FrameType.PUSH_PROMISE.getId(), paddingSize, true);
+        }
+    }
+}

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[tomcat] 06/06: Fix server push. Validation will see pseudo headers so should allow them

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 6c71b4f206730c20d3e81459d7d5e4a9d8234bae
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Jan 14 19:25:35 2022 +0000

    Fix server push. Validation will see pseudo headers so should allow them
---
 java/org/apache/coyote/http2/StreamProcessor.java | 19 ++++++++++++++++++-
 webapps/docs/changelog.xml                        |  8 ++++++++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/coyote/http2/StreamProcessor.java b/java/org/apache/coyote/http2/StreamProcessor.java
index c8731a6..734a4cb 100644
--- a/java/org/apache/coyote/http2/StreamProcessor.java
+++ b/java/org/apache/coyote/http2/StreamProcessor.java
@@ -18,7 +18,9 @@ package org.apache.coyote.http2;
 
 import java.io.IOException;
 import java.util.Enumeration;
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Set;
 
 import javax.servlet.http.HttpServletResponse;
 
@@ -49,9 +51,17 @@ class StreamProcessor extends AbstractProcessor {
     private static final Log log = LogFactory.getLog(StreamProcessor.class);
     private static final StringManager sm = StringManager.getManager(StreamProcessor.class);
 
+    private static final Set<String> H2_PSEUDO_HEADERS_REQUEST = new HashSet<>();
+
     private final Http2UpgradeHandler handler;
     private final Stream stream;
 
+    static {
+        H2_PSEUDO_HEADERS_REQUEST.add(":method");
+        H2_PSEUDO_HEADERS_REQUEST.add(":scheme");
+        H2_PSEUDO_HEADERS_REQUEST.add(":authority");
+        H2_PSEUDO_HEADERS_REQUEST.add(":path");
+    }
 
     StreamProcessor(Http2UpgradeHandler handler, Stream stream, Adapter adapter,
             SocketWrapperBase<?> socketWrapper) {
@@ -456,9 +466,16 @@ class StreamProcessor extends AbstractProcessor {
 
         // HTTP header names must be tokens.
         MimeHeaders headers = request.getMimeHeaders();
+        boolean previousHeaderWasPseudoHeader = true;
         Enumeration<String> names = headers.names();
         while (names.hasMoreElements()) {
-            if (!HttpParser.isToken(names.nextElement())) {
+            String name = names.nextElement();
+            if (H2_PSEUDO_HEADERS_REQUEST.contains(name)) {
+                if (!previousHeaderWasPseudoHeader) {
+                    return false;
+                }
+            } else if (!HttpParser.isToken(name)) {
+                previousHeaderWasPseudoHeader = false;
                 return false;
             }
         }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 5b5fa84..aa82f3d 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -105,6 +105,14 @@
   issues do not "pop up" wrt. others).
 -->
 <section name="Tomcat 8.5.75 (schultz)" rtext="In development">
+  <subsection name="Coyote">
+    <changelog>
+      <fix>
+        Correct a regression in the fix for <bug>65785</bug> that broke HTTP/2
+        server push. (markt)
+      </fix>
+    </changelog>
+  </subsection>
 </section>
 <section name="Tomcat 8.5.74 (schultz)" rtext="Release in progress">
   <subsection name="Catalina">

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org