diff --git a/runtime/runtime_impl_jetty9/src/main/java/com/google/apphosting/runtime/jetty9/JettyHttpProxy.java b/runtime/runtime_impl_jetty9/src/main/java/com/google/apphosting/runtime/jetty9/JettyHttpProxy.java index 226bd7a27..02ec8cd34 100644 --- a/runtime/runtime_impl_jetty9/src/main/java/com/google/apphosting/runtime/jetty9/JettyHttpProxy.java +++ b/runtime/runtime_impl_jetty9/src/main/java/com/google/apphosting/runtime/jetty9/JettyHttpProxy.java @@ -16,6 +16,7 @@ package com.google.apphosting.runtime.jetty9; +import static com.google.apphosting.runtime.AppEngineConstants.HTTP_CONNECTOR_MODE; import static com.google.apphosting.runtime.AppEngineConstants.LEGACY_MODE; import com.google.apphosting.base.protos.AppLogsPb; @@ -35,9 +36,11 @@ import java.util.logging.Level; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.CookieCompliance; import org.eclipse.jetty.http.HttpCompliance; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.MultiPartFormDataCompliance; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; @@ -94,8 +97,7 @@ public static ServerConnector newConnector( connector.setPort(runtimeOptions.jettyHttpAddress().getPort()); HttpConnectionFactory factory = connector.getConnectionFactory(HttpConnectionFactory.class); - factory.setHttpCompliance( - LEGACY_MODE ? HttpCompliance.RFC7230_LEGACY : HttpCompliance.RFC7230); + factory.setHttpCompliance(LEGACY_MODE ? HttpCompliance.RFC7230_LEGACY : HttpCompliance.RFC7230); HttpConfiguration config = factory.getHttpConfiguration(); config.setRequestHeaderSize(runtimeOptions.jettyRequestHeaderSize()); @@ -104,6 +106,12 @@ public static ServerConnector newConnector( config.setSendServerVersion(false); config.setSendXPoweredBy(false); + if (LEGACY_MODE && Boolean.getBoolean(HTTP_CONNECTOR_MODE)) { + config.setRequestCookieCompliance(CookieCompliance.RFC2965); + config.setResponseCookieCompliance(CookieCompliance.RFC2965); + config.setMultiPartFormDataCompliance(MultiPartFormDataCompliance.LEGACY); + } + return connector; } diff --git a/runtime/test/src/test/java/com/google/apphosting/runtime/jetty9/CookieComplianceTest.java b/runtime/test/src/test/java/com/google/apphosting/runtime/jetty9/CookieComplianceTest.java index 66a771047..e432316cf 100644 --- a/runtime/test/src/test/java/com/google/apphosting/runtime/jetty9/CookieComplianceTest.java +++ b/runtime/test/src/test/java/com/google/apphosting/runtime/jetty9/CookieComplianceTest.java @@ -17,7 +17,9 @@ package com.google.apphosting.runtime.jetty9; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assume.assumeTrue; +import java.util.List; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; @@ -28,28 +30,40 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.runners.Parameterized; -@RunWith(JUnit4.class) +@RunWith(Parameterized.class) public class CookieComplianceTest extends JavaRuntimeViaHttpBase { - // This is set in the app appengine-web.xml file + // This is set in the app appengine-web.xml file. static { System.setProperty("com.google.apphosting.runtime.jetty94.LEGACY_MODE", "true"); } - public CookieComplianceTest() { - //Test also running in google3, so we limit to jetty 9.4 for now. - // TODO(ludo): Enable for other versions once we remove internal jetty94 dependency. - // TODO(ludo): http connector true: fails, but http connector false: pass - super("java17", "9.4", "EE6", false); + @Parameterized.Parameters + public static List version() { + return allVersions(); + } + + public CookieComplianceTest(String runtimeVersion, String jettyVersion, String version, boolean useHttpConnector) { + super(runtimeVersion, jettyVersion, version, useHttpConnector); } @Rule public TemporaryFolder temp = new TemporaryFolder(); @Before public void copyAppToTemp() throws Exception { - copyAppToDir("cookiecomplianceapp", temp.getRoot().toPath()); + // Internal testing is limited to Jetty 9.4 EE6 for now. + boolean internal = Boolean.getBoolean("test.running.internally"); + assumeTrue(!internal || "EE6".equals(jakartaVersion)); + + String app = "com/google/apphosting/runtime/jetty9/cookiecomplianceapp/"; + if (isJakarta()) { + app = app + "jakarta"; + } else { + app = app + "javax"; + } + copyAppToDir(app, temp.getRoot().toPath()); } @Test diff --git a/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/JakartaCookieTestServlet.java b/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/JakartaCookieTestServlet.java new file mode 100644 index 000000000..35abba62a --- /dev/null +++ b/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/JakartaCookieTestServlet.java @@ -0,0 +1,37 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed 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 + * + * https://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 com.google.apphosting.runtime.jetty9.cookiecomplianceapp; + +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +/** This servlet sets a cookie which is illegal to be set under the rules of RFC6265. */ +@WebServlet(urlPatterns = "/*") +public class JakartaCookieTestServlet extends HttpServlet { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + PrintWriter writer = resp.getWriter(); + resp.setContentType("text/plain"); + writer.print("cookieTestServletContent"); + resp.addCookie(new Cookie("invalidRFC6265Cookie", "value\"1234")); + } +} diff --git a/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/CookieTestServlet.java b/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/JavaxCookieTestServlet.java similarity index 95% rename from runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/CookieTestServlet.java rename to runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/JavaxCookieTestServlet.java index 78249fbe3..6a3d03c0c 100644 --- a/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/CookieTestServlet.java +++ b/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/JavaxCookieTestServlet.java @@ -26,7 +26,7 @@ /** This servlet sets a cookie which is illegal to be set under the rules of RFC6265. */ @WebServlet(urlPatterns = "/*") -public class CookieTestServlet extends HttpServlet { +public class JavaxCookieTestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { PrintWriter writer = resp.getWriter(); diff --git a/runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/WEB-INF/appengine-web.xml b/runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/jakarta/WEB-INF/appengine-web.xml similarity index 100% rename from runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/WEB-INF/appengine-web.xml rename to runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/jakarta/WEB-INF/appengine-web.xml diff --git a/runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/jakarta/WEB-INF/web.xml b/runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/jakarta/WEB-INF/web.xml new file mode 100644 index 000000000..36da38641 --- /dev/null +++ b/runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/jakarta/WEB-INF/web.xml @@ -0,0 +1,29 @@ + + + + + + CookieTestServlet + com.google.apphosting.runtime.jetty9.cookiecomplianceapp.JakartaCookieTestServlet + + + CookieTestServlet + /* + + diff --git a/runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/javax/WEB-INF/appengine-web.xml b/runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/javax/WEB-INF/appengine-web.xml new file mode 100644 index 000000000..e1d843ba5 --- /dev/null +++ b/runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/javax/WEB-INF/appengine-web.xml @@ -0,0 +1,25 @@ + + + + + java17 + cookiecomplianceapp + 1 + + + + diff --git a/runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/WEB-INF/web.xml b/runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/javax/WEB-INF/web.xml similarity index 95% rename from runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/WEB-INF/web.xml rename to runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/javax/WEB-INF/web.xml index 6e7bdc975..d63f2957d 100644 --- a/runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/WEB-INF/web.xml +++ b/runtime/testapps/src/main/resources/com/google/apphosting/runtime/jetty9/cookiecomplianceapp/javax/WEB-INF/web.xml @@ -20,7 +20,7 @@ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"> CookieTestServlet - com.google.apphosting.runtime.jetty9.cookiecomplianceapp.CookieTestServlet + com.google.apphosting.runtime.jetty9.cookiecomplianceapp.JavaxCookieTestServlet CookieTestServlet