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

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

commit d28d6836b80d0709c56a3ab24d515788498c760e
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Oct 2 11:56:41 2023 +0100

    Remove support for HTTP/2 server push
---
 java/org/apache/catalina/connector/Request.java    |  19 -
 .../apache/catalina/connector/RequestFacade.java   |  14 -
 .../catalina/core/ApplicationHttpRequest.java      |  18 -
 .../catalina/core/ApplicationPushBuilder.java      | 427 ---------------------
 .../apache/catalina/core/LocalStrings.properties   |   5 -
 .../catalina/core/LocalStrings_fr.properties       |   5 -
 .../catalina/core/LocalStrings_ja.properties       |   5 -
 .../catalina/core/LocalStrings_ko.properties       |   5 -
 .../catalina/core/LocalStrings_zh_CN.properties    |   5 -
 .../apache/catalina/filters/RemoteIpFilter.java    |  16 -
 .../catalina/core/TestApplicationPushBuilder.java  |  72 ----
 .../catalina/filters/TesterHttpServletRequest.java |   6 -
 .../apache/coyote/http2/TestHttp2Section_6_6.java  | 127 ------
 webapps/docs/changelog.xml                         |   5 +
 .../WEB-INF/classes/http2/SimpleImagePush.java     |  59 ---
 webapps/examples/WEB-INF/web.xml                   |  10 -
 webapps/examples/servlets/index.html               |  11 -
 17 files changed, 5 insertions(+), 804 deletions(-)

diff --git a/java/org/apache/catalina/connector/Request.java 
b/java/org/apache/catalina/connector/Request.java
index 8e800464be..cc9a515f96 100644
--- a/java/org/apache/catalina/connector/Request.java
+++ b/java/org/apache/catalina/connector/Request.java
@@ -65,7 +65,6 @@ import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpSession;
 import jakarta.servlet.http.HttpUpgradeHandler;
 import jakarta.servlet.http.Part;
-import jakarta.servlet.http.PushBuilder;
 
 import org.apache.catalina.Container;
 import org.apache.catalina.Context;
@@ -79,7 +78,6 @@ import org.apache.catalina.Wrapper;
 import org.apache.catalina.core.ApplicationFilterChain;
 import org.apache.catalina.core.ApplicationMapping;
 import org.apache.catalina.core.ApplicationPart;
-import org.apache.catalina.core.ApplicationPushBuilder;
 import org.apache.catalina.core.ApplicationSessionCookieConfig;
 import org.apache.catalina.core.AsyncContextImpl;
 import org.apache.catalina.mapper.MappingData;
@@ -1866,23 +1864,6 @@ public class Request implements HttpServletRequest {
     }
 
 
-    @Override
-    public PushBuilder newPushBuilder() {
-        return newPushBuilder(this);
-    }
-
-
-    public PushBuilder newPushBuilder(HttpServletRequest request) {
-        AtomicBoolean result = new AtomicBoolean();
-        coyoteRequest.action(ActionCode.IS_PUSH_SUPPORTED, result);
-        if (result.get()) {
-            return new ApplicationPushBuilder(this, request);
-        } else {
-            return null;
-        }
-    }
-
-
     @SuppressWarnings("unchecked")
     @Override
     public <T extends HttpUpgradeHandler> T upgrade(Class<T> 
httpUpgradeHandlerClass)
diff --git a/java/org/apache/catalina/connector/RequestFacade.java 
b/java/org/apache/catalina/connector/RequestFacade.java
index 956790888f..1a2f335076 100644
--- a/java/org/apache/catalina/connector/RequestFacade.java
+++ b/java/org/apache/catalina/connector/RequestFacade.java
@@ -40,7 +40,6 @@ import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpSession;
 import jakarta.servlet.http.HttpUpgradeHandler;
 import jakarta.servlet.http.Part;
-import jakarta.servlet.http.PushBuilder;
 
 import org.apache.tomcat.util.res.StringManager;
 
@@ -573,19 +572,6 @@ public class RequestFacade implements HttpServletRequest {
     }
 
 
-    @Override
-    public PushBuilder newPushBuilder() {
-        checkFacade();
-        return request.newPushBuilder();
-    }
-
-
-    public PushBuilder newPushBuilder(HttpServletRequest request) {
-        checkFacade();
-        return this.request.newPushBuilder(request);
-    }
-
-
     @Override
     public boolean isTrailerFieldsReady() {
         checkFacade();
diff --git a/java/org/apache/catalina/core/ApplicationHttpRequest.java 
b/java/org/apache/catalina/core/ApplicationHttpRequest.java
index 1b93479d32..14f0855b9e 100644
--- a/java/org/apache/catalina/core/ApplicationHttpRequest.java
+++ b/java/org/apache/catalina/core/ApplicationHttpRequest.java
@@ -32,19 +32,15 @@ import java.util.NoSuchElementException;
 import jakarta.servlet.DispatcherType;
 import jakarta.servlet.RequestDispatcher;
 import jakarta.servlet.ServletContext;
-import jakarta.servlet.ServletRequest;
-import jakarta.servlet.ServletRequestWrapper;
 import jakarta.servlet.http.HttpServletMapping;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletRequestWrapper;
 import jakarta.servlet.http.HttpSession;
-import jakarta.servlet.http.PushBuilder;
 
 import org.apache.catalina.Context;
 import org.apache.catalina.Globals;
 import org.apache.catalina.Manager;
 import org.apache.catalina.Session;
-import org.apache.catalina.connector.RequestFacade;
 import org.apache.catalina.util.ParameterMap;
 import org.apache.catalina.util.RequestUtil;
 import org.apache.catalina.util.URLEncoder;
@@ -597,20 +593,6 @@ class ApplicationHttpRequest extends 
HttpServletRequestWrapper {
     }
 
 
-    @Override
-    public PushBuilder newPushBuilder() {
-        ServletRequest current = getRequest();
-        while (current instanceof ServletRequestWrapper) {
-            current = ((ServletRequestWrapper) current).getRequest();
-        }
-        if (current instanceof RequestFacade) {
-            return ((RequestFacade) current).newPushBuilder(this);
-        } else {
-            return null;
-        }
-    }
-
-
     // -------------------------------------------------------- Package Methods
 
     /**
diff --git a/java/org/apache/catalina/core/ApplicationPushBuilder.java 
b/java/org/apache/catalina/core/ApplicationPushBuilder.java
deleted file mode 100644
index 90250326ac..0000000000
--- a/java/org/apache/catalina/core/ApplicationPushBuilder.java
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * 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.catalina.core;
-
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-import jakarta.servlet.SessionTrackingMode;
-import jakarta.servlet.http.Cookie;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpSession;
-import jakarta.servlet.http.PushBuilder;
-
-import org.apache.catalina.Context;
-import org.apache.catalina.authenticator.AuthenticatorBase;
-import org.apache.catalina.connector.Request;
-import org.apache.catalina.util.SessionConfig;
-import org.apache.coyote.ActionCode;
-import org.apache.tomcat.util.buf.HexUtils;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.collections.CaseInsensitiveKeyMap;
-import org.apache.tomcat.util.http.CookieProcessor;
-import org.apache.tomcat.util.http.parser.HttpParser;
-import org.apache.tomcat.util.res.StringManager;
-
-public class ApplicationPushBuilder implements PushBuilder {
-
-    private static final StringManager sm = 
StringManager.getManager(ApplicationPushBuilder.class);
-    private static final Set<String> DISALLOWED_METHODS = new HashSet<>();
-
-    static {
-        DISALLOWED_METHODS.add("POST");
-        DISALLOWED_METHODS.add("PUT");
-        DISALLOWED_METHODS.add("DELETE");
-        DISALLOWED_METHODS.add("CONNECT");
-        DISALLOWED_METHODS.add("OPTIONS");
-        DISALLOWED_METHODS.add("TRACE");
-    }
-
-    private final HttpServletRequest baseRequest;
-    private final Request catalinaRequest;
-    private final org.apache.coyote.Request coyoteRequest;
-    private final String sessionCookieName;
-    private final String sessionPathParameterName;
-    private final boolean addSessionCookie;
-    private final boolean addSessionPathParameter;
-
-    private final Map<String,List<String>> headers = new 
CaseInsensitiveKeyMap<>();
-    private final List<Cookie> cookies = new ArrayList<>();
-    private String method = "GET";
-    private String path;
-    private String queryString;
-    private String sessionId;
-    private String userName;
-
-
-    public ApplicationPushBuilder(Request catalinaRequest, HttpServletRequest 
request) {
-
-        baseRequest = request;
-        this.catalinaRequest = catalinaRequest;
-        coyoteRequest = catalinaRequest.getCoyoteRequest();
-
-        // Populate the initial list of HTTP headers
-        Enumeration<String> headerNames = request.getHeaderNames();
-        while (headerNames.hasMoreElements()) {
-            String headerName = headerNames.nextElement();
-            List<String> values = new ArrayList<>();
-            headers.put(headerName, values);
-            Enumeration<String> headerValues = request.getHeaders(headerName);
-            while (headerValues.hasMoreElements()) {
-                values.add(headerValues.nextElement());
-            }
-        }
-
-        // Remove the headers
-        headers.remove("if-match");
-        headers.remove("if-none-match");
-        headers.remove("if-modified-since");
-        headers.remove("if-unmodified-since");
-        headers.remove("if-range");
-        headers.remove("range");
-        headers.remove("expect");
-        headers.remove("authorization");
-        headers.remove("referer");
-        // Also remove the cookie header since it will be regenerated
-        headers.remove("cookie");
-
-        // set the referer header
-        StringBuffer referer = request.getRequestURL();
-        if (request.getQueryString() != null) {
-            referer.append('?');
-            referer.append(request.getQueryString());
-        }
-        addHeader("referer", referer.toString());
-
-        // Session
-        Context context = catalinaRequest.getContext();
-        sessionCookieName = SessionConfig.getSessionCookieName(context);
-        sessionPathParameterName = 
SessionConfig.getSessionUriParamName(context);
-
-        HttpSession session = request.getSession(false);
-        if (session != null) {
-            sessionId = session.getId();
-        }
-        if (sessionId == null) {
-            sessionId = request.getRequestedSessionId();
-        }
-        if (!request.isRequestedSessionIdFromCookie() && 
!request.isRequestedSessionIdFromURL() && sessionId != null) {
-            Set<SessionTrackingMode> sessionTrackingModes =
-                    
request.getServletContext().getEffectiveSessionTrackingModes();
-            addSessionCookie = 
sessionTrackingModes.contains(SessionTrackingMode.COOKIE);
-            addSessionPathParameter = 
sessionTrackingModes.contains(SessionTrackingMode.URL);
-        } else {
-            addSessionCookie = request.isRequestedSessionIdFromCookie();
-            addSessionPathParameter = request.isRequestedSessionIdFromURL();
-        }
-
-        // Cookies
-        if (request.getCookies() != null) {
-            cookies.addAll(Arrays.asList(request.getCookies()));
-        }
-        for (Cookie responseCookie : 
catalinaRequest.getResponse().getCookies()) {
-            if (responseCookie.getMaxAge() < 0) {
-                // Path information not available so can only remove based on
-                // name.
-                cookies.removeIf(cookie -> 
cookie.getName().equals(responseCookie.getName()));
-            } else {
-                cookies.add(new Cookie(responseCookie.getName(), 
responseCookie.getValue()));
-            }
-        }
-        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) {
-            if ((session == null) || 
catalinaRequest.getSessionInternal(false).getPrincipal() == null ||
-                    !(context.getAuthenticator() instanceof AuthenticatorBase) 
||
-                    !((AuthenticatorBase) 
context.getAuthenticator()).getCache()) {
-                // Set a username only if there is no session cache for the 
principal
-                userName = catalinaRequest.getPrincipal().getName();
-            }
-            setHeader("authorization", "x-push");
-        }
-    }
-
-    @Override
-    public PushBuilder path(String path) {
-        if (path.startsWith("/")) {
-            this.path = path;
-        } else {
-            String contextPath = baseRequest.getContextPath();
-            int len = contextPath.length() + path.length() + 1;
-            StringBuilder sb = new StringBuilder(len);
-            sb.append(contextPath);
-            sb.append('/');
-            sb.append(path);
-            this.path = sb.toString();
-        }
-        return this;
-    }
-
-
-    @Override
-    public String getPath() {
-        return path;
-    }
-
-
-    @Override
-    public PushBuilder method(String method) {
-        String upperMethod = method.trim().toUpperCase(Locale.ENGLISH);
-        if (DISALLOWED_METHODS.contains(upperMethod) || upperMethod.length() 
== 0) {
-            throw new 
IllegalArgumentException(sm.getString("applicationPushBuilder.methodInvalid", 
upperMethod));
-        }
-        // Check a token was supplied
-        if (!HttpParser.isToken(upperMethod)) {
-            throw new 
IllegalArgumentException(sm.getString("applicationPushBuilder.methodNotToken", 
upperMethod));
-        }
-        this.method = method;
-        return this;
-    }
-
-
-    @Override
-    public String getMethod() {
-        return method;
-    }
-
-
-    @Override
-    public PushBuilder queryString(String queryString) {
-        this.queryString = queryString;
-        return this;
-    }
-
-
-    @Override
-    public String getQueryString() {
-        return queryString;
-    }
-
-
-    @Override
-    public PushBuilder sessionId(String sessionId) {
-        this.sessionId = sessionId;
-        return this;
-    }
-
-
-    @Override
-    public String getSessionId() {
-        return sessionId;
-    }
-
-
-    @Override
-    public PushBuilder addHeader(String name, String value) {
-        headers.computeIfAbsent(name, k -> new ArrayList<>()).add(value);
-        return this;
-    }
-
-
-    @Override
-    public PushBuilder setHeader(String name, String value) {
-        List<String> values = headers.get(name);
-        if (values == null) {
-            values = new ArrayList<>();
-            headers.put(name, values);
-        } else {
-            values.clear();
-        }
-        values.add(value);
-
-        return this;
-    }
-
-
-    @Override
-    public PushBuilder removeHeader(String name) {
-        headers.remove(name);
-
-        return this;
-    }
-
-
-    @Override
-    public Set<String> getHeaderNames() {
-        return Collections.unmodifiableSet(headers.keySet());
-    }
-
-
-    @Override
-    public String getHeader(String name) {
-        List<String> values = headers.get(name);
-        if (values == null) {
-            return null;
-        } else {
-            return values.get(0);
-        }
-    }
-
-
-    @Override
-    public void push() {
-        if (path == null) {
-            throw new 
IllegalStateException(sm.getString("pushBuilder.noPath"));
-        }
-
-        org.apache.coyote.Request pushTarget = new org.apache.coyote.Request();
-
-        pushTarget.method().setString(method);
-        // The next three are implied by the Javadoc getPath()
-        pushTarget.serverName().setString(baseRequest.getServerName());
-        pushTarget.setServerPort(baseRequest.getServerPort());
-        pushTarget.scheme().setString(baseRequest.getScheme());
-
-        // Copy headers
-        for (Map.Entry<String,List<String>> header : headers.entrySet()) {
-            for (String value : header.getValue()) {
-                
pushTarget.getMimeHeaders().addValue(header.getKey()).setString(value);
-            }
-        }
-
-        // Path and query string
-        int queryIndex = path.indexOf('?');
-        String pushPath;
-        String pushQueryString = null;
-        if (queryIndex > -1) {
-            pushPath = path.substring(0, queryIndex);
-            if (queryIndex + 1 < path.length()) {
-                pushQueryString = path.substring(queryIndex + 1);
-            }
-        } else {
-            pushPath = path;
-        }
-
-        // Session ID (do this before setting the path since it may change it)
-        if (sessionId != null) {
-            if (addSessionPathParameter) {
-                pushPath = pushPath + ";" + sessionPathParameterName + "=" + 
sessionId;
-                pushTarget.addPathParameter(sessionPathParameterName, 
sessionId);
-            }
-            if (addSessionCookie) {
-                String sessionCookieHeader = sessionCookieName + "=" + 
sessionId;
-                MessageBytes mb = 
pushTarget.getMimeHeaders().getValue("cookie");
-                if (mb == null) {
-                    mb = pushTarget.getMimeHeaders().addValue("cookie");
-                    mb.setString(sessionCookieHeader);
-                } else {
-                    mb.setString(mb.getString() + ";" + sessionCookieHeader);
-                }
-            }
-        }
-
-        // Undecoded path - just %nn encoded
-        pushTarget.requestURI().setString(pushPath);
-        pushTarget.decodedURI().setString(decode(pushPath, 
catalinaRequest.getConnector().getURICharset()));
-
-        // Query string
-        if (pushQueryString == null && queryString != null) {
-            pushTarget.queryString().setString(queryString);
-        } else if (pushQueryString != null && queryString == null) {
-            pushTarget.queryString().setString(pushQueryString);
-        } else if (pushQueryString != null && queryString != null) {
-            pushTarget.queryString().setString(pushQueryString + "&" + 
queryString);
-        }
-
-        // Authorization
-        if (userName != null) {
-            pushTarget.getRemoteUser().setString(userName);
-            pushTarget.setRemoteUserNeedsAuthorization(true);
-        }
-
-        coyoteRequest.action(ActionCode.PUSH_REQUEST, pushTarget);
-
-        // Reset for next call to this method
-        path = null;
-        headers.remove("if-none-match");
-        headers.remove("if-modified-since");
-    }
-
-
-    // Package private so it can be tested. charsetName must be in lower case.
-    static String decode(String input, Charset charset) {
-        int start = input.indexOf('%');
-        int end = 0;
-
-        // Shortcut
-        if (start == -1) {
-            return input;
-        }
-
-        StringBuilder result = new StringBuilder(input.length());
-        while (start != -1) {
-            // Found the start of a %nn sequence. Copy everything from the last
-            // end to this start to the output.
-            result.append(input.substring(end, start));
-            // Advance the end 3 characters: %nn
-            end = start + 3;
-            while (end < input.length() && input.charAt(end) == '%') {
-                end += 3;
-            }
-            result.append(decodePercentSequence(input.substring(start, end), 
charset));
-            start = input.indexOf('%', end);
-        }
-        // Append the remaining text
-        result.append(input.substring(end));
-
-        return result.toString();
-    }
-
-
-    private static String decodePercentSequence(String sequence, Charset 
charset) {
-        byte[] bytes = new byte[sequence.length() / 3];
-        for (int i = 0; i < bytes.length; i += 3) {
-            bytes[i] = (byte) ((HexUtils.getDec(sequence.charAt(1 + 3 * i)) << 
4) +
-                    HexUtils.getDec(sequence.charAt(2 + 3 * i)));
-        }
-
-        return new String(bytes, charset);
-    }
-
-
-    private static String generateCookieHeader(List<Cookie> cookies, 
CookieProcessor cookieProcessor) {
-        StringBuilder result = new StringBuilder();
-        boolean first = true;
-        for (Cookie cookie : cookies) {
-            if (first) {
-                first = false;
-            } else {
-                result.append(';');
-            }
-            // The cookie header value generated by the CookieProcessor was
-            // originally intended for the Set-Cookie header on the response.
-            // However, if passed a Cookie with just a name and value set it
-            // will generate an appropriate header for the Cookie header on the
-            // pushed request.
-            result.append(cookieProcessor.generateHeader(cookie, null));
-        }
-        return result.toString();
-    }
-}
diff --git a/java/org/apache/catalina/core/LocalStrings.properties 
b/java/org/apache/catalina/core/LocalStrings.properties
index fd59aa65dc..d3d47814d0 100644
--- a/java/org/apache/catalina/core/LocalStrings.properties
+++ b/java/org/apache/catalina/core/LocalStrings.properties
@@ -60,9 +60,6 @@ applicationFilterRegistration.nullInitParams=Unable to set 
initialisation parame
 
 applicationHttpRequest.fragmentInDispatchPath=The fragment in dispatch path 
[{0}] has been removed
 
-applicationPushBuilder.methodInvalid=The HTTP method for a push request must 
be both cacheable and safe but [{0}] is not
-applicationPushBuilder.methodNotToken=HTTP methods must be tokens but [{0}] 
contains a non-token character
-
 applicationServletRegistration.setServletSecurity.iae=Null constraint 
specified for servlet [{0}] deployed to context with name [{1}]
 applicationServletRegistration.setServletSecurity.ise=Security constraints 
can''t be added to servlet [{0}] deployed to context with name [{1}] as the 
context has already been initialised
 
@@ -162,8 +159,6 @@ naming.wsdlFailed=Failed to find wsdl file: [{0}]
 
 noPluggabilityServletContext.notAllowed=Section 4.4 of the Servlet 3.0 
specification does not permit this method to be called from a 
ServletContextListener that was not defined in web.xml, a web-fragment.xml file 
nor annotated with @WebListener
 
-pushBuilder.noPath=It is illegal to call push() before setting a path
-
 propertiesRoleMappingListener.roleMappingFileNull=Role mapping file cannot be 
null
 propertiesRoleMappingListener.roleMappingFileEmpty=Role mapping file cannot be 
empty
 propertiesRoleMappingListener.roleMappingFileFail=Failed to load role mapping 
file [{0}]
diff --git a/java/org/apache/catalina/core/LocalStrings_fr.properties 
b/java/org/apache/catalina/core/LocalStrings_fr.properties
index f77785045b..cd627970f9 100644
--- a/java/org/apache/catalina/core/LocalStrings_fr.properties
+++ b/java/org/apache/catalina/core/LocalStrings_fr.properties
@@ -60,9 +60,6 @@ applicationFilterRegistration.nullInitParams=Impossible de 
fixer les paramètres
 
 applicationHttpRequest.fragmentInDispatchPath=Le fragment dans le chemin de 
dispatch [{0}] a été enlevé
 
-applicationPushBuilder.methodInvalid=La méthode HTTP pour une requête push 
doit être à la fois être sans danger et pouvoir être mise en cache, mais [{0}] 
ne correspond pas
-applicationPushBuilder.methodNotToken=Les méthodes HTTP doivent être des 
"token", mais [{0}] contient un caractère invalide dans un token.
-
 applicationServletRegistration.setServletSecurity.iae=Contrainte nulle 
spécifiée pour le Servlet [{0}] déployé dans le contexte avec le nom [{1}]
 applicationServletRegistration.setServletSecurity.ise=Les contraintes de 
sécurité ne peuvent pas être ajoutées au Servlet [{0}] déployé dans le contexte 
[{1}] car le contexte a déjà été initialisé
 
@@ -168,8 +165,6 @@ propertiesRoleMappingListener.roleMappingFileEmpty=Le 
fichier d'association de r
 propertiesRoleMappingListener.roleMappingFileFail=Erreur de chargement du 
fichier d''association de rôles [{0}]
 propertiesRoleMappingListener.roleMappingFileNull=Le fichier d'association de 
rôles ne peut être null
 
-pushBuilder.noPath=Il est interdit d'appeler push() avant de fixer un chemin
-
 standardContext.applicationListener=Erreur lors de la configuration de la 
classe d''écoute de l''application (application listener) [{0}]
 standardContext.applicationSkipped=L'installation des écouteurs (listeners) de 
l'application a été sautée suite aux erreurs précédentes
 standardContext.backgroundProcess.instanceManager=Exception lors du traitement 
d''arrière plan du gestionnaire d''instances [{0}]
diff --git a/java/org/apache/catalina/core/LocalStrings_ja.properties 
b/java/org/apache/catalina/core/LocalStrings_ja.properties
index 40006c8836..7faf8abedc 100644
--- a/java/org/apache/catalina/core/LocalStrings_ja.properties
+++ b/java/org/apache/catalina/core/LocalStrings_ja.properties
@@ -60,9 +60,6 @@ applicationFilterRegistration.nullInitParams=キー [{0}] または値 
[{1}] の
 
 applicationHttpRequest.fragmentInDispatchPath=ディスパッチパス [{0}] 中のフラグメントは除去されました
 
-applicationPushBuilder.methodInvalid=プッシュリクエストの HTTP 
メソッドはキャッシュ可能、かつ、安全でなければなりません。[{0}] は指定できません。
-applicationPushBuilder.methodNotToken=HTTP メソッド [{0}] にトークンとして利用できない文字が含まれています。
-
 applicationServletRegistration.setServletSecurity.iae=サーブレット [{0}] 
に指定されたNULL制約が、名前 [{1}] のコンテキストに配備されました
 applicationServletRegistration.setServletSecurity.ise=コンテキストが既に初期化されているため、名前 
[{1}] のコンテキストに配備されたサーブレット [{0}] にセキュリティ制約を追加できません
 
@@ -168,8 +165,6 @@ propertiesRoleMappingListener.roleMappingFileEmpty=ロール 
マッピング フ
 propertiesRoleMappingListener.roleMappingFileFail=ロール マッピング ファイル [{0}] 
のロードに失敗しました
 propertiesRoleMappingListener.roleMappingFileNull=ロール マッピング ファイルを null 
にすることはできません
 
-pushBuilder.noPath=path を設定する前に push() を呼び出すことはできません。
-
 standardContext.applicationListener=クラス [{0}] のアプリケーションリスナの設定中にエラーが発生しました
 standardContext.applicationSkipped=前のエラーのためにアプリケーションリスナのインストールをスキップします
 standardContext.backgroundProcess.instanceManager=インスタンスマネージャ [{0}] 
のバックグラウンドプロセス処理中の例外
diff --git a/java/org/apache/catalina/core/LocalStrings_ko.properties 
b/java/org/apache/catalina/core/LocalStrings_ko.properties
index 6d735f15cb..6ed9a1005d 100644
--- a/java/org/apache/catalina/core/LocalStrings_ko.properties
+++ b/java/org/apache/catalina/core/LocalStrings_ko.properties
@@ -60,9 +60,6 @@ applicationFilterRegistration.nullInitParams=널인 이름 또는 값 때문에,
 
 applicationHttpRequest.fragmentInDispatchPath=디스패치 경로 [{0}](으)로부터 URI 
fragment를 제거했습니다.
 
-applicationPushBuilder.methodInvalid=PUSH 요청을 위한 HTTP 메소드는 반드시 캐시 가능하고 안전해야 
하는데, [{0}]은(는) 그렇지 않습니다.
-applicationPushBuilder.methodNotToken=HTTP 메소드들은 토큰들이어야 하지만, [{0}]은(는) 토큰이 아닌 
문자를 포함하고 있습니다.
-
 applicationServletRegistration.setServletSecurity.iae=[{1}](이)라는 이름의 컨텍스트에 배치된 
서블릿 [{0}]을(를) 위해, 널 constraint가 지정되었습니다.
 applicationServletRegistration.setServletSecurity.ise=컨텍스트가 이미 초기화되었기에, 
[{1}](이)라는 이름의 컨텍스트에 배치된 서블릿 [{0}]에 security constraint들이 추가될 수 없습니다.
 
@@ -159,8 +156,6 @@ naming.wsdlFailed=wsdl 파일을 찾지 못했습니다: [{0}]
 
 noPluggabilityServletContext.notAllowed=Servlet 3.0 스펙의 4.4 장에 따르면, web.xml 또는 
web-fragment.xml 파일에 정의되지 않거나 @WebListener로 annotate되지 않은, 
ServletContextListener에서 이 메소드를 호출하는 것은 허용되지 않습니다.
 
-pushBuilder.noPath=경로를 설정하기 전에 push()를 호출하는 것은 불허됩니다.
-
 standardContext.applicationListener=클래스 [{0}]의 애플리케이션 리스너를 설정하는 중 오류 발생
 standardContext.applicationSkipped=이전 오류(들)로 인하여, 애플리케이션 리스너들을 설치하는 것을 건너뛰었습니다.
 standardContext.backgroundProcess.instanceManager=인스턴스 매니저 [{0}]을(를) 백그라운드 
프로세스에서 처리 중 예외 발생
diff --git a/java/org/apache/catalina/core/LocalStrings_zh_CN.properties 
b/java/org/apache/catalina/core/LocalStrings_zh_CN.properties
index 1ce8fc779b..534134732a 100644
--- a/java/org/apache/catalina/core/LocalStrings_zh_CN.properties
+++ b/java/org/apache/catalina/core/LocalStrings_zh_CN.properties
@@ -61,9 +61,6 @@ 
applicationFilterRegistration.nullInitParams=由于name和(或)value为null,
 
 applicationHttpRequest.fragmentInDispatchPath=调度路径[{0}]中的片段已被删除
 
-applicationPushBuilder.methodInvalid=推送请求的HTTP方法必须既可缓存又安全,但是[{0}]不是
-applicationPushBuilder.methodNotToken=HTTP方法必须是令牌(token),但 [{0}] 包含非令牌字符
-
 
applicationServletRegistration.setServletSecurity.iae=为部署到名为[{1}]的上下文的Servlet[{0}]指定的空约束
 
applicationServletRegistration.setServletSecurity.ise=无法将安全性约束添加到已部署到名称为[{1}]的上下文的servlet
 [{0}]中,因为上下文已被初始化
 
@@ -164,8 +161,6 @@ propertiesRoleMappingListener.roleMappingFileEmpty=角色映射文件不能为
 propertiesRoleMappingListener.roleMappingFileFail=加载角色映射文件[{0}]失败
 propertiesRoleMappingListener.roleMappingFileNull=角色映射文件不能为NULL
 
-pushBuilder.noPath=在设置路径之前调用push()是非法的
-
 standardContext.applicationListener=配置应用程序监听器[{0}]错误
 standardContext.applicationSkipped=由于以前的错误,已跳过安装应用程序侦听器
 standardContext.backgroundProcess.instanceManager=异常处理实例管理器[{0}]后台进程
diff --git a/java/org/apache/catalina/filters/RemoteIpFilter.java 
b/java/org/apache/catalina/filters/RemoteIpFilter.java
index 13a0eb7bf9..038f4a95b7 100644
--- a/java/org/apache/catalina/filters/RemoteIpFilter.java
+++ b/java/org/apache/catalina/filters/RemoteIpFilter.java
@@ -34,16 +34,13 @@ import jakarta.servlet.FilterChain;
 import jakarta.servlet.GenericFilter;
 import jakarta.servlet.ServletException;
 import jakarta.servlet.ServletRequest;
-import jakarta.servlet.ServletRequestWrapper;
 import jakarta.servlet.ServletResponse;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletRequestWrapper;
 import jakarta.servlet.http.HttpServletResponse;
-import jakarta.servlet.http.PushBuilder;
 
 import org.apache.catalina.AccessLog;
 import org.apache.catalina.Globals;
-import org.apache.catalina.connector.RequestFacade;
 import org.apache.catalina.util.RequestUtil;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
@@ -640,19 +637,6 @@ public class RemoteIpFilter extends GenericFilter {
         public StringBuffer getRequestURL() {
             return RequestUtil.getRequestURL(this);
         }
-
-        @Override
-        public PushBuilder newPushBuilder() {
-            ServletRequest current = getRequest();
-            while (current instanceof ServletRequestWrapper) {
-                current = ((ServletRequestWrapper) current).getRequest();
-            }
-            if (current instanceof RequestFacade) {
-                return ((RequestFacade) current).newPushBuilder(this);
-            } else {
-                return null;
-            }
-        }
     }
 
 
diff --git a/test/org/apache/catalina/core/TestApplicationPushBuilder.java 
b/test/org/apache/catalina/core/TestApplicationPushBuilder.java
deleted file mode 100644
index e939084b64..0000000000
--- a/test/org/apache/catalina/core/TestApplicationPushBuilder.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *  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.catalina.core;
-
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class TestApplicationPushBuilder {
-
-    @Test
-    public void test01() {
-        doTest("foo", StandardCharsets.UTF_8, "foo");
-    }
-
-    @Test
-    public void test02() {
-        doTest("/foo", StandardCharsets.UTF_8, "/foo");
-    }
-
-    @Test
-    public void test03() {
-        doTest("%20foo", StandardCharsets.UTF_8, " foo");
-    }
-
-    @Test
-    public void test04() {
-        doTest("fo%20o", StandardCharsets.UTF_8, "fo o");
-    }
-
-    @Test
-    public void test05() {
-        doTest("foo%20", StandardCharsets.UTF_8, "foo ");
-    }
-
-    @Test
-    public void test06() {
-        doTest("%21foo", StandardCharsets.UTF_8, "!foo");
-    }
-
-    @Test
-    public void test07() {
-        doTest("fo%21o", StandardCharsets.UTF_8, "fo!o");
-    }
-
-    @Test
-    public void test08() {
-        doTest("foo%21", StandardCharsets.UTF_8, "foo!");
-    }
-
-
-    private void doTest(String input, Charset charset, String expected) {
-        String result = ApplicationPushBuilder.decode(input, charset);
-        Assert.assertEquals(expected, result);
-    }
-}
diff --git a/test/org/apache/catalina/filters/TesterHttpServletRequest.java 
b/test/org/apache/catalina/filters/TesterHttpServletRequest.java
index 449963e6ec..e03737b83a 100644
--- a/test/org/apache/catalina/filters/TesterHttpServletRequest.java
+++ b/test/org/apache/catalina/filters/TesterHttpServletRequest.java
@@ -45,7 +45,6 @@ import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpSession;
 import jakarta.servlet.http.HttpUpgradeHandler;
 import jakarta.servlet.http.Part;
-import jakarta.servlet.http.PushBuilder;
 
 public class TesterHttpServletRequest implements HttpServletRequest {
 
@@ -431,11 +430,6 @@ public class TesterHttpServletRequest implements 
HttpServletRequest {
         throw new RuntimeException("Not implemented");
     }
 
-    @Override
-    public PushBuilder newPushBuilder() {
-        throw new RuntimeException("Not implemented");
-    }
-
     @Override
     public boolean isTrailerFieldsReady() {
         throw new RuntimeException("Not implemented");
diff --git a/test/org/apache/coyote/http2/TestHttp2Section_6_6.java 
b/test/org/apache/coyote/http2/TestHttp2Section_6_6.java
deleted file mode 100644
index ae61fd31f1..0000000000
--- a/test/org/apache/coyote/http2/TestHttp2Section_6_6.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- *  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 jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServlet;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.servlet.http.PushBuilder;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import org.apache.catalina.Context;
-import org.apache.catalina.LifecycleException;
-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();
-        // stream 3 response headers
-        parser.readFrame();
-        // stream 3 response body
-        parser.readFrame();
-        // stream 2 response headers
-        parser.readFrame();
-        // stream 2 response body
-        parser.readFrame();
-
-        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 {
-            PushBuilder pb = 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);
-            }
-        }
-    }
-}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 0addab5e1f..9b1c426bfd 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -165,6 +165,11 @@
         for the Servlet 6.1 specification. It will be replaced in a future
         Tomcat 11 milestone with support for 103 early hints. (markt)
       </update>
+      <update>
+        Remove support for HTTP/2 server push. Calls to
+        <code>newPushBuilder()</code> will always return <code>null</code>.
+        (markt)
+      </update>
     </changelog>
   </subsection>
   <subsection name="Jasper">
diff --git a/webapps/examples/WEB-INF/classes/http2/SimpleImagePush.java 
b/webapps/examples/WEB-INF/classes/http2/SimpleImagePush.java
deleted file mode 100644
index 3da6895904..0000000000
--- a/webapps/examples/WEB-INF/classes/http2/SimpleImagePush.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  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 http2;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServlet;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.servlet.http.PushBuilder;
-
-public class SimpleImagePush extends HttpServlet {
-
-    private static final long serialVersionUID = 1L;
-
-    @Override
-    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
-            throws ServletException, IOException {
-
-        resp.setCharacterEncoding("UTF-8");
-        resp.setContentType("text/html");
-        PrintWriter pw = resp.getWriter();
-
-        PushBuilder pb = req.newPushBuilder();
-        if (pb != null) {
-            pb.path("servlets/images/code.gif");
-            pb.push();
-            pw.println("<html>");
-            pw.println("<body>");
-            pw.println("<p>The following image was provided via a push 
request.</p>");
-            pw.println("<img src=\"" + getServletContext().getContextPath() + 
"/servlets/images/code.gif\"/>");
-            pw.println("</body>");
-            pw.println("</html>");
-            pw.flush();
-        } else {
-            pw.println("<html>");
-            pw.println("<body>");
-            pw.println("<p>Server push requests are not supported by this 
protocol.</p>");
-            pw.println("</body>");
-            pw.println("</html>");
-        }
-    }
-}
diff --git a/webapps/examples/WEB-INF/web.xml b/webapps/examples/WEB-INF/web.xml
index 12d865ef2d..442aa032e8 100644
--- a/webapps/examples/WEB-INF/web.xml
+++ b/webapps/examples/WEB-INF/web.xml
@@ -383,16 +383,6 @@
       <url-pattern>/servlets/nonblocking/numberwriter</url-pattern>
     </servlet-mapping>
 
-    <!-- Server Push examples -->
-    <servlet>
-      <servlet-name>simpleimagepush</servlet-name>
-      <servlet-class>http2.SimpleImagePush</servlet-class>
-    </servlet>
-    <servlet-mapping>
-      <servlet-name>simpleimagepush</servlet-name>
-      <url-pattern>/servlets/serverpush/simpleimage</url-pattern>
-    </servlet-mapping>
-
     <!-- Trailer examples -->
     <servlet>
       <servlet-name>responsetrailer</servlet-name>
diff --git a/webapps/examples/servlets/index.html 
b/webapps/examples/servlets/index.html
index d07a277e9c..5a36096d17 100644
--- a/webapps/examples/servlets/index.html
+++ b/webapps/examples/servlets/index.html
@@ -165,17 +165,6 @@ for clarity.</p>
   <td style="width: 30%;"></td>
 </tr>
 
-<tr>
-  <th colspan="3">Servlet 4.0 Server Push examples</th>
-</tr>
-<tr>
-  <td>Simple image push</td>
-  <td style="width: 30%;">
-    <a href="serverpush/simpleimage"><img src="images/execute.gif" alt=""> 
Execute</a>
-  </td>
-  <td style="width: 30%;"></td>
-</tr>
-
 <tr>
   <th colspan="3">Servlet 4.0 Trailer Field examples</th>
 </tr>


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


Reply via email to