From 7e3faaa7ffaf60a6f91c86bfaa3807f55b0b24d9 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Mon, 27 May 2013 11:45:15 +0000
Subject: [PATCH] OPENDJ-942 (CR-1744) HTTP Connection Handler - Running an authenticated request at "/" hangs

---
 opendj-sdk/opends/src/server/org/opends/server/protocols/http/HTTPConnectionHandler.java |  160 +++++++++++++++++++++++++++-------------------------
 1 files changed, 83 insertions(+), 77 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/protocols/http/HTTPConnectionHandler.java b/opendj-sdk/opends/src/server/org/opends/server/protocols/http/HTTPConnectionHandler.java
index 6bbc35c..7963627 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/protocols/http/HTTPConnectionHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/protocols/http/HTTPConnectionHandler.java
@@ -54,7 +54,7 @@
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
 import javax.servlet.DispatcherType;
-import javax.servlet.FilterRegistration;
+import javax.servlet.Filter;
 import javax.servlet.ServletException;
 
 import org.codehaus.jackson.JsonParseException;
@@ -78,7 +78,6 @@
 import org.glassfish.grizzly.http.server.ServerConfiguration;
 import org.glassfish.grizzly.monitoring.MonitoringConfig;
 import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
-import org.glassfish.grizzly.servlet.ServletRegistration;
 import org.glassfish.grizzly.servlet.WebappContext;
 import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
 import org.glassfish.grizzly.strategies.SameThreadIOStrategy;
@@ -264,12 +263,12 @@
       // handle it
       if (!this.currentConfig.isKeepStats() && config.isKeepStats())
       { // it must now keep stats while it was not previously
-        setHttpStatsProbe();
+        setHttpStatsProbe(this.httpServer);
       }
       else if (this.currentConfig.isKeepStats() && !config.isKeepStats()
           && this.httpProbe != null)
       { // it must NOT keep stats anymore
-        getHttpConfig().removeProbes(this.httpProbe);
+        getHttpConfig(this.httpServer).removeProbes(this.httpProbe);
         this.httpProbe = null;
       }
     }
@@ -803,75 +802,10 @@
       logError(WARN_CONFIG_LOGGER_NO_ACTIVE_HTTP_ACCESS_LOGGERS.get());
     }
 
-    this.httpServer =
-        HttpServer.createSimpleServer("./", initConfig.getListenPort());
+    this.httpServer = createHttpServer();
 
-    int requestSize = (int) currentConfig.getMaxRequestSize();
-    final ServerConfiguration serverConfig =
-        this.httpServer.getServerConfiguration();
-    serverConfig.setMaxBufferedPostSize(requestSize);
-    serverConfig.setMaxFormPostSize(requestSize);
-    if (keepStats())
-    {
-      setHttpStatsProbe();
-    }
-
-    for (NetworkListener listener : this.httpServer.getListeners())
-    {
-      TCPNIOTransport transport = listener.getTransport();
-      transport.setReuseAddress(currentConfig.isAllowTCPReuseAddress());
-      transport.setKeepAlive(currentConfig.isUseTCPKeepAlive());
-      transport.setTcpNoDelay(currentConfig.isUseTCPNoDelay());
-      transport.setWriteTimeout(currentConfig.getMaxBlockedWriteTimeLimit(),
-          TimeUnit.MILLISECONDS);
-
-      int bufferSize = (int) currentConfig.getBufferSize();
-      transport.setReadBufferSize(bufferSize);
-      transport.setWriteBufferSize(bufferSize);
-      transport.setIOStrategy(SameThreadIOStrategy.getInstance());
-      final int numRequestHandlers =
-          getNumRequestHandlers(currentConfig.getNumRequestHandlers(),
-              friendlyName);
-      transport.setSelectorRunnersCount(numRequestHandlers);
-      transport.setServerConnectionBackLog(currentConfig.getAcceptBacklog());
-
-      if (sslEngineConfigurator != null)
-      {
-        listener.setSecure(true);
-        listener.setSSLEngineConfig(sslEngineConfigurator);
-      }
-    }
-
-    final String servletName = "OpenDJ Rest2LDAP servlet";
-    final String urlPattern = "/*";
-    final WebappContext ctx = new WebappContext(servletName);
-
-    final JsonValue configuration =
-        parseJsonConfiguration(getFileForPath(this.currentConfig
-            .getConfigFile()));
-
-    final HTTPAuthenticationConfig authenticationConfig =
-        getAuthenticationConfig(configuration);
-
-    javax.servlet.Filter filter =
-        new CollectClientConnectionsFilter(this, authenticationConfig);
-    FilterRegistration filterReg =
-        ctx.addFilter("collectClientConnections", filter);
-    // TODO JNR this is not working
-    // filterReg.addMappingForServletNames(EnumSet.allOf(
-    // DispatcherType.class), servletName);
-    filterReg.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST),
-        true, urlPattern);
-
-    ConnectionFactory connFactory = getConnectionFactory(configuration);
-
-    final ServletRegistration reg =
-        ctx.addServlet(servletName, new HttpServlet(connFactory,
-        // Used for hooking our HTTPClientConnection in Rest2LDAP
-            Rest2LDAPContextFactory.getHttpServletContextFactory()));
-    reg.addMapping(urlPattern);
-
-    ctx.deploy(this.httpServer);
+    // register servlet as default servlet and also able to serve REST requests
+    createAndRegisterServlet("OpenDJ Rest2LDAP servlet", "", "/*");
 
     TRACER.debugInfo("Starting HTTP server...");
     this.httpServer.start();
@@ -879,19 +813,91 @@
     logError(NOTE_CONNHANDLER_STARTED_LISTENING.get(handlerName));
   }
 
-  private void setHttpStatsProbe()
+  private HttpServer createHttpServer()
   {
-    httpProbe = new HTTPStatsProbe(this.statTracker);
-    getHttpConfig().addProbes(httpProbe);
+    final HttpServer server = new HttpServer();
+
+    final int requestSize = (int) currentConfig.getMaxRequestSize();
+    final ServerConfiguration serverConfig = server.getServerConfiguration();
+    serverConfig.setMaxBufferedPostSize(requestSize);
+    serverConfig.setMaxFormPostSize(requestSize);
+    if (keepStats())
+    {
+      setHttpStatsProbe(server);
+    }
+
+    // configure the network listener
+    final NetworkListener listener =
+        new NetworkListener("Rest2LDAP", NetworkListener.DEFAULT_NETWORK_HOST,
+            initConfig.getListenPort());
+    server.addListener(listener);
+
+    // configure the network transport
+    final TCPNIOTransport transport = listener.getTransport();
+    transport.setReuseAddress(currentConfig.isAllowTCPReuseAddress());
+    transport.setKeepAlive(currentConfig.isUseTCPKeepAlive());
+    transport.setTcpNoDelay(currentConfig.isUseTCPNoDelay());
+    transport.setWriteTimeout(currentConfig.getMaxBlockedWriteTimeLimit(),
+        TimeUnit.MILLISECONDS);
+
+    final int bufferSize = (int) currentConfig.getBufferSize();
+    transport.setReadBufferSize(bufferSize);
+    transport.setWriteBufferSize(bufferSize);
+    transport.setIOStrategy(SameThreadIOStrategy.getInstance());
+    final int numRequestHandlers =
+        getNumRequestHandlers(currentConfig.getNumRequestHandlers(),
+            friendlyName);
+    transport.setSelectorRunnersCount(numRequestHandlers);
+    transport.setServerConnectionBackLog(currentConfig.getAcceptBacklog());
+
+    // configure SSL
+    if (sslEngineConfigurator != null)
+    {
+      listener.setSecure(true);
+      listener.setSSLEngineConfig(sslEngineConfigurator);
+    }
+
+    return server;
   }
 
-  private MonitoringConfig<HttpProbe> getHttpConfig()
+  private void setHttpStatsProbe(HttpServer server)
+  {
+    this.httpProbe = new HTTPStatsProbe(this.statTracker);
+    getHttpConfig(server).addProbes(this.httpProbe);
+  }
+
+  private MonitoringConfig<HttpProbe> getHttpConfig(HttpServer server)
   {
     final HttpServerMonitoringConfig monitoringCfg =
-        this.httpServer.getServerConfiguration().getMonitoringConfig();
+        server.getServerConfiguration().getMonitoringConfig();
     return monitoringCfg.getHttpConfig();
   }
 
+  private void createAndRegisterServlet(final String servletName,
+      final String... urlPatterns) throws Exception
+  {
+    // parse and use JSON config
+    final JsonValue configuration =
+        parseJsonConfiguration(getFileForPath(this.currentConfig
+            .getConfigFile()));
+    final HTTPAuthenticationConfig authenticationConfig =
+        getAuthenticationConfig(configuration);
+    final ConnectionFactory connFactory = getConnectionFactory(configuration);
+
+    Filter filter =
+        new CollectClientConnectionsFilter(this, authenticationConfig);
+    final HttpServlet servlet = new HttpServlet(connFactory,
+    // Used for hooking our HTTPClientConnection in Rest2LDAP
+        Rest2LDAPContextFactory.getHttpServletContextFactory());
+
+    // Create and deploy the Web app context
+    final WebappContext ctx = new WebappContext(servletName);
+    ctx.addFilter("collectClientConnections", filter).addMappingForUrlPatterns(
+        EnumSet.of(DispatcherType.REQUEST), true, urlPatterns);
+    ctx.addServlet(servletName, servlet).addMapping(urlPatterns);
+    ctx.deploy(this.httpServer);
+  }
+
   private HTTPAuthenticationConfig getAuthenticationConfig(
       final JsonValue configuration)
   {

--
Gitblit v1.10.0