This is an automated email from the ASF dual-hosted git repository. rzo1 pushed a commit to branch TOMEE-4707 in repository https://gitbox.apache.org/repos/asf/tomee.git
commit af063822e2e9e515bf14feb6a3da7c931d20f11c Author: Richard Zowalla <[email protected]> AuthorDate: Sun Sep 20 21:22:58 2026 +0200 TOMEE-4707 drop the standalone HTTP server from openejb-http TomEE serves requests through Tomcat's connectors, so the hand written HTTP server in openejb-http is unused attack surface. Removes it, the unreachable Jetty backend, the httpejbd service and OpenEJBHttpRegistry. isTextXml and reformat move to HttpUtil. RsRegistryImpl and OpenEJBHttpWsRegistry extended OpenEJBHttpRegistry and were the non-Tomcat fallbacks in RESTService and WsService; both go, so openejb-standalone and arquillian-openejb-embedded lose embedded REST/WS wiring. Everything Tomcat needs stays: listeners, the registry, request, response and session, the servlet and filter adapters, ServerServlet and the CDI listeners. The tests that drove the removed transport over a socket go with it. --- server/openejb-http/pom.xml | 16 - .../apache/openejb/server/httpd/HttpEjbServer.java | 95 ------ .../openejb/server/httpd/HttpRequestImpl.java | 5 +- .../openejb/server/httpd/HttpResponseImpl.java | 5 +- .../apache/openejb/server/httpd/HttpServer.java | 24 -- .../openejb/server/httpd/HttpServerFactory.java | 36 --- .../openejb/server/httpd/JettyHttpEjbServer.java | 31 -- .../openejb/server/httpd/JettyHttpServer.java | 134 -------- .../LightweightWebAppBuilderListenerExtractor.java | 2 - .../openejb/server/httpd/OpenEJBHttpEjbServer.java | 29 -- .../openejb/server/httpd/OpenEJBHttpRegistry.java | 181 ----------- .../openejb/server/httpd/OpenEJBHttpServer.java | 359 --------------------- .../openejb/server/httpd/ServerServiceAdapter.java | 36 --- .../server/httpd/ServletIntputStreamAdapter.java | 54 ---- .../server/httpd/ServletOutputStreamAdapter.java | 45 --- .../apache/openejb/server/httpd/util/HttpUtil.java | 42 +++ .../httpejbd | 11 - .../apache/openejb/server/httpd/AsyncHttpTest.java | 171 ---------- .../openejb/server/httpd/CustomHttpMethodTest.java | 79 ----- .../server/httpd/FilterRegistrationTest.java | 145 --------- .../openejb/server/httpd/HttpEjbServerTest.java | 130 -------- .../server/httpd/HttpResponseImplSessionTest.java | 144 --------- .../org/apache/openejb/server/httpd/JettyTest.java | 79 ----- .../server/httpd/OpenEJBHttpServerTest.java | 119 ------- .../apache/openejb/server/httpd/ResourcesTest.java | 76 ----- .../server/httpd/ServletRegistrationTest.java | 127 -------- .../apache/openejb/server/rest/RESTService.java | 3 - .../apache/openejb/server/rest/RsRegistryImpl.java | 61 ---- .../server/rest/RsRegistryImplAuthTest.java | 43 --- .../server/webservices/OpenEJBHttpWsRegistry.java | 95 ------ .../openejb/server/webservices/WsService.java | 3 - .../webservices/OpenEJBHttpWsRegistryAuthTest.java | 43 --- 32 files changed, 48 insertions(+), 2375 deletions(-) diff --git a/server/openejb-http/pom.xml b/server/openejb-http/pom.xml index 6a97459713..943f9dfa3e 100644 --- a/server/openejb-http/pom.xml +++ b/server/openejb-http/pom.xml @@ -35,10 +35,6 @@ <properties> <tomee.build.name>${project.groupId}.server.http</tomee.build.name> - <openejb.osgi.import.pkg> - org.eclipse.jetty*;resolution:=optional, - * - </openejb.osgi.import.pkg> </properties> <build> @@ -134,18 +130,6 @@ <artifactId>openejb-ejbd</artifactId> <version>${project.version}</version> </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-server</artifactId> - <version>${version.jetty}</version> - <optional>true</optional> - </dependency> - <dependency> - <groupId>org.eclipse.jetty.ee11</groupId> - <artifactId>jetty-ee11-servlet</artifactId> - <version>${version.jetty}</version> - <optional>true</optional> - </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>openejb-itests-client</artifactId> diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpEjbServer.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpEjbServer.java deleted file mode 100644 index 2ab8a69f8a..0000000000 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpEjbServer.java +++ /dev/null @@ -1,95 +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.openejb.server.httpd; - -import org.apache.openejb.loader.SystemInstance; -import org.apache.openejb.server.ServerService; -import org.apache.openejb.server.ServiceException; -import org.apache.openejb.server.ejbd.EjbServer; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.util.Properties; - -/** - * @version $Revision$ $Date$ - */ -public abstract class HttpEjbServer implements ServerService { - - protected HttpServer httpServer; - private String name; - - @Override - public void init(final Properties props) throws Exception { - name = props.getProperty("name"); - final EjbServer ejbServer = new EjbServer(); - final ServerServiceAdapter adapter = new ServerServiceAdapter(ejbServer); - - final SystemInstance systemInstance = SystemInstance.get(); - HttpListenerRegistry registry = systemInstance.getComponent(HttpListenerRegistry.class); - if (registry == null) { - registry = new HttpListenerRegistry(); - systemInstance.setComponent(HttpListenerRegistry.class, registry); - } - - registry.addHttpListener(adapter, "/ejb/?.*"); - - // register the http server - systemInstance.setComponent(HttpServer.class, httpServer); - - httpServer.init(props); - ejbServer.init(props); - } - - @Override - public void service(final Socket socket) throws ServiceException, IOException { - httpServer.service(socket); - } - - @Override - public void service(final InputStream in, final OutputStream out) throws ServiceException, IOException { - httpServer.service(in, out); - } - - @Override - public void start() throws ServiceException { - httpServer.start(); - } - - @Override - public void stop() throws ServiceException { - httpServer.stop(); - } - - @Override - public String getName() { - return name; - } - - @Override - public int getPort() { - return httpServer.getPort(); - } - - @Override - public String getIP() { - return httpServer.getIP(); - } -} diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java index d73c2de1d6..4f98f48949 100644 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java +++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java @@ -28,6 +28,7 @@ import org.apache.openejb.spi.SecurityService; import org.apache.openejb.util.AppFinder; import org.apache.openejb.util.ArrayEnumeration; import org.apache.openejb.util.Logger; +import org.apache.openejb.server.httpd.util.HttpUtil; import org.apache.webbeans.config.WebBeansContext; import java.io.BufferedReader; @@ -447,8 +448,8 @@ public class HttpRequestImpl implements HttpRequest { builder.append("\n"); final String text = new String(body); - if (formatXml && OpenEJBHttpServer.isTextXml(headers)) { - builder.append(OpenEJBHttpServer.reformat(text)).append("\n"); + if (formatXml && HttpUtil.isTextXml(headers)) { + builder.append(HttpUtil.reformat(text)).append("\n"); } else { builder.append(text).append("\n"); } diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpResponseImpl.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpResponseImpl.java index bd0c708ad3..f9356c39cd 100644 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpResponseImpl.java +++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpResponseImpl.java @@ -21,6 +21,7 @@ import org.apache.openejb.server.httpd.session.SessionManager; import org.apache.openejb.util.LogCategory; import org.apache.openejb.util.Logger; import org.apache.openejb.util.OpenEjbVersion; +import org.apache.openejb.server.httpd.util.HttpUtil; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.Cookie; @@ -537,9 +538,9 @@ public class HttpResponseImpl implements HttpResponse { private void writeBody(final DataOutput out, final boolean indent) throws IOException { out.writeBytes(CRLF); if (content == null) { - if (indent && OpenEJBHttpServer.isTextXml(headers)) { + if (indent && HttpUtil.isTextXml(headers)) { final String xml = new String(sosi.getOutputStream().toByteArray()); - out.write(OpenEJBHttpServer.reformat(xml).getBytes()); + out.write(HttpUtil.reformat(xml).getBytes()); } else { out.write(sosi.getOutputStream().toByteArray()); } diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpServer.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpServer.java deleted file mode 100644 index e3317ef782..0000000000 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpServer.java +++ /dev/null @@ -1,24 +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.openejb.server.httpd; - -import org.apache.openejb.server.ServerService; - -public interface HttpServer extends ServerService { - HttpListener getListener(); -} diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpServerFactory.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpServerFactory.java deleted file mode 100644 index cd747092e7..0000000000 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpServerFactory.java +++ /dev/null @@ -1,36 +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.openejb.server.httpd; - -import org.apache.openejb.server.ServerService; -import org.apache.xbean.recipe.ParameterNames; - -public class HttpServerFactory { - @ParameterNames("useJetty") - public static ServerService createServerService(final boolean useJetty) { - if (useJetty) { - try { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - cl.loadClass("org.mortbay.jetty.Connector"); - return new JettyHttpEjbServer(); - } catch (Throwable e) { - // We don't have jetty - } - } - return new OpenEJBHttpEjbServer(); - } -} diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/JettyHttpEjbServer.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/JettyHttpEjbServer.java deleted file mode 100644 index 61cb7fa141..0000000000 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/JettyHttpEjbServer.java +++ /dev/null @@ -1,31 +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.openejb.server.httpd; - -import org.apache.openejb.server.SelfManaging; - -/** - * @version $Rev: 607077 $ $Date: 2007-12-27 15:55:23 +0100 (Thu, 27 Dec 2007) $ - */ -public class JettyHttpEjbServer extends HttpEjbServer implements SelfManaging { - - public JettyHttpEjbServer() { - super(); - httpServer = new JettyHttpServer(); - } - -} \ No newline at end of file diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/JettyHttpServer.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/JettyHttpServer.java deleted file mode 100644 index 0ef1ffec91..0000000000 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/JettyHttpServer.java +++ /dev/null @@ -1,134 +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.openejb.server.httpd; - -import org.apache.openejb.loader.Options; -import org.apache.openejb.server.ServiceException; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.ee11.servlet.ServletContextHandler; - -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.util.Properties; - -/** - * Jetty based http server implementation - */ -public class JettyHttpServer implements HttpServer { - - private final HttpListener listener; - private Server server; - private int port; - - public JettyHttpServer() { - this(OpenEJBHttpServer.getHttpListenerRegistry()); - } - - public JettyHttpServer(final HttpListener listener) { - this.listener = listener; - } - - @Override - public HttpListener getListener() { - return listener; - } - - @Override - public void service(final Socket socket) throws ServiceException, IOException { - throw new UnsupportedOperationException(); - } - - @Override - public void service(final InputStream in, final OutputStream out) throws ServiceException, IOException { - throw new UnsupportedOperationException(); - } - - @Override - public String getName() { - return "jetty"; - } - - @Override - public int getPort() { - return port; - } - - @Override - public String getIP() { - return "0.0.0.0"; - } - - @Override - public void init(final Properties props) throws Exception { - final Options options = new Options(props); - - port = options.get("port", 8080); - - // Create all the Jetty objects but dont' start them - server = new Server(); - final ServerConnector connector = new ServerConnector(server); - connector.setPort(port); - server.setConnectors(new Connector[]{connector}); - - final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); - context.setContextPath("/"); - final ServletContext servletContext = context.getServletContext(); - server.setHandler(context); - - context.addServlet(new HttpServlet() { - @Override - protected void service(final HttpServletRequest req, final HttpServletResponse res) throws IOException, ServletException { - try { - final HttpRequest httpRequest = new ServletRequestAdapter(req, res, servletContext); - final HttpResponse httpResponse = new ServletResponseAdapter(res); - JettyHttpServer.this.listener.onMessage(httpRequest, httpResponse); - } catch (IOException | ServletException e) { - throw e; - } catch (Exception e) { - throw new ServletException(e); - } - } - }, "/*"); - } - - @Override - public void start() throws ServiceException { - try { - server.join(); - } catch (Exception e) { - throw new ServiceException(e); - } - } - - @Override - public void stop() throws ServiceException { - try { - server.destroy(); - } catch (Exception e) { - throw new ServiceException(e); - } - } -} diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/LightweightWebAppBuilderListenerExtractor.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/LightweightWebAppBuilderListenerExtractor.java index 5dddd47f28..f6290ee83e 100644 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/LightweightWebAppBuilderListenerExtractor.java +++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/LightweightWebAppBuilderListenerExtractor.java @@ -27,8 +27,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -// could be optimized since we could bind to the request the listeners in org.apache.openejb.server.httpd.OpenEJBHttpRegistry.ClassLoaderHttpListener.onMessage() -// but ok for now since that's fully for the embedded mode public final class LightweightWebAppBuilderListenerExtractor { public static <T> Collection<T> findByTypeForContext(final String context, final Class<T> type) { final WebAppBuilder builder = SystemInstance.get().getComponent(WebAppBuilder.class); diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpEjbServer.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpEjbServer.java deleted file mode 100644 index cc6d930ee5..0000000000 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpEjbServer.java +++ /dev/null @@ -1,29 +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.openejb.server.httpd; - -/** - * @version $Rev: 607077 $ $Date: 2007-12-27 15:55:23 +0100 (Thu, 27 Dec 2007) $ - */ -public class OpenEJBHttpEjbServer extends HttpEjbServer { - - public OpenEJBHttpEjbServer() { - super(); - httpServer = new OpenEJBHttpServer(); - } - -} diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java deleted file mode 100644 index 830b4a9186..0000000000 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java +++ /dev/null @@ -1,181 +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.openejb.server.httpd; - -import org.apache.openejb.AppContext; -import org.apache.openejb.assembler.classic.OpenEjbConfiguration; -import org.apache.openejb.assembler.classic.ServiceInfo; -import org.apache.openejb.core.WebContext; -import org.apache.openejb.loader.SystemInstance; -import org.apache.openejb.spi.ContainerSystem; -import org.apache.openejb.util.LogCategory; -import org.apache.openejb.util.Logger; -import org.apache.openejb.util.PropertyPlaceHolderHelper; -import org.apache.webbeans.config.WebBeansContext; - -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.List; - -public class OpenEJBHttpRegistry { - public static final Logger log = Logger.getInstance(LogCategory.HTTPSERVER, OpenEJBHttpRegistry.class); - - protected final HttpListenerRegistry registry; - protected final List<URI> baseUris = new ArrayList<>(); - - public OpenEJBHttpRegistry() { - try { - OpenEjbConfiguration configuration = SystemInstance.get().getComponent(OpenEjbConfiguration.class); - for (ServiceInfo service : configuration.facilities.services) { - if (service.className.equals(HttpServerFactory.class.getName())) { - int port = Integer.parseInt(PropertyPlaceHolderHelper.simpleValue(service.properties.getProperty("port"))); - String ip = service.properties.getProperty("bind"); - if ("0.0.0.0".equals(ip)) { - InetAddress[] addresses = InetAddress.getAllByName(ip); - for (InetAddress address : addresses) { - baseUris.add(new URI("http", null, address.getHostAddress(), port, null, null, null)); - } - } else { - baseUris.add(new URI("http", null, ip, port, null, null, null)); - } - break; - } - } - } catch (Exception e) { - log.error("Unable to build base URIs for " + getClass().getSimpleName() + " registry", e); - } - registry = SystemInstance.get().getComponent(HttpListenerRegistry.class); - } - - public HttpListener addWrappedHttpListener(HttpListener httpListener, ClassLoader classLoader, String regex) { - HttpListener listener = new ClassLoaderHttpListener(httpListener, classLoader); - registry.addHttpListener(listener, regex); - return listener; - } - - public List<String> getResolvedAddresses(String path) { - String suffix = path; - if (!path.startsWith("/")) { - suffix = '/' + suffix; - } - - List<String> addresses = new ArrayList<>(); - for (final URI baseUri : baseUris) { - URI uri = baseUri; - if (baseUri.getPort() == 0) { // if port was set to 0 we need to get httpejbd service port which was updated in SystemInstance - final int port = Integer.parseInt(SystemInstance.get().getProperty("httpejbd.port", "0")); - if (port != 0) { - try { - uri = new URI(baseUri.getScheme(), baseUri.getUserInfo(), baseUri.getHost(), port, baseUri.getPath(), baseUri.getQuery(), baseUri.getFragment()); - } catch (final URISyntaxException e) { - // no-op - } - } - } - final URI address = uri.resolve(suffix); - addresses.add(address.toString()); - } - return addresses; - } - - protected static class ClassLoaderHttpListener implements HttpListener { - private final HttpListener delegate; - private final ClassLoader classLoader; - - protected ClassLoaderHttpListener(HttpListener delegate, ClassLoader classLoader) { - this.delegate = delegate; - this.classLoader = classLoader; - } - - public void onMessage(HttpRequest request, HttpResponse response) throws Exception { - final Thread thread = Thread.currentThread(); - final ClassLoader oldCl = thread.getContextClassLoader(); - - WebBeansContext wbc = null; - try { - if (request instanceof HttpRequestImpl) { - final HttpRequestImpl httpRequest = HttpRequestImpl.class.cast(request); - final WebContext web = findWebContext(request.getURI() == null ? request.getContextPath() : request.getURI().getPath()); - if (web != null) { - httpRequest.setApplication(web); - - if (web.getClassLoader() != null) { - thread.setContextClassLoader(web.getClassLoader()); - } else if (web.getAppContext().getClassLoader() != null) { - thread.setContextClassLoader(web.getAppContext().getClassLoader()); - } - - final String ctx = (web.getContextRoot().startsWith("/") ? "" : "/") + web.getContextRoot(); - httpRequest.initPathFromContext(ctx); - wbc = web.getWebbeansContext() != null ? web.getWebbeansContext() : web.getAppContext().getWebBeansContext(); - } else { - thread.setContextClassLoader(classLoader); - - if (SystemInstance.isInitialized()) { // avoid to rely on default if we didnt init it and then create lazily a context - try { // surely an issue or something just tolerated for fake webapps - wbc = WebBeansContext.currentInstance(); - } catch (final IllegalStateException ise) { - // no-op - } - } - } - if (wbc != null) { - httpRequest.setAttribute("openejb_owb_context", wbc); - initCdi(wbc, httpRequest).init(); - } - } - - delegate.onMessage(request, response); - } finally { - if (wbc != null) { - HttpRequestImpl.class.cast(request).destroy(); - } - - thread.setContextClassLoader(oldCl); - } - } - - private static WebContext findWebContext(final String path) { // TODO: this is a poor impl, would need registration of app etc to be better and have a rooter - for (final AppContext app : SystemInstance.get().getComponent(ContainerSystem.class).getAppContexts()) { - for (final WebContext web : app.getWebContexts()) { - if (path.startsWith(web.getContextRoot()) || path.startsWith('/' + web.getContextRoot())) { - return web; - } - } - } - return null; - } - - private static HttpRequestImpl initCdi(final WebBeansContext context, final HttpRequestImpl request) { - try { - if (context.getBeanManagerImpl().isInUse()) { - request.setBeginListener(new BeginWebBeansListener(context)); - request.setEndListener(new EndWebBeansListener(context)); - } - } catch (IllegalStateException ise) { - // no-op: ignore - } - return request; - } - - public HttpListener getDelegate() { - return delegate; - } - } -} diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpServer.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpServer.java deleted file mode 100644 index 1cf463852f..0000000000 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpServer.java +++ /dev/null @@ -1,359 +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.openejb.server.httpd; - -import org.apache.openejb.OpenEJBException; -import org.apache.openejb.core.ParentClassLoaderFinder; -import org.apache.openejb.loader.Options; -import org.apache.openejb.loader.SystemInstance; -import org.apache.openejb.server.ServiceException; -import org.apache.openejb.server.context.RequestInfos; -import org.apache.openejb.server.httpd.session.SessionManager; -import org.apache.openejb.server.stream.CountingInputStream; -import org.apache.openejb.server.stream.CountingOutputStream; -import org.apache.openejb.spi.SecurityService; -import org.apache.openejb.util.LogCategory; -import org.apache.openejb.util.Logger; -import org.apache.openejb.util.OptionsLog; - -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.StringReader; -import java.io.StringWriter; -import java.net.Socket; -import java.net.SocketException; -import java.net.URI; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -/** - * This is the main class for the web administration. It takes care of the - * processing from the browser, sockets and threading. - * - * @since 11/25/2001 - */ -public class OpenEJBHttpServer implements HttpServer { - - private static final Logger log = Logger.getInstance(LogCategory.HTTPSERVER, "org.apache.openejb.util.resources"); - - private HttpListener listener; - private Set<Output> print; - private boolean indent; - private boolean countStreams; - - public OpenEJBHttpServer() { - this(null); - } - - public static HttpListenerRegistry getHttpListenerRegistry() { - final SystemInstance systemInstance = SystemInstance.get(); - HttpListenerRegistry registry = systemInstance.getComponent(HttpListenerRegistry.class); - if (registry == null) { - registry = new HttpListenerRegistry(); - systemInstance.setComponent(HttpListenerRegistry.class, registry); - } - return registry; - } - - public OpenEJBHttpServer(final HttpListener listener) { - if (SystemInstance.get().getComponent(SessionManager.class) == null) { - SystemInstance.get().setComponent(SessionManager.class, new SessionManager()); - } - this.listener = new OpenEJBHttpRegistry.ClassLoaderHttpListener( - listener == null ? getHttpListenerRegistry() : listener, ParentClassLoaderFinder.Helper.get()); - } - - public static boolean isTextXml(final Map<String, List<String>> headers) { - final Collection<String> contentType = headers.get("Content-Type"); - if (contentType == null) { - return false; - } - for (final String current : contentType) { - if (current.contains("text/xml")) { - return true; - } - } - return false; - } - - @Override - public HttpListener getListener() { - return listener; - } - - @Override - public void service(final Socket socket) throws ServiceException, IOException { - /** - * The InputStream used to receive incoming messages from the client. - */ - InputStream in = null; - /** - * The OutputStream used to send outgoing response messages to the client. - */ - OutputStream out = null; - - boolean close = true; - try { - RequestInfos.initRequestInfo(socket); - - if (countStreams) { - in = new CountingInputStream(socket.getInputStream()); - out = new CountingOutputStream(socket.getOutputStream()); - } else { - in = socket.getInputStream(); - out = socket.getOutputStream(); - } - - //TODO: if ssl change to https - final URI socketURI = new URI("http://" + socket.getLocalAddress().getHostAddress() + ":" + socket.getLocalPort()); - close = processRequest(socket, socketURI, in, out); - - } catch (final Throwable e) { - log.error("Unexpected error", e); - } finally { - if (close) { - if (out != null) { - try { - out.flush(); - } catch (Throwable e) { - //Ignore - } - try { - out.close(); - } catch (Throwable e) { - //Ignore - } - } - - if (in != null) { - try { - in.close(); - } catch (Throwable e) { - //Ignore - } - } - - try { - socket.close(); - } catch (Throwable e) { - log.error("Encountered problem while closing connection with client: " + e.getMessage()); - } - } - } - } - - @Override - public void service(final InputStream in, final OutputStream out) throws ServiceException, IOException { - throw new UnsupportedOperationException("Method not implemented: service(InputStream in, OutputStream out)"); - } - - @Override - public void init(final Properties props) throws Exception { - final Options options = new Options(props); - options.setLogger(new OptionsLog(log)); - print = options.getAll("print", OpenEJBHttpServer.Output.class); - indent = print.size() > 0 && options.get("" + - "" + - ".xml", false); - countStreams = options.get("stream.count", false); - } - - public static enum Output { - REQUEST, - RESPONSE - } - - @Override - public void start() throws ServiceException { - } - - @Override - public void stop() throws ServiceException { - OpenEJBAsyncContext.destroy(); - final SessionManager component = SystemInstance.get().getComponent(SessionManager.class); - if (component != null) { - component.destroy(); - } - } - - @Override - public String getName() { - return "httpd"; - } - - @Override - public int getPort() { - return 0; - } - - @Override - public String getIP() { - return ""; - } - - /** - * takes care of processing requests and creating the webadmin ejb's - * - * @param in the input stream from the browser - * @param out the output stream to the browser - */ - private boolean processRequest(final Socket socket, final URI socketURI, final InputStream in, final OutputStream out) { - HttpResponseImpl response = null; - try { - response = process(socket, socketURI, in); - return response != null; - } catch (final Throwable t) { - log.error(t.getMessage(), t); - response = HttpResponseImpl.createError(t.getMessage(), t); - return true; - } finally { - try { - if (response != null) { - response.writeMessage(out, false); - if (print.size() > 0 && print.contains(Output.RESPONSE)) { - response.writeMessage(new LoggerOutputStream(log, "debug"), indent); - } - } - } catch (final Throwable t2) { - - if (log.isDebugEnabled()) { - log.debug("Could not write response", t2); - } else { - //SocketException is something a client can cause, so do not log it (potential DOS) - if (!SocketException.class.isInstance(t2)) { - log.warning("Could not write response:" + t2); - } - } - - } - } - } - - private HttpResponseImpl process(final Socket socket, final URI socketURI, final InputStream in) throws OpenEJBException { - final HttpRequestImpl req = new HttpRequestImpl(socketURI); - final HttpResponseImpl res = new HttpResponseImpl(); - - try { - if (!req.readMessage(in)) { - return res; - } - - if (print.size() > 0 && print.contains(Output.REQUEST)) { - req.print(log, indent); - } - - res.setRequest(req); - } catch (Throwable t) { - res.setCode(400); - res.setResponseString("Could not read the request"); - try { - res.getWriter().println("Bad request"); - } catch (IOException e) { - // no-op - } - log.error("BAD REQUEST", t); - throw new OpenEJBException("Could not read the request.\n" + t.getClass().getName() + ":\n" + t.getMessage(), t); - } - - final URI uri; - String location = null; - try { - uri = req.getURI(); - location = uri.getPath(); - final int querry = location.indexOf("?"); - if (querry != -1) { - location = location.substring(0, querry); - } - } catch (Throwable t) { - throw new OpenEJBException("Could not determine the module " + location + "\n" + t.getClass().getName() + ":\n" + t.getMessage()); - } - - try { - req.setAttribute("openejb_response", res); - req.setAttribute("openejb_socket", socket); - listener.onMessage(req, res); - } catch (Throwable t) { - throw new OpenEJBException("Error occurred while executing the module " + location + "\n" + t.getClass().getName() + ":\n" + t.getMessage(), t); - } finally { - // the request thread is pooled, reset any security association made during the request - final SecurityService securityService = SystemInstance.get().getComponent(SecurityService.class); - if (securityService != null) { - securityService.disassociate(); - } - } - - final boolean async = "true".equals(req.getAttribute("openejb_async")); - return !async ? res : null; - } - - public static String reformat(final String raw) { - if (raw.length() == 0) { - return raw; - } - - try { - final TransformerFactory factory = TransformerFactory.newInstance(); - // bugged in some XML implementation - // should we use another implementation? - //factory.setAttribute("indent-number", 2); - - final Transformer transformer = factory.newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); - - final StreamResult result = new StreamResult(new StringWriter()); - - transformer.transform(new StreamSource(new StringReader(raw)), result); - - return result.getWriter().toString(); - } catch (TransformerException e) { - e.printStackTrace(); - return raw; - } - } - - private static class LoggerOutputStream extends OutputStream { - - private final Logger logger; - private final String level; - - public LoggerOutputStream(final Logger log, final String lvl) { - logger = log; - level = lvl; - } - - @Override - public void write(final int b) throws IOException { - logger.log(level, Character.toString((char) b)); - } - - @Override // shortcut for String - because we know what we have ;) - public void write(final byte[] b) throws IOException { - logger.log(level, new String(b)); - } - } -} diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServerServiceAdapter.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServerServiceAdapter.java deleted file mode 100644 index 3bf49eaf9f..0000000000 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServerServiceAdapter.java +++ /dev/null @@ -1,36 +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.openejb.server.httpd; - -import org.apache.openejb.server.ServerService; - -/** - * @version $Revision$ $Date$ - */ -public class ServerServiceAdapter implements HttpListener { - - private final ServerService service; - - public ServerServiceAdapter(ServerService service) { - this.service = service; - } - - public void onMessage(HttpRequest request, HttpResponse response) throws Exception { - service.service(request.getInputStream(), response.getOutputStream()); - } -} diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletIntputStreamAdapter.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletIntputStreamAdapter.java deleted file mode 100644 index 125f09c029..0000000000 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletIntputStreamAdapter.java +++ /dev/null @@ -1,54 +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.openejb.server.httpd; - -import jakarta.servlet.ReadListener; -import jakarta.servlet.ServletInputStream; - -import java.io.IOException; -import java.io.InputStream; - -public class ServletIntputStreamAdapter extends ServletInputStream { - private InputStream intputStream; - private boolean finished; - - public ServletIntputStreamAdapter(InputStream is) { - intputStream = is; - } - - @Override - public int read() throws IOException { - final int read = intputStream.read(); - finished = read == -1; - return read; - } - - @Override - public boolean isFinished() { - return finished; - } - - @Override - public boolean isReady() { - return true; - } - - @Override - public void setReadListener(final ReadListener listener) { - // no-op - } -} diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletOutputStreamAdapter.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletOutputStreamAdapter.java deleted file mode 100644 index 6b5d2c7166..0000000000 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletOutputStreamAdapter.java +++ /dev/null @@ -1,45 +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.openejb.server.httpd; - -import jakarta.servlet.ServletOutputStream; -import jakarta.servlet.WriteListener; -import java.io.IOException; -import java.io.OutputStream; - -public class ServletOutputStreamAdapter extends ServletOutputStream { - private OutputStream outputStream; - - public ServletOutputStreamAdapter(OutputStream os) { - outputStream = os; - } - - @Override - public void write(int b) throws IOException { - outputStream.write(b); - } - - @Override - public boolean isReady() { - return true; - } - - @Override - public void setWriteListener(final WriteListener listener) { - // no-op - } -} diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/util/HttpUtil.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/util/HttpUtil.java index 260347776a..950807761a 100644 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/util/HttpUtil.java +++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/util/HttpUtil.java @@ -34,12 +34,22 @@ import jakarta.servlet.ServletContext; import jakarta.servlet.ServletContextEvent; import jakarta.servlet.ServletContextListener; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import java.io.StringReader; +import java.io.StringWriter; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.List; +import java.util.Map; public final class HttpUtil { private static final String WILDCARD = SystemInstance.get().getProperty("openejb.http.wildcard", ".*"); @@ -257,4 +267,36 @@ public final class HttpUtil { } return path; } + + public static boolean isTextXml(final Map<String, List<String>> headers) { + final Collection<String> contentType = headers.get("Content-Type"); + if (contentType == null) { + return false; + } + for (final String current : contentType) { + if (current.contains("text/xml")) { + return true; + } + } + return false; + } + + public static String reformat(final String raw) { + if (raw.isEmpty()) { + return raw; + } + + try { + final TransformerFactory factory = TransformerFactory.newInstance(); + final Transformer transformer = factory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); + + final StreamResult result = new StreamResult(new StringWriter()); + transformer.transform(new StreamSource(new StringReader(raw)), result); + return result.getWriter().toString(); + } catch (final TransformerException e) { + return raw; + } + } } diff --git a/server/openejb-http/src/main/resources/META-INF/org.apache.openejb.server.ServerService/httpejbd b/server/openejb-http/src/main/resources/META-INF/org.apache.openejb.server.ServerService/httpejbd deleted file mode 100644 index 1fcdd297a7..0000000000 --- a/server/openejb-http/src/main/resources/META-INF/org.apache.openejb.server.ServerService/httpejbd +++ /dev/null @@ -1,11 +0,0 @@ -server = org.apache.openejb.server.httpd.HttpServerFactory -bind = 127.0.0.1 -port = 4204 -disabled = ${openejb.profile.custom} -threads = 200 - -# if possible use jetty -useJetty = true - -# ServicePool shouldn't force socket.close() for AsyncContext handling, HttpServer does it well already in any case -forceSocketClose = false diff --git a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/AsyncHttpTest.java b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/AsyncHttpTest.java deleted file mode 100644 index a447fe6836..0000000000 --- a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/AsyncHttpTest.java +++ /dev/null @@ -1,171 +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.openejb.server.httpd; - -import org.apache.openejb.junit.ApplicationComposerRule; -import org.apache.openejb.loader.IO; -import org.apache.openejb.testing.Classes; -import org.apache.openejb.testing.ContainerProperties; -import org.apache.openejb.testing.EnableServices; -import org.apache.openejb.testing.RandomPort; -import org.junit.Rule; -import org.junit.Test; - -import jakarta.inject.Inject; -import jakarta.servlet.AsyncContext; -import jakarta.servlet.AsyncEvent; -import jakarta.servlet.AsyncListener; -import jakarta.servlet.ServletException; -import jakarta.servlet.annotation.WebServlet; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.net.URL; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -@EnableServices("http") -@Classes(cdi = true, innerClassesAsBean = true) -@ContainerProperties(@ContainerProperties.Property(name = "httpejbd.useJetty", value = "fase")) -public class AsyncHttpTest { - @Rule - public final ApplicationComposerRule container = new ApplicationComposerRule(this); - - @RandomPort("http") - private URL context; - - @Test - public void async() throws IOException { - SimpleAsyncListener.started = false; - assertEquals("OK", IO.slurp(new URL(context.toExternalForm() + "openejb/AsyncServlet"))); - assertTrue(SimpleAsyncListener.started); - } - - @Test - public void asyncDispatch() throws IOException { - assertEquals("OK2", IO.slurp(new URL(context.toExternalForm() + "openejb/DispatchAsyncServlet"))); - } - - @WebServlet(name = "AsyncServlet", urlPatterns = "/AsyncServlet", asyncSupported = true) - public static class AsyncServlet extends HttpServlet { - private ExecutorService executorService; - - @Override - public void init() throws ServletException { - executorService = Executors.newSingleThreadExecutor(); - } - - @Override - protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { - final AsyncContext actx = req.startAsync(); - actx.addListener(actx.createListener(SimpleAsyncListener.class)); - resp.setContentType("text/plain"); - executorService.execute(new AsyncHandler(actx)); - } - - @Override - public void destroy() { - executorService.shutdownNow(); - } - } - - @WebServlet(name = "DispatchAsyncServlet", urlPatterns = "/DispatchAsyncServlet", asyncSupported = true) - public static class DispatchAsyncServlet extends HttpServlet { - private ExecutorService executorService; - - @Override - public void init() throws ServletException { - executorService = Executors.newSingleThreadExecutor(); - } - - @Override - protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { - final AsyncContext actx = req.startAsync(); - resp.setContentType("text/plain"); - actx.dispatch("/ok"); - } - - @Override - public void destroy() { - executorService.shutdownNow(); - } - } - - public static class ABean {} - - public static class SimpleAsyncListener implements AsyncListener { - private static boolean started; - - @Inject - private ABean bean; - - @Override - public void onComplete(final AsyncEvent event) throws IOException { - // no-op - } - - @Override - public void onTimeout(AsyncEvent event) throws IOException { - // no-op - } - - @Override - public void onError(AsyncEvent event) throws IOException { - // no-op - } - - @Override - public void onStartAsync(final AsyncEvent event) throws IOException { - started = bean != null; - } - } - - @WebServlet("/ok") - public static class SimpleServlet extends HttpServlet { - @Override - protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { - resp.getWriter().write("OK2"); - } - } - - private static class AsyncHandler implements Runnable { - private final AsyncContext actx; - - public AsyncHandler(final AsyncContext ctx) { - this.actx = ctx; - } - - @Override - public void run() { - try { - actx.getResponse().getWriter().write("OK"); - } catch (final IOException e) { - try { - HttpServletResponse.class.cast(actx.getResponse()).sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } catch (final IOException e1) { - // no-op - } - actx.complete(); - } - actx.complete(); - } - } -} diff --git a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/CustomHttpMethodTest.java b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/CustomHttpMethodTest.java deleted file mode 100644 index 000780395c..0000000000 --- a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/CustomHttpMethodTest.java +++ /dev/null @@ -1,79 +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.openejb.server.httpd; - -import org.apache.openejb.jee.EjbJar; -import org.apache.openejb.junit.ApplicationComposer; -import org.apache.openejb.loader.IO; -import org.apache.openejb.loader.SystemInstance; -import org.apache.openejb.testing.Configuration; -import org.apache.openejb.testing.EnableServices; -import org.apache.openejb.testing.Module; -import org.apache.openejb.testng.PropertiesBuilder; -import org.apache.openejb.util.NetworkUtil; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Properties; -import java.util.concurrent.atomic.AtomicReference; - -import static org.junit.Assert.assertEquals; - -@EnableServices({"httpejbd"}) -@RunWith(ApplicationComposer.class) -public class CustomHttpMethodTest { - private int nextAvailablePort = -1; - - @Test - public void custom() throws URISyntaxException, IOException { - final AtomicReference<String> method = new AtomicReference<String>(); - final HttpListenerRegistry registry = SystemInstance.get().getComponent(HttpListenerRegistry.class); - registry.addHttpListener(new HttpListener() { - @Override - public void onMessage(final HttpRequest request, final HttpResponse response) throws Exception { - method.set(request.getMethod()); - } - }, "/custom"); - try { - final URL url = new URL("http://localhost:" + nextAvailablePort + "/custom"); - final HttpURLConnection connection = HttpURLConnection.class.cast(url.openConnection()); - connection.setRequestMethod("OPTIONS"); - final InputStream inputStream = connection.getInputStream(); - IO.slurp(inputStream); - assertEquals("OPTIONS", method.get()); - inputStream.close(); - } finally { - registry.removeHttpListener("/custom"); - } - } - - @Configuration - public Properties props() { - nextAvailablePort = NetworkUtil.getNextAvailablePort(); - return new PropertiesBuilder().p("httpejbd.port", Integer.toString(nextAvailablePort)).build(); - } - - @Module - public EjbJar jar() { - return new EjbJar(); - } -} diff --git a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/FilterRegistrationTest.java b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/FilterRegistrationTest.java deleted file mode 100644 index d2a3c815e8..0000000000 --- a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/FilterRegistrationTest.java +++ /dev/null @@ -1,145 +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.openejb.server.httpd; - -import org.apache.openejb.jee.WebApp; -import org.apache.openejb.junit.ApplicationComposer; -import org.apache.openejb.loader.IO; -import org.apache.openejb.testing.Configuration; -import org.apache.openejb.testing.EnableServices; -import org.apache.openejb.testing.Module; -import org.apache.openejb.testng.PropertiesBuilder; -import org.apache.openejb.util.NetworkUtil; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import jakarta.servlet.Filter; -import jakarta.servlet.FilterChain; -import jakarta.servlet.FilterConfig; -import jakarta.servlet.ServletException; -import jakarta.servlet.ServletRequest; -import jakarta.servlet.ServletResponse; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletRequestWrapper; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Properties; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -@EnableServices({"httpejbd"}) -@RunWith(ApplicationComposer.class) -public class FilterRegistrationTest { - - private static int port = -1; - - @BeforeClass - public static void beforeClass() { - port = NetworkUtil.getNextAvailablePort(); - } - - @Configuration - public Properties props() { - return new PropertiesBuilder().p("httpejbd.port", Integer.toString(port)).build(); - } - - @Module - public WebApp app() { - return new WebApp() - .contextRoot("filter") - .addServlet("test", TestServlet.class.getName(), "/touch") - .addFilter("filter", TestFilter.class.getName(), "/touch") - .addFilter("filter2", TestFilter2.class.getName(), "/touch"); - } - - @Test - public void touch() throws IOException { - assertEquals("/filter/touch", IO.slurp(new URL("http://localhost:" + port + "/filter/touch"))); - assertTrue(TestFilter.init); - assertTrue(TestFilter.ok); - assertTrue(TestFilter2.ok); - } - - public static class TestServlet extends HttpServlet { - @Override - protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { - resp.getWriter().write(req.getRequestURI()); - } - } - - public static class TestFilter implements Filter { - public static boolean ok = false; - private static boolean init = false; - - @Override - public void init(final FilterConfig filterConfig) throws ServletException { - init = true; - } - - @Override - public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { - ok = true; - try { - chain.doFilter(new HttpServletRequestWrapper(new HttpRequestImpl(new URI("http://ok/filter/touch")) { - @Override - public java.net.URI getURI() { - return super.getSocketURI(); - } - - @Override - public String getMethod() { - return "GET"; - } - - }), response); - } catch (URISyntaxException e) { - throw new ServletException(e); - } - } - - @Override - public void destroy() { - System.out.println("destroyed"); - } - } - - public static class TestFilter2 implements Filter { - public static boolean ok = false; - - @Override - public void init(final FilterConfig filterConfig) throws ServletException { - // no-op - } - - @Override - public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { - ok = true; - chain.doFilter(request, response); - } - - @Override - public void destroy() { - // no-op - } - } -} diff --git a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/HttpEjbServerTest.java b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/HttpEjbServerTest.java deleted file mode 100644 index 4b14c5d756..0000000000 --- a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/HttpEjbServerTest.java +++ /dev/null @@ -1,130 +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.openejb.server.httpd; - -import java.util.Properties; - -import junit.framework.Test; -import junit.framework.TestSuite; - -import org.apache.openejb.OpenEJB; -import org.apache.openejb.core.ServerFederation; -import org.apache.openejb.server.ServiceException; -import org.apache.openejb.server.ServiceDaemon; -import org.apache.openejb.server.ejbd.EjbServer; -import org.apache.openejb.test.TestManager; -import org.apache.openejb.test.singleton.SingletonTestSuite; -import org.apache.openejb.test.entity.bmp.BmpTestSuite; -import org.apache.openejb.test.entity.cmp.CmpTestSuite; -import org.apache.openejb.test.stateful.StatefulTestSuite; -import org.apache.openejb.test.stateless.StatelessTestSuite; - -/** - * To run from intellij or another IDE add - * - * -Dopenejb.home=/Users/dblevins/work/openejb3/server/openejb-httpd/target/test-classes - * - * @version $Revision$ $Date$ - */ -public class HttpEjbServerTest extends org.apache.openejb.test.TestSuite { - - protected void setUp() throws Exception { - System.setProperty("openejb.test.server", HttpEjbTestServer.class.getName()); -// System.setProperty("openejb.test.database", org.apache.openejb.test.DerbyTestDatabase.class.getName()); - System.setProperty("openejb.test.database", org.apache.openejb.test.HsqldbTestDatabase.class.getName()); - - // Copied from org.apache.openejb.server.httpd.SomeoneBrokeSurefireAndThisIsADirtyHackForItTest which is now gone - System.setProperty("openejb.assembler", org.apache.openejb.assembler.classic.Assembler.class.getName()); - System.setProperty("openejb.deployments.classpath.include", ".*openejb-itests-beans.*"); - System.setProperty("openejb.deployments.classpath.filter.systemapps", "false"); - - TestManager.init(null); - TestManager.start(); - } - - protected void tearDown() throws Exception { - TestManager.stop(); - OpenEJB.destroy(); - } - - public static Test suite() { - TestSuite suite = new HttpEjbServerTest(); - suite.addTest(SingletonTestSuite.suite()); - suite.addTest(StatelessTestSuite.suite()); - suite.addTest(StatefulTestSuite.suite()); - suite.addTest(BmpTestSuite.suite()); - suite.addTest(CmpTestSuite.suite()); - return suite; - } - - public static class HttpEjbTestServer implements org.apache.openejb.test.TestServer { - private ServiceDaemon serviceDaemon; - HttpServer httpServer; - private int port; - - public void init(Properties props) { - try { - EjbServer ejbServer = new EjbServer(); - ServerServiceAdapter adapter = new ServerServiceAdapter(ejbServer); - httpServer = new OpenEJBHttpServer(adapter); - - props.put("openejb.deployments.classpath", "true"); - OpenEJB.init(props, new ServerFederation()); - ejbServer.init(props); - - httpServer.init(props); - - // Binding to port 0 means that the OS will - // randomly pick an *available* port and bind to it - serviceDaemon = new ServiceDaemon(httpServer, 0, "localhost"); - - } catch (Exception e) { - throw new RuntimeException("Unable to initialize Test Server.", e); - } - } - - public void start() { - try { - serviceDaemon.start(); - httpServer.start(); - - // Here we figure out which port the OS picked for us - // so we can use it in the getContextEnvironment method - port = serviceDaemon.getPort(); - } catch (ServiceException e) { - throw new RuntimeException("Unable to start Test Server.", e); - } - } - - public void stop() { - try { - serviceDaemon.stop(); - httpServer.stop(); - } catch (ServiceException e) { - throw new RuntimeException("Unable to stop Test Server.", e); - } - } - - public Properties getContextEnvironment() { - Properties props = new Properties(); - props.put("java.naming.factory.initial", "org.apache.openejb.client.RemoteInitialContextFactory"); - props.put("java.naming.provider.url", "http://127.0.0.1:" + port + "/rjp"); - return props; - } - } -} diff --git a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/HttpResponseImplSessionTest.java b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/HttpResponseImplSessionTest.java deleted file mode 100644 index c3a6b888c5..0000000000 --- a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/HttpResponseImplSessionTest.java +++ /dev/null @@ -1,144 +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.openejb.server.httpd; - -import org.apache.openejb.core.CoreContainerSystem; -import org.apache.openejb.core.ivm.naming.IvmJndiFactory; -import org.apache.openejb.loader.SystemInstance; -import org.apache.openejb.server.ServiceException; -import org.apache.openejb.server.httpd.session.SessionManager; -import org.apache.openejb.spi.ContainerSystem; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.util.Properties; -import java.util.concurrent.atomic.AtomicReference; -import jakarta.servlet.http.HttpSession; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class HttpResponseImplSessionTest { - private OpenEJBHttpEjbServer server; - - private static int numberOfSessions() throws IllegalAccessException { - return SystemInstance.get().getComponent(SessionManager.class).size(); - } - - @Before - public void start() throws Exception { - SystemInstance.get().setComponent(ContainerSystem.class, new CoreContainerSystem(new IvmJndiFactory())); - - server = new OpenEJBHttpEjbServer(); - server.init(new Properties()); - server.start(); - } - - private String request(final InOutSocket socket) throws ServiceException, IOException { - server.service(socket); - return socket.out(); - } - - @After - public void stop() throws ServiceException { - server.stop(); - SystemInstance.reset(); - } - - @Test - public void noSession() throws Exception { - final int numberOfSessionsBefore = numberOfSessions(); - assertFalse(request(new InOutSocket().reset("GET /foo")).contains("Set-Cookie")); - assertEquals(numberOfSessionsBefore, numberOfSessions()); - } - - @Test - public void session() throws Exception { - final AtomicReference<Boolean> clearSession = new AtomicReference<Boolean>(false); - - SystemInstance.get().getComponent(HttpListenerRegistry.class).addHttpListener(new HttpListener() { - @Override - public void onMessage(final HttpRequest request, final HttpResponse response) throws Exception { - final HttpSession session = request.getSession(true); - if (clearSession.get()) { - session.invalidate(); - } - } - }, "/session"); - - try { - final int numberOfSessions = numberOfSessions() + 1; // first request will create one - final InOutSocket socket = new InOutSocket(); - String session = null; - for (int i = 0; i < 3; i++) { - String request = "GET /session"; - if (session != null) { - request += "\nCookie: EJBSESSIONID=" + session + ";\n"; - } - final String response = request(socket.reset(request)); - assertTrue(response.contains("Set-Cookie")); - - if (session == null) { - final int beginIndex = response.indexOf("EJBSESSIONID=") + "EJBSESSIONID=".length(); - session = response.substring(beginIndex, response.indexOf(";", beginIndex)); - } - - assertEquals(numberOfSessions, numberOfSessions()); - } - - clearSession.set(true); - request(socket.reset("GET /session\nCookie: EJBSESSIONID=" + session + ";\n")); - assertEquals(numberOfSessions - 1, numberOfSessions()); - } finally { - SystemInstance.get().getComponent(HttpListenerRegistry.class).removeHttpListener("/session"); - } - } - - private static class InOutSocket extends Socket { - private ByteArrayInputStream inputStream; - private ByteArrayOutputStream outputStream; - - @Override - public InputStream getInputStream() throws IOException { - return inputStream; - } - - @Override - public OutputStream getOutputStream() throws IOException { - return outputStream; - } - - public InOutSocket reset(final String input) { - inputStream = new ByteArrayInputStream(input.getBytes()); - outputStream = new ByteArrayOutputStream(); - return this; - } - - public String out() { - return new String(outputStream.toByteArray()); - } - } -} diff --git a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/JettyTest.java b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/JettyTest.java deleted file mode 100644 index e3fa694ac8..0000000000 --- a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/JettyTest.java +++ /dev/null @@ -1,79 +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.openejb.server.httpd; - -import junit.framework.TestCase; - -public class JettyTest extends TestCase { - - public void testDummy() { - assertTrue(true); - } - -// public void testJettyImpl() throws Exception { -// SystemInstance.get().setComponent(ContainerSystem.class, new CoreContainerSystem()); -// -// Properties props = new Properties(); -// props.setProperty("impl", "Jetty"); -// -// HttpEjbServer server = new HttpEjbServer(); -// server.init(props); -// -// assertTrue("SystemInstance.get().getComponent(HttpServer.class) should be an instance of JettyHttpServer", -// SystemInstance.get().getComponent(HttpServer.class) instanceof JettyHttpServer); -// } - -// public void testOpenEJBImpl() throws Exception { -// SystemInstance.get().setComponent(ContainerSystem.class, new CoreContainerSystem()); -// -// Properties props = new Properties(); -// props.setProperty("impl", "openejb"); -// -// HttpEjbServer server = new HttpEjbServer(); -// server.init(props); -// -// assertTrue("SystemInstance.get().getComponent(HttpServer.class) should be an instance of OpenEJBHttpServer", -// SystemInstance.get().getComponent(HttpServer.class) instanceof OpenEJBHttpServer); -// } - -// public void testJettyClassCheck() throws Exception { -// SystemInstance.get().setComponent(ContainerSystem.class, new CoreContainerSystem()); -// -// Properties props = new Properties(); -// -// HttpEjbServer server = new HttpEjbServer(); -// server.init(props); -// -// assertTrue("SystemInstance.get().getComponent(HttpServer.class) should be an instance of JettyHttpServer", -// SystemInstance.get().getComponent(HttpServer.class) instanceof JettyHttpServer); -// } - -// public void testUnknownImpl() throws Exception { -// SystemInstance.get().setComponent(ContainerSystem.class, new CoreContainerSystem()); -// -// Properties props = new Properties(); -// props.setProperty("impl", "fake"); -// -// try { -// HttpEjbServer server = new HttpEjbServer(); -// server.init(props); -// fail("expected IllegalArgumentException"); -// } catch (IllegalArgumentException expected) { -// } -// } -} diff --git a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/OpenEJBHttpServerTest.java b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/OpenEJBHttpServerTest.java deleted file mode 100644 index ef3d1b0440..0000000000 --- a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/OpenEJBHttpServerTest.java +++ /dev/null @@ -1,119 +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.openejb.server.httpd; - -import org.apache.openejb.jee.EjbJar; -import org.apache.openejb.junit.ApplicationComposer; -import org.apache.openejb.loader.SystemInstance; -import org.apache.openejb.spi.SecurityService; -import org.apache.openejb.testing.Configuration; -import org.apache.openejb.testing.EnableServices; -import org.apache.openejb.testing.Module; -import org.apache.openejb.testng.PropertiesBuilder; -import org.apache.openejb.util.NetworkUtil; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.Socket; -import java.net.URL; -import java.security.Principal; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Properties; -import java.util.concurrent.CopyOnWriteArrayList; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -@EnableServices({"httpejbd"}) -@RunWith(ApplicationComposer.class) -public class OpenEJBHttpServerTest { - private int nextAvailablePort = -1; - - @Test - public void requestStartsWithoutCallerIdentity() throws Exception { - final List<String> callersAtRequestStart = new CopyOnWriteArrayList<>(); - final HttpListenerRegistry registry = SystemInstance.get().getComponent(HttpListenerRegistry.class); - registry.addHttpListener(new HttpListener() { - @Override - public void onMessage(final HttpRequest request, final HttpResponse response) throws Exception { - final Principal principal = SystemInstance.get().getComponent(SecurityService.class).getCallerPrincipal(); - callersAtRequestStart.add(principal == null ? null : principal.getName()); - request.login("jonathan", "secret"); // intentionally never logged out - response.getOutputStream().write("ok".getBytes()); - } - }, "/login"); - try { - final List<Integer> statuses = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - final URL url = new URL("http://localhost:" + nextAvailablePort + "/login"); - final HttpURLConnection connection = HttpURLConnection.class.cast(url.openConnection()); - statuses.add(connection.getResponseCode()); - connection.disconnect(); - } - assertEquals(10, callersAtRequestStart.size()); - assertFalse(callersAtRequestStart.toString(), callersAtRequestStart.contains("jonathan")); - assertEquals(Collections.nCopies(10, 200), statuses); - } finally { - registry.removeHttpListener("/login"); - } - } - - @Test - public void malformedRequestResponseContainsNoServerDetails() throws Exception { - final String response; - try (final Socket socket = new Socket("localhost", nextAvailablePort)) { - final OutputStream out = socket.getOutputStream(); - out.write("GET /foo HTTP/1.1\r\nno-colon-header\r\n\r\n".getBytes()); - out.flush(); - socket.shutdownOutput(); - final InputStream in = socket.getInputStream(); - final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - final byte[] chunk = new byte[1024]; - int read; - while ((read = in.read(chunk)) != -1) { - buffer.write(chunk, 0, read); - } - response = buffer.toString(); - } - assertTrue(response, response.startsWith("HTTP/1.1 500 ")); - assertFalse(response, response.contains("Exception")); - assertFalse(response, response.contains("org.apache.openejb")); - assertFalse(response, response.contains("\tat ")); - } - - @Configuration - public Properties props() { - nextAvailablePort = NetworkUtil.getNextAvailablePort(); - return new PropertiesBuilder() - .p("httpejbd.port", Integer.toString(nextAvailablePort)) - .p("httpejbd.threadsCore", "2") - .p("httpejbd.threads", "2") - .build(); - } - - @Module - public EjbJar jar() { - return new EjbJar(); - } -} diff --git a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ResourcesTest.java b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ResourcesTest.java deleted file mode 100644 index f78ceda53a..0000000000 --- a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ResourcesTest.java +++ /dev/null @@ -1,76 +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.openejb.server.httpd; - -import org.apache.openejb.junit.ApplicationComposerRule; -import org.apache.openejb.loader.IO; -import org.apache.openejb.testing.Classes; -import org.apache.openejb.testing.ContainerProperties; -import org.apache.openejb.testing.EnableServices; -import org.apache.openejb.testing.RandomPort; -import org.apache.openejb.testing.WebResource; -import org.junit.Rule; -import org.junit.Test; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -@EnableServices("http") -@WebResource("src/test/web") -@Classes -@ContainerProperties(@ContainerProperties.Property(name = "httpejbd.useJetty", value = "fase")) -public class ResourcesTest { - @Rule - public final ApplicationComposerRule container = new ApplicationComposerRule(this); - - @RandomPort("http") - private URL context; - - @Test - public void classloader() throws IOException { - assertTrue(IO.slurp(new URL(context.toExternalForm() + "openejb/foo.txt")).contains("from classloader")); - assertTrue(IO.slurp(new URL(context.toExternalForm() + "openejb/other/foo.txt")).contains("from classloader2")); - } - - @Test - public void folder() throws IOException { - assertTrue(IO.slurp(new URL(context.toExternalForm() + "openejb/bar.txt")).contains("from web")); - assertTrue(IO.slurp(new URL(context.toExternalForm() + "openejb/sub/bar.txt")).contains("from web2")); - } - - @Test - public void parentSegmentsAreNotServed() throws IOException { - // src/test/web/../../../pom.xml resolves to the module pom - final String body = slurpQuietly(new URL(context.toExternalForm() + "openejb/%2e%2e/%2e%2e/%2e%2e/pom.xml")); - assertFalse(body, body.contains("<project")); - } - - private static String slurpQuietly(final URL url) throws IOException { - final HttpURLConnection connection = HttpURLConnection.class.cast(url.openConnection()); - try { - final InputStream stream = connection.getResponseCode() < 400 ? connection.getInputStream() : connection.getErrorStream(); - return stream == null ? "" : IO.slurp(stream); - } finally { - connection.disconnect(); - } - } -} diff --git a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ServletRegistrationTest.java b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ServletRegistrationTest.java deleted file mode 100644 index d6d259c8d9..0000000000 --- a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ServletRegistrationTest.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.openejb.server.httpd; - -import org.apache.openejb.jee.WebApp; -import org.apache.openejb.junit.ApplicationComposer; -import org.apache.openejb.testing.Classes; -import org.apache.openejb.testing.Configuration; -import org.apache.openejb.testing.EnableServices; -import org.apache.openejb.testing.Module; -import org.apache.openejb.loader.IO; -import org.apache.openejb.testng.PropertiesBuilder; -import org.apache.openejb.util.NetworkUtil; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import jakarta.ejb.EJB; -import jakarta.ejb.Singleton; -import jakarta.servlet.ServletException; -import jakarta.servlet.annotation.WebServlet; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.net.URL; -import java.util.Properties; - -import static org.junit.Assert.assertEquals; - -@EnableServices("httpejbd") -@RunWith(ApplicationComposer.class) -public class ServletRegistrationTest { - - private static int port = -1; - - @BeforeClass - public static void beforeClass() { - port = NetworkUtil.getNextAvailablePort(); - } - - @Configuration - public Properties props() { - return new PropertiesBuilder().p("httpejbd.port", Integer.toString(port)).build(); - } - - @Module - @Classes({TestServlet.class, TestServlet2.class, TestServlet3.class, TestServlet4.class, SomeEjb.class}) - public WebApp app() { - return new WebApp() - .contextRoot("servlet") - .addServlet("test", TestServlet.class.getName(), "/touch"); - } - - @Test - public void touch() throws IOException { - assertEquals("touched", IO.slurp(new URL("http://localhost:" + port + "/servlet/touch"))); - } - - @Test - public void discover() throws IOException { - assertEquals("discovered", IO.slurp(new URL("http://localhost:" + port + "/servlet/discover"))); - } - - @Test - public void wildcard() throws IOException { - assertEquals("wildcard", IO.slurp(new URL("http://localhost:" + port + "/servlet/bar/openejb"))); - } - - @Test - public void injections() throws IOException { - assertEquals("true", IO.slurp(new URL("http://localhost:" + port + "/servlet/injection"))); - } - - public static class TestServlet extends HttpServlet { - @Override - protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { - resp.getWriter().write("touched"); - } - } - - @WebServlet(urlPatterns = "/discover") - public static class TestServlet2 extends HttpServlet { - @Override - protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { - resp.getWriter().write("discovered"); - } - } - - @WebServlet(urlPatterns = "/bar/*") - public static class TestServlet3 extends HttpServlet { - @Override - protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { - resp.getWriter().write("wildcard"); - } - } - - @WebServlet(urlPatterns = "/injection") - public static class TestServlet4 extends HttpServlet { - @EJB - private SomeEjb ejb; - - @Override - protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { - resp.getWriter().write(Boolean.toString(ejb != null)); - } - } - - @Singleton - public static class SomeEjb { - - } -} diff --git a/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RESTService.java b/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RESTService.java index 9f77bbb764..5e7670bf56 100644 --- a/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RESTService.java +++ b/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RESTService.java @@ -1070,9 +1070,6 @@ public abstract class RESTService implements ServerService, SelfManaging { protected void beforeStart() { rsRegistry = SystemInstance.get().getComponent(RsRegistry.class); - if (rsRegistry == null && SystemInstance.get().getComponent(HttpListenerRegistry.class) != null) { - rsRegistry = new RsRegistryImpl(); - } } @Override diff --git a/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RsRegistryImpl.java b/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RsRegistryImpl.java deleted file mode 100644 index dd7d77c61c..0000000000 --- a/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RsRegistryImpl.java +++ /dev/null @@ -1,61 +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.openejb.server.rest; - -import org.apache.openejb.server.httpd.BasicAuthHttpListenerWrapper; -import org.apache.openejb.server.httpd.HttpListener; -import org.apache.openejb.server.httpd.OpenEJBHttpRegistry; -import org.apache.openejb.server.httpd.util.HttpUtil; - -import java.util.HashMap; -import java.util.Map; - -public class RsRegistryImpl extends OpenEJBHttpRegistry implements RsRegistry { - private Map<String, String> addresses = new HashMap<>(); - - @Override - public AddressInfo createRsHttpListener(final String appId, final String webContext, - final HttpListener listener, final ClassLoader classLoader, final String path, - final String virtualHost, final String auth, final String realm) { - final String address = HttpUtil.selectSingleAddress(getResolvedAddresses(path)); - - if ("BASIC".equals(auth)) { // important to wrap with basic wrapper before classloader wrapping - addWrappedHttpListener(new BasicAuthHttpListenerWrapper(listener, realm), classLoader, path); - } else if (auth == null || "NONE".equals(auth)) { - addWrappedHttpListener(listener, classLoader, path); - } else { - throw new IllegalArgumentException("The embedded HTTP transport only supports BASIC or NONE authentication, " - + "refusing to publish '" + path + "' with auth method '" + auth + "'"); - } - - addresses.put(address, path); - return new AddressInfo(address, address); - } - - @Override - public HttpListener removeListener(final String appId, final String context) { - String regex = addresses.get(context); - if (regex != null) { - HttpListener listener = registry.removeHttpListener(regex); - if (listener instanceof ClassLoaderHttpListener) { - return ((ClassLoaderHttpListener) listener).getDelegate(); - } - } - return null; - } -} diff --git a/server/openejb-rest/src/test/java/org/apache/openejb/server/rest/RsRegistryImplAuthTest.java b/server/openejb-rest/src/test/java/org/apache/openejb/server/rest/RsRegistryImplAuthTest.java deleted file mode 100644 index f400b35a99..0000000000 --- a/server/openejb-rest/src/test/java/org/apache/openejb/server/rest/RsRegistryImplAuthTest.java +++ /dev/null @@ -1,43 +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.openejb.server.rest; - -import org.apache.openejb.server.httpd.HttpListener; -import org.junit.Test; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -public class RsRegistryImplAuthTest { - private static final HttpListener NOOP_LISTENER = (request, response) -> { - // no-op - }; - - @Test - public void onlyBasicOrNoneAreAccepted() { - for (final String auth : new String[]{"DIGEST", "CLIENT-CERT"}) { - try { - new RsRegistryImpl().createRsHttpListener( - "app", "web", NOOP_LISTENER, Thread.currentThread().getContextClassLoader(), - "/rest/.*", "localhost", auth, "realm"); - fail("auth method " + auth + " must be rejected"); - } catch (final IllegalArgumentException expected) { - assertTrue(expected.getMessage().contains(auth)); - } - } - } -} diff --git a/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistry.java b/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistry.java deleted file mode 100644 index 69ed5729df..0000000000 --- a/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistry.java +++ /dev/null @@ -1,95 +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.openejb.server.webservices; - -import org.apache.openejb.assembler.classic.ServletInfo; -import org.apache.openejb.server.httpd.BasicAuthHttpListenerWrapper; -import org.apache.openejb.server.httpd.HttpListener; -import org.apache.openejb.server.httpd.OpenEJBHttpRegistry; - -import java.util.List; - -public class OpenEJBHttpWsRegistry extends OpenEJBHttpRegistry implements WsRegistry { - @Override - public List<String> setWsContainer(final HttpListener httpListener, - final ClassLoader classLoader, - final String context, final String virtualHost, final ServletInfo servletInfo, - final String realmName, final String transportGuarantee, final String authMethod, - final String moduleId) throws Exception { - - final String path = servletInfo.mappings.iterator().next(); - return addWsContainer(httpListener, classLoader, context, virtualHost, path, realmName, transportGuarantee, authMethod, moduleId); - } - - @Override - public void clearWsContainer(final String context, final String virtualHost, final ServletInfo servletInfo, final String moduleId) { - final String path = servletInfo.mappings.iterator().next(); - removeWsContainer(path, moduleId); - } - - @Override - public List<String> addWsContainer(final HttpListener inputListener, - final ClassLoader classLoader, - final String context, - final String virtualHost, - final String path, - final String realmName, - final String transportGuarantee, // ignored - final String authMethod, - final String moduleId) throws Exception { - - if (path == null) throw new NullPointerException("contextRoot is null"); - - HttpListener httpListener = inputListener; - if (httpListener == null) throw new NullPointerException("httpListener is null"); - - if ("BASIC".equals(authMethod)) { - httpListener = new BasicAuthHttpListenerWrapper(httpListener, realmName, true); - } else if (authMethod != null && !"NONE".equals(authMethod)) { - throw new IllegalArgumentException("The embedded HTTP transport only supports BASIC or NONE authentication, " - + "refusing to publish '" + path + "' with auth method '" + authMethod + "'"); - } - - final StringBuilder deployedPath = new StringBuilder(""); - if (context != null) { - if (!context.startsWith("/")) { - deployedPath.append("/"); - } - deployedPath.append(context); - if (!context.endsWith("/")) { - deployedPath.append("/"); - } - } else { - deployedPath.append("/"); - } - if (path.startsWith("/") && path.length() > 1) { - deployedPath.append(path.substring(1)); - } else if (path.length() > 1) { - deployedPath.append(path); - } - addWrappedHttpListener(httpListener, classLoader, deployedPath.toString()); - - // register wsdl locations for service-ref resolution - return getResolvedAddresses(deployedPath.toString()); - } - - @Override - public void removeWsContainer(final String path, final String moduleId) { - registry.removeHttpListener(path); - } -} diff --git a/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsService.java b/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsService.java index 47d9c7704e..d7eeebdda4 100644 --- a/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsService.java +++ b/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsService.java @@ -174,9 +174,6 @@ public abstract class WsService implements ServerService, SelfManaging { @Override public void start() throws ServiceException { wsRegistry = SystemInstance.get().getComponent(WsRegistry.class); - if (wsRegistry == null && SystemInstance.get().getComponent(HttpListenerRegistry.class) != null) { - wsRegistry = new OpenEJBHttpWsRegistry(); - } if (portAddressRegistry == null) { portAddressRegistry = new PortAddressRegistryImpl(); diff --git a/server/openejb-webservices/src/test/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistryAuthTest.java b/server/openejb-webservices/src/test/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistryAuthTest.java deleted file mode 100644 index 3f44b5b737..0000000000 --- a/server/openejb-webservices/src/test/java/org/apache/openejb/server/webservices/OpenEJBHttpWsRegistryAuthTest.java +++ /dev/null @@ -1,43 +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.openejb.server.webservices; - -import org.apache.openejb.server.httpd.HttpListener; -import org.junit.Test; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -public class OpenEJBHttpWsRegistryAuthTest { - private static final HttpListener NOOP_LISTENER = (request, response) -> { - // no-op - }; - - @Test - public void onlyBasicOrNoneAreAccepted() throws Exception { - for (final String authMethod : new String[]{"DIGEST", "CLIENT-CERT"}) { - try { - new OpenEJBHttpWsRegistry().addWsContainer( - NOOP_LISTENER, Thread.currentThread().getContextClassLoader(), - "ctx", "localhost", "/service", "realm", "NONE", authMethod, "moduleId"); - fail("auth method " + authMethod + " must be rejected"); - } catch (final IllegalArgumentException expected) { - assertTrue(expected.getMessage().contains(authMethod)); - } - } - } -}
