From b0c3c11bd937ac2571d15e6125ace67d0c42ae70 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Sun, 9 Aug 2015 13:36:24 +0000
Subject: [PATCH] Start work on Jetty 9 targetting 9.2.x for now Requires Java
 7

---
 apps/jetty/build.xml                          | 11 ++-
 .../java/src/net/i2p/jetty/I2PLogger.java     |  7 ++
 .../java/src/net/i2p/jetty/I2PRequestLog.java | 18 ++--
 .../java/src/net/i2p/jetty/JettyStart.java    | 19 ++--
 .../i2p/router/web/RouterConsoleRunner.java   | 87 ++++++++++---------
 5 files changed, 79 insertions(+), 63 deletions(-)

diff --git a/apps/jetty/build.xml b/apps/jetty/build.xml
index 2fad37dfaf..11418fb95e 100644
--- a/apps/jetty/build.xml
+++ b/apps/jetty/build.xml
@@ -1,10 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project basedir="." default="all" name="jetty">
 
-    <property name="jetty.ver" value="8.1.17.v20150415" />
+    <!-- unused until we go to 9.3 -->
+    <property name="jetty.branch" value="stable-9" />
+    <property name="jetty.ver" value="9.2.13.v20150730" />
     <property name="jetty.base" value="jetty-distribution-${jetty.ver}" />
-    <property name="jetty.sha1" value="ce7bcd1bdcdac4cf130467f6d55155b9e1517e71" />
+    <property name="jetty.sha1" value="9368e431901c7102bb6a39172e905de30d360484" />
     <property name="jetty.filename" value="${jetty.base}.zip" />
+    <!-- change jetty.ver to jetty.branch for 9.3 -->
     <property name="jetty.url" value="http://download.eclipse.org/jetty/${jetty.ver}/dist/${jetty.filename}" />
     <property name="verified.filename" value="verified.txt" />
     <property name="javac.compilerargs" value="" />
@@ -139,8 +142,8 @@
             </manifest>
         </jar>
         <jar destfile="jettylib/javax.servlet.jar" duplicate="preserve" filesetmanifest="mergewithoutmain" >
-            <zipfileset excludes="about.html about_files about_files/* META-INF/ECLIPSEF.* META-INF/eclipse.inf plugin.properties" src="${jetty.base}/lib/servlet-api-3.0.jar" />
-            <zipfileset excludes="about.html about_files about_files/* META-INF/ECLIPSEF.* META-INF/eclipse.inf plugin.properties" src="${jetty.base}/lib/jsp/javax.servlet.jsp-2.2.0.v201112011158.jar" />
+            <zipfileset excludes="about.html about_files about_files/* META-INF/ECLIPSEF.* META-INF/eclipse.inf plugin.properties" src="${jetty.base}/lib/servlet-api-3.1.jar" />
+            <zipfileset excludes="about.html about_files about_files/* META-INF/ECLIPSEF.* META-INF/eclipse.inf plugin.properties" src="${jetty.base}/lib/jsp/javax.servlet.jsp-2.3.2.jar" />
         </jar>
       <!--
         <delete file="jetty.tar" />
diff --git a/apps/jetty/java/src/net/i2p/jetty/I2PLogger.java b/apps/jetty/java/src/net/i2p/jetty/I2PLogger.java
index 5d3e421293..83666d431d 100644
--- a/apps/jetty/java/src/net/i2p/jetty/I2PLogger.java
+++ b/apps/jetty/java/src/net/i2p/jetty/I2PLogger.java
@@ -259,4 +259,11 @@ public class I2PLogger implements Logger
     public String getName() {
         return "net.i2p.jetty.I2PLogger";
     }
+
+    /**
+     *  @since Jetty 9
+     */
+    public void debug(String msg, long arg) {
+        debug(msg, Long.valueOf(arg), null);
+    }
 }
diff --git a/apps/jetty/java/src/net/i2p/jetty/I2PRequestLog.java b/apps/jetty/java/src/net/i2p/jetty/I2PRequestLog.java
index 723e069f77..52d76ef08a 100644
--- a/apps/jetty/java/src/net/i2p/jetty/I2PRequestLog.java
+++ b/apps/jetty/java/src/net/i2p/jetty/I2PRequestLog.java
@@ -24,7 +24,6 @@ import java.util.TimeZone;
 
 import javax.servlet.http.Cookie;
 
-import org.eclipse.jetty.http.HttpHeaders;
 import org.eclipse.jetty.http.PathMap;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.RequestLog;
@@ -276,7 +275,7 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
                 String addr = null;
                 if (_preferProxiedForAddress) 
                 {
-                    addr = request.getHeader(HttpHeaders.X_FORWARDED_FOR);
+                    addr = request.getHeader("X-Forwarded-For");
                 }
 
                 if (addr == null) {
@@ -296,7 +295,9 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
                 if (_logDateCache!=null)
                     buf.append(_logDateCache.format(request.getTimeStamp()));
                 else
-                    buf.append(request.getTimeStampBuffer().toString());
+                    //buf.append(request.getTimeStampBuffer().toString());
+                    // TODO SimpleDateFormat or something
+                    buf.append(request.getTimeStamp());
                     
                 buf.append("] \"");
                 buf.append(request.getMethod());
@@ -344,7 +345,7 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
             {
                 synchronized(_writer)
                 {
-                    buf.append(StringUtil.__LINE_SEPARATOR);
+                    buf.append(System.getProperty("line.separator", "\n"));
                     int l=buf.length();
                     if (l>_copy.length)
                         l=_copy.length;  
@@ -398,7 +399,7 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
                         _writer.write(Long.toString(System.currentTimeMillis() - request.getTimeStamp()));
                     }
 
-                    _writer.write(StringUtil.__LINE_SEPARATOR);
+                    _writer.write(System.getProperty("line.separator", "\n"));
                     _writer.flush();
                 }
             }
@@ -415,7 +416,7 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
                                Response response, 
                                Writer writer) throws IOException 
     {
-        String referer = request.getHeader(HttpHeaders.REFERER);
+        String referer = request.getHeader("Referer");
         if (referer == null) 
             writer.write("\"-\" ");
         else 
@@ -425,7 +426,7 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
             writer.write("\" ");
         }
         
-        String agent = request.getHeader(HttpHeaders.USER_AGENT);
+        String agent = request.getHeader("User-Agent");
         if (agent == null)
             writer.write("\"-\" ");
         else
@@ -441,8 +442,7 @@ public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
     {
         if (_logDateFormat!=null)
         {       
-            _logDateCache = new DateCache(_logDateFormat, _logLocale);
-            _logDateCache.setTimeZoneID(_logTimeZone);
+            _logDateCache = new DateCache(_logDateFormat, _logLocale, _logTimeZone);
         }
         
         if (_filename != null) 
diff --git a/apps/jetty/java/src/net/i2p/jetty/JettyStart.java b/apps/jetty/java/src/net/i2p/jetty/JettyStart.java
index 73b4b4d786..102e211991 100644
--- a/apps/jetty/java/src/net/i2p/jetty/JettyStart.java
+++ b/apps/jetty/java/src/net/i2p/jetty/JettyStart.java
@@ -29,6 +29,7 @@ import static net.i2p.app.ClientAppState.*;
 import net.i2p.util.PortMapper;
 
 import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.NetworkConnector;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.util.component.LifeCycle;
 import org.eclipse.jetty.util.resource.Resource;
@@ -127,13 +128,17 @@ public class JettyStart implements ClientApp {
                                 Server server = (Server) lc;
                                 Connector[] connectors = server.getConnectors();
                                 if (connectors.length > 0) {
-                                    int port = connectors[0].getPort();
-                                    if (port > 0) {
-                                        _port = port;
-                                        String host = connectors[0].getHost();
-                                        if (host.equals("0.0.0.0") || host.equals("::"))
-                                            host = "127.0.0.1";
-                                        _context.portMapper().register(PortMapper.SVC_EEPSITE, host, port);
+                                    Connector conn = connectors[0];
+                                    if (conn instanceof NetworkConnector) {
+                                        NetworkConnector nconn = (NetworkConnector) conn;
+                                        int port = nconn.getPort();
+                                        if (port > 0) {
+                                            _port = port;
+                                            String host = nconn.getHost();
+                                            if (host.equals("0.0.0.0") || host.equals("::"))
+                                                host = "127.0.0.1";
+                                            _context.portMapper().register(PortMapper.SVC_EEPSITE, host, port);
+                                        }
                                     }
                                 }
                             }
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
index 0c36391dd1..4645825031 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
@@ -40,18 +40,20 @@ import org.eclipse.jetty.security.ConstraintMapping;
 import org.eclipse.jetty.security.ConstraintSecurityHandler;
 import org.eclipse.jetty.security.authentication.DigestAuthenticator;
 import org.eclipse.jetty.server.AbstractConnector;
+import org.eclipse.jetty.server.ConnectionFactory;
 import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
 import org.eclipse.jetty.server.NCSARequestLog;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
 import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.bio.SocketConnector;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
 import org.eclipse.jetty.server.handler.ContextHandlerCollection;
 import org.eclipse.jetty.server.handler.DefaultHandler;
 import org.eclipse.jetty.server.handler.HandlerCollection;
 import org.eclipse.jetty.server.handler.HandlerWrapper;
 import org.eclipse.jetty.server.handler.RequestLogHandler;
-import org.eclipse.jetty.server.nio.SelectChannelConnector;
-import org.eclipse.jetty.server.ssl.SslSocketConnector;
-import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
 import org.eclipse.jetty.servlet.ServletHandler;
 import org.eclipse.jetty.servlet.ServletHolder;
 import org.eclipse.jetty.webapp.WebAppContext;
@@ -327,6 +329,22 @@ public class RouterConsoleRunner implements RouterApp {
      *			DefaultHandler
      *			RequestLogHandler (opt)
      *</pre>
+     *
+     *  Porting to Jetty 9:
+     *
+     *  http://dev.eclipse.org/mhonarc/lists/jetty-dev/msg01952.html
+     *  You are missing a few facts about Jetty 9.1 ...
+     *  First, there are no longer any blocking connectors.
+     *  Its all async / nio connectors now. (mainly because that's the direction that the servlet api 3.1 is taking)
+     *
+     *  Next, there is only 1 connector.   The ServerConnector.
+     *  However, it takes 1 or more ConnectionFactory implementations to know how to handle the incoming connection.
+     *  We have factories for HTTP (0.9 thru 1.1), SPDY, SSL-http, and SSL-npn so far.
+     *  This list of factories will expand as the future of connectivity to web servers is ever growing (think HTTP/2)
+     *
+     *  Use the embedded examples for help understanding this.
+     *  http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java?id=jetty-9.1.0.RC0
+     *
      */
     public void startConsole() {
         File workDir = new SecureDirectory(_context.getTempDir(), "jetty-work");
@@ -339,8 +357,9 @@ public class RouterConsoleRunner implements RouterApp {
 
         // so Jetty can find WebAppConfiguration
         System.setProperty("jetty.class.path", _context.getBaseDir() + "/lib/routerconsole.jar");
-        _server = new Server();
-        _server.setGracefulShutdown(1000);
+        // FIXME
+        // http://dev.eclipse.org/mhonarc/lists/jetty-users/msg03487.html
+        //_server.setGracefulShutdown(1000);
 
         // In Jetty 6, QTP was not concurrent, so we switched to
         // ThreadPoolExecutor with a fixed-size queue, a set maxThreads,
@@ -372,14 +391,11 @@ public class RouterConsoleRunner implements RouterApp {
             // class not found...
             //System.out.println("INFO: Jetty concurrent ThreadPool unavailable, using QueuedThreadPool");
             LinkedBlockingQueue<Runnable> lbq = new LinkedBlockingQueue<Runnable>(4*MAX_THREADS);
-            QueuedThreadPool qtp = new QueuedThreadPool(lbq);
-            // min and max threads will be set below
-            //qtp.setMinThreads(MIN_THREADS);
-            //qtp.setMaxThreads(MAX_THREADS);
-            qtp.setMaxIdleTimeMs(MAX_IDLE_TIME);
+            // min and max threads will be reset below
+            QueuedThreadPool qtp = new QueuedThreadPool(MAX_THREADS, MIN_THREADS, MAX_IDLE_TIME, lbq);
             qtp.setName(THREAD_NAME);
             qtp.setDaemon(true);
-            _server.setThreadPool(qtp);
+            _server = new Server(qtp);
         //}
 
         HandlerCollection hColl = new HandlerCollection();
@@ -465,27 +481,15 @@ public class RouterConsoleRunner implements RouterApp {
                         } finally {
                             if (testSock != null) try { testSock.close(); } catch (IOException ioe) {}
                         }
-                        //if (host.indexOf(":") >= 0) // IPV6 - requires patched Jetty 5
-                        //    _server.addListener('[' + host + "]:" + _listenPort);
-                        //else
-                        //    _server.addListener(host + ':' + _listenPort);
-                        AbstractConnector lsnr;
-                        if (SystemVersion.isJava6() && !SystemVersion.isGNU()) {
-                            SelectChannelConnector slsnr = new SelectChannelConnector();
-                            slsnr.setUseDirectBuffers(false);  // default true seems to be leaky
-                            lsnr = slsnr;
-                        } else {
-                            // Jetty 6 and NIO on Java 5 don't get along that well
-                            // Also: http://jira.codehaus.org/browse/JETTY-1238
-                            // "Do not use GCJ with Jetty, it will not work."
-                            // Actually it does if you don't use NIO
-                            lsnr = new SocketConnector();
-                        }
+                        HttpConfiguration httpConfig = new HttpConfiguration();
+                        // number of acceptors, (default) number of selectors
+                        ServerConnector lsnr = new ServerConnector(_server, 1, 0,
+                                                                   new HttpConnectionFactory(httpConfig));
+                        //lsnr.setUseDirectBuffers(false);  // default true seems to be leaky
                         lsnr.setHost(host);
                         lsnr.setPort(lport);
-                        lsnr.setMaxIdleTime(90*1000);  // default 10 sec
+                        lsnr.setIdleTimeout(90*1000);  // default 10 sec
                         lsnr.setName("ConsoleSocket");   // all with same name will use the same thread pool
-                        lsnr.setAcceptors(1);          // default changed to 2 somewhere in Jetty 7?
                         //_server.addConnector(lsnr);
                         connectors.add(lsnr);
                         boundAddresses++;
@@ -541,22 +545,19 @@ public class RouterConsoleRunner implements RouterApp {
                             } finally {
                                 if (testSock != null) try { testSock.close(); } catch (IOException ioe) {}
                             }
-                            // TODO if class not found use SslChannelConnector
-                            AbstractConnector ssll;
-                            if (SystemVersion.isJava6() && !SystemVersion.isGNU()) {
-                                SslSelectChannelConnector sssll = new SslSelectChannelConnector(sslFactory);
-                                sssll.setUseDirectBuffers(false);  // default true seems to be leaky
-                                ssll = sssll;
-                            } else {
-                                // Jetty 6 and NIO on Java 5 don't get along that well
-                                SslSocketConnector sssll = new SslSocketConnector(sslFactory);
-                                ssll = sssll;
-                            }
+                            HttpConfiguration httpConfig = new HttpConfiguration();
+                            httpConfig.setSecureScheme("https");
+                            httpConfig.setSecurePort(sslPort);
+                            httpConfig.addCustomizer(new SecureRequestCustomizer());
+                            // number of acceptors, (default) number of selectors
+                            ServerConnector ssll = new ServerConnector(_server, 1, 0,
+                                                                       new SslConnectionFactory(sslFactory, "http/1.1"),
+                                                                       new HttpConnectionFactory(httpConfig));
+                            //sssll.setUseDirectBuffers(false);  // default true seems to be leaky
                             ssll.setHost(host);
                             ssll.setPort(sslPort);
-                            ssll.setMaxIdleTime(90*1000);  // default 10 sec
+                            ssll.setIdleTimeout(90*1000);  // default 10 sec
                             ssll.setName("ConsoleSocket");   // all with same name will use the same thread pool
-                            ssll.setAcceptors(1);          // default changed to 2 somewhere in Jetty 7?
                             //_server.addConnector(ssll);
                             connectors.add(ssll);
                             boundAddresses++;
-- 
GitLab