Search in sources :

Example 11 with ServletHandler

use of org.eclipse.jetty.servlet.ServletHandler in project nifi by apache.

the class TestPostHTTP method testBatchWithMultipleUrls.

@Test
public void testBatchWithMultipleUrls() throws Exception {
    CaptureServlet servletA, servletB;
    TestServer serverA, serverB;
    {
        // setup test servers
        setup(null);
        servletA = servlet;
        serverA = server;
        // set up second web service
        ServletHandler handler = new ServletHandler();
        handler.addServletWithMapping(CaptureServlet.class, "/*");
        // create the second service
        serverB = new TestServer(null);
        serverB.addHandler(handler);
        serverB.startServer();
        servletB = (CaptureServlet) handler.getServlets()[0].getServlet();
    }
    // use EL for the URL
    runner.setProperty(PostHTTP.URL, "${url}");
    runner.setProperty(PostHTTP.SEND_AS_FLOWFILE, "true");
    runner.setProperty(PostHTTP.MAX_BATCH_SIZE, "10 b");
    Set<String> expectedContentA = new HashSet<>();
    Set<String> expectedContentB = new HashSet<>();
    Set<String> actualContentA = new HashSet<>();
    Set<String> actualContentB = new HashSet<>();
    // enqueue 9 FlowFiles
    for (int i = 0; i < 9; i++) {
        enqueueWithURL("a" + i, serverA.getUrl());
        enqueueWithURL("b" + i, serverB.getUrl());
        expectedContentA.add("a" + i);
        expectedContentB.add("b" + i);
    }
    // MAX_BATCH_SIZE is 10 bytes, each file is 2 bytes, so 18 files should produce 4 batches
    for (int i = 0; i < 4; i++) {
        runner.run(1);
        runner.assertAllFlowFilesTransferred(PostHTTP.REL_SUCCESS);
        final List<MockFlowFile> successFiles = runner.getFlowFilesForRelationship(PostHTTP.REL_SUCCESS);
        assertFalse(successFiles.isEmpty());
        MockFlowFile mff = successFiles.get(0);
        final String urlAttr = mff.getAttribute("url");
        if (serverA.getUrl().equals(urlAttr)) {
            checkBatch(serverA, servletA, actualContentA, (actualContentA.isEmpty() ? 5 : 4));
        } else if (serverB.getUrl().equals(urlAttr)) {
            checkBatch(serverB, servletB, actualContentB, (actualContentB.isEmpty() ? 5 : 4));
        } else {
            fail("unexpected url attribute");
        }
    }
    assertEquals(expectedContentA, actualContentA);
    assertEquals(expectedContentB, actualContentB);
    // make sure everything transferred, nothing more to do
    runner.run(1);
    runner.assertAllFlowFilesTransferred(PostHTTP.REL_SUCCESS, 0);
}
Also used : MockFlowFile(org.apache.nifi.util.MockFlowFile) ServletHandler(org.eclipse.jetty.servlet.ServletHandler) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 12 with ServletHandler

use of org.eclipse.jetty.servlet.ServletHandler in project ddf by codice.

the class FilterInjector method injectFilter.

/**
     * Injects the filter into the passed-in servlet context. This only works if
     * the servlet has not already been initialized.
     *
     * @param serviceReference Reference to the servlet context that the filter should be
     *                         injected into.
     */
public void injectFilter(ServiceReference<ServletContext> serviceReference) {
    Bundle refBundle = serviceReference.getBundle();
    LOGGER.debug("Adding Servlet Filter for {}", refBundle.getSymbolicName());
    BundleContext bundlectx = refBundle.getBundleContext();
    ServletContext context = bundlectx.getService(serviceReference);
    try {
        SessionCookieConfig sessionCookieConfig = context.getSessionCookieConfig();
        sessionCookieConfig.setPath("/");
        sessionCookieConfig.setSecure(true);
        sessionCookieConfig.setHttpOnly(true);
    } catch (Exception e) {
        LOGGER.trace("Failed trying to set the cookie config path to /. This can usually be ignored", e);
    }
    //Jetty will place non-programmatically added filters (filters added via web.xml) in front of programmatically
    //added filters. This is probably OK in most instances, however, this security filter must ALWAYS be first.
    //This reflection hack basically tricks Jetty into believing that this filter is a web.xml filter so that it always ends up first.
    //In order for this to work correctly, the delegating filter must always be added before any other programmatically added filters.
    Field field = null;
    try {
        //this grabs the enclosing instance class, which is actually a private class
        //this is the only way to do this in Java
        field = context.getClass().getDeclaredField("this$0");
        field.setAccessible(true);
    } catch (NoSuchFieldException e) {
        LOGGER.warn("Unable to find enclosing class of ServletContext for delegating filter. Security may not work correctly", e);
    }
    Field matchAfterField = null;
    Object matchAfterValue = null;
    ServletHandler handler = null;
    if (field != null) {
        //need to grab the servlet context handler so we can get down to the handler, which is what we really need
        ServletContextHandler httpServiceContext = null;
        try {
            httpServiceContext = (ServletContextHandler) field.get(context);
        } catch (IllegalAccessException e) {
            LOGGER.warn("Unable to get the ServletContextHandler for {}. The delegating filter may not work properly.", refBundle.getSymbolicName(), e);
        }
        if (httpServiceContext != null) {
            //now that we have the handler, we can muck with the filters and state variables
            handler = httpServiceContext.getServletHandler();
            SessionHandler sessionHandler = httpServiceContext.getSessionHandler();
            if (sessionHandler != null) {
                sessionHandler.addEventListener(new WrapperListener());
            }
            if (handler != null) {
                try {
                    matchAfterField = handler.getClass().getSuperclass().getDeclaredField("_matchAfterIndex");
                    matchAfterField.setAccessible(true);
                } catch (NoSuchFieldException e) {
                    LOGGER.warn("Unable to find the matchAfterIndex value for the ServletHandler. The delegating filter may not work properly.", e);
                }
                if (matchAfterField != null) {
                    try {
                        //this value is initialized to -1 and only changes after a programmatic filter has been added
                        //so basically we are grabbing this value (should be -1) and then setting the field back to that value
                        //after we add our delegating filter to the mix
                        matchAfterValue = matchAfterField.get(handler);
                    } catch (IllegalAccessException e) {
                        LOGGER.warn("Unable to get the value of the match after field. The delegating filter may not work properly.", e);
                    }
                }
            }
        }
    }
    try {
        //This causes the value of "_matchAfterIndex" to jump to 0 which means all web.xml filters will be added in front of it
        //this isn't what we want, so we need to reset it back to what it was before
        FilterRegistration filterReg = context.addFilter(DELEGATING_FILTER, delegatingServletFilter);
        if (filterReg == null) {
            filterReg = context.getFilterRegistration(DELEGATING_FILTER);
        } else {
            ((FilterRegistration.Dynamic) filterReg).setAsyncSupported(true);
        }
        filterReg.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, ALL_URLS);
    } catch (IllegalStateException ise) {
        LOGGER.warn("Could not inject filter into {} because the servlet was already initialized.", refBundle.getSymbolicName(), ise);
    }
    if (matchAfterField != null && matchAfterValue != null) {
        try {
            //Reset the value back to what it was before we added our delegating filter, this should cause Jetty to behave as if
            //this was a filter added via web.xml
            matchAfterField.set(handler, matchAfterValue);
        } catch (IllegalAccessException e) {
            LOGGER.warn("Unable to set the match after field back to the original value. The delegating filter might be out of order", e);
        }
    } else {
        LOGGER.warn("Unable to set the match after field back to the original value. The delegating filter might be out of order.");
    }
}
Also used : SessionHandler(org.eclipse.jetty.server.session.SessionHandler) ServletHandler(org.eclipse.jetty.servlet.ServletHandler) Bundle(org.osgi.framework.Bundle) Field(java.lang.reflect.Field) ServletContext(javax.servlet.ServletContext) SessionCookieConfig(javax.servlet.SessionCookieConfig) ServletContextHandler(org.eclipse.jetty.servlet.ServletContextHandler) BundleContext(org.osgi.framework.BundleContext) FilterRegistration(javax.servlet.FilterRegistration)

Example 13 with ServletHandler

use of org.eclipse.jetty.servlet.ServletHandler in project hive by apache.

the class HttpServer method setupSpnegoFilter.

/**
 * Secure the web server with kerberos (AuthenticationFilter).
 */
void setupSpnegoFilter(Builder b) throws IOException {
    Map<String, String> params = new HashMap<String, String>();
    params.put("kerberos.principal", SecurityUtil.getServerPrincipal(b.spnegoPrincipal, b.host));
    params.put("kerberos.keytab", b.spnegoKeytab);
    params.put(AuthenticationFilter.AUTH_TYPE, "kerberos");
    FilterHolder holder = new FilterHolder();
    holder.setClassName(AuthenticationFilter.class.getName());
    holder.setInitParameters(params);
    ServletHandler handler = webAppContext.getServletHandler();
    handler.addFilterWithMapping(holder, "/*", FilterMapping.ALL);
}
Also used : ServletHandler(org.eclipse.jetty.servlet.ServletHandler) FilterHolder(org.eclipse.jetty.servlet.FilterHolder) HashMap(java.util.HashMap) AuthenticationFilter(org.apache.hadoop.security.authentication.server.AuthenticationFilter)

Example 14 with ServletHandler

use of org.eclipse.jetty.servlet.ServletHandler in project tutorials by eugenp.

the class JettyServer method start.

void start() throws Exception {
    int maxThreads = 100;
    int minThreads = 10;
    int idleTimeout = 120;
    QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads, minThreads, idleTimeout);
    server = new Server(threadPool);
    ServerConnector connector = new ServerConnector(server);
    connector.setPort(8090);
    server.setConnectors(new Connector[] { connector });
    ServletHandler servletHandler = new ServletHandler();
    server.setHandler(servletHandler);
    servletHandler.addServletWithMapping(BlockingServlet.class, "/status");
    servletHandler.addServletWithMapping(AsyncServlet.class, "/heavy/async");
    server.start();
}
Also used : ServerConnector(org.eclipse.jetty.server.ServerConnector) ServletHandler(org.eclipse.jetty.servlet.ServletHandler) Server(org.eclipse.jetty.server.Server) QueuedThreadPool(org.eclipse.jetty.util.thread.QueuedThreadPool)

Example 15 with ServletHandler

use of org.eclipse.jetty.servlet.ServletHandler in project i2p.i2p by i2p.

the class RouterConsoleRunner method startConsole.

/**
 *  http://irc.codehaus.org/display/JETTY/Porting+to+jetty6
 *
 *<pre>
 *	Server
 *		HandlerCollection
 *			HostCheckHandler (extends GzipHandler)
 *				ContextHandlerCollection
 *					LocaleWebAppHandler (routerconsole)
 *						SessionHandler
 *						SecurityHandler
 *						ServletHandler
 *							servlets...
 *					WebAppContext (i2psnark)
 *					WebAppContext (i2ptunnel)
 *					WebAppContext (imagegen)
 *					WebAppContext (susidns)
 *					WebAppContext (susimail)
 *					WebAppContext (for each plugin with a .war)
 *			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");
    boolean workDirRemoved = FileUtil.rmdir(workDir, false);
    if (!workDirRemoved)
        System.err.println("ERROR: Unable to remove Jetty temporary work directory");
    boolean workDirCreated = workDir.mkdirs();
    if (!workDirCreated)
        System.err.println("ERROR: Unable to create Jetty temporary work directory");
    // so Jetty can find WebAppConfiguration
    System.setProperty("jetty.class.path", _context.getBaseDir() + "/lib/routerconsole.jar");
    // 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,
    // and a RejectedExecutionPolicy of CallerRuns.
    // Unfortunately, CallerRuns causes lockups in Jetty NIO (ticket #1395)
    // In addition, no flavor of TPE gives us what QTP does:
    // - TPE direct handoff (which we were using) never queues.
    // This doesn't provide any burst management when maxThreads is reached.
    // CallerRuns was an attempt to work around that.
    // - TPE unbounded queue does not adjust the number of threads.
    // This doesn't provide automatic resource management.
    // - TPE bounded queue does not add threads until the queue is full.
    // This doesn't provide good responsiveness to even small bursts.
    // QTP adds threads as soon as the queue is non-empty.
    // QTP as of Jetty 7 uses concurrent.
    // QTP unbounded queue is the default in Jetty.
    // So switch back to QTP with a bounded queue.
    // 
    // ref:
    // http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html
    // https://wiki.eclipse.org/Jetty/Howto/High_Load
    // 
    // try {
    // ThreadPool ctp = new CustomThreadPoolExecutor();
    // // Gone in Jetty 7
    // //ctp.prestartAllCoreThreads();
    // _server.setThreadPool(ctp);
    // } catch (Throwable t) {
    // class not found...
    // System.out.println("INFO: Jetty concurrent ThreadPool unavailable, using QueuedThreadPool");
    LinkedBlockingQueue<Runnable> lbq = new LinkedBlockingQueue<Runnable>(4 * MAX_THREADS);
    // 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 = new Server(qtp);
    // }
    HandlerCollection hColl = new HandlerCollection();
    ContextHandlerCollection chColl = new ContextHandlerCollection();
    HostCheckHandler chCollWrapper = new HostCheckHandler(_context);
    chCollWrapper.setHandler(chColl);
    // gone in Jetty 7
    // _server.addHandler(hColl);
    _server.setHandler(hColl);
    hColl.addHandler(chCollWrapper);
    hColl.addHandler(new DefaultHandler());
    String log = _context.getProperty("routerconsole.log");
    if (log != null) {
        File logFile = new File(log);
        if (!logFile.isAbsolute())
            logFile = new File(_context.getLogDir(), "logs/" + log);
        try {
            RequestLogHandler rhl = new RequestLogHandler();
            rhl.setRequestLog(new NCSARequestLog(logFile.getAbsolutePath()));
            hColl.addHandler(rhl);
        } catch (Exception ioe) {
            System.err.println("ERROR: Unable to create Jetty log: " + ioe);
        }
    }
    boolean rewrite = false;
    Properties props = webAppProperties();
    if (props.isEmpty()) {
        props.setProperty(PREFIX + ROUTERCONSOLE + ENABLED, "true");
        rewrite = true;
    }
    // Get an absolute path with a trailing slash for the webapps dir
    // We assume relative to the base install dir for backward compatibility
    File app = new File(_webAppsDir);
    if (!app.isAbsolute()) {
        app = new File(_context.getBaseDir(), _webAppsDir);
        try {
            _webAppsDir = app.getCanonicalPath();
        } catch (IOException ioe) {
        }
    }
    if (!_webAppsDir.endsWith("/"))
        _webAppsDir += '/';
    Set<String> listenHosts = new HashSet<String>(8);
    HandlerWrapper rootWebApp = null;
    ServletHandler rootServletHandler = null;
    List<Connector> connectors = new ArrayList<Connector>(4);
    try {
        int boundAddresses = 0;
        SortedSet<String> addresses = Addresses.getAllAddresses();
        boolean hasIPV4 = addresses.contains("0.0.0.0");
        boolean hasIPV6 = addresses.contains("0:0:0:0:0:0:0:0");
        // add standard listeners
        int lport = 0;
        if (_listenPort != null) {
            try {
                lport = Integer.parseInt(_listenPort);
            } catch (NumberFormatException nfe) {
            }
            if (lport <= 0)
                System.err.println("Bad routerconsole port " + _listenPort);
        }
        if (lport > 0) {
            List<String> hosts = new ArrayList<String>(2);
            StringTokenizer tok = new StringTokenizer(_listenHost, " ,");
            while (tok.hasMoreTokens()) {
                String host = tok.nextToken().trim();
                try {
                    // connectors are bad
                    if ((!hasIPV6) && Addresses.isIPv6Address(host))
                        throw new IOException("IPv6 addresses unsupported");
                    if ((!hasIPV4) && Addresses.isIPv4Address(host))
                        throw new IOException("IPv4 addresses unsupported");
                    ServerSocket testSock = null;
                    try {
                        // On Windows, this was passing and Jetty was still failing,
                        // possibly due to %scope_id ???
                        // https://issues.apache.org/jira/browse/ZOOKEEPER-667
                        // so do exactly what Jetty does in SelectChannelConnector.open()
                        testSock = new ServerSocket();
                        InetSocketAddress isa = new InetSocketAddress(host, 0);
                        testSock.bind(isa);
                    } finally {
                        if (testSock != null)
                            try {
                                testSock.close();
                            } catch (IOException ioe) {
                            }
                    }
                    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);
                    // default 10 sec
                    lsnr.setIdleTimeout(90 * 1000);
                    // all with same name will use the same thread pool
                    lsnr.setName("ConsoleSocket");
                    // _server.addConnector(lsnr);
                    connectors.add(lsnr);
                    boundAddresses++;
                    hosts.add(host);
                } catch (Exception ioe) {
                    System.err.println("Unable to bind routerconsole to " + host + " port " + _listenPort + ": " + ioe);
                    System.err.println("You may ignore this warning if the console is still available at http://localhost:" + _listenPort);
                }
            }
            if (hosts.isEmpty()) {
                _context.portMapper().register(PortMapper.SVC_CONSOLE, lport);
            } else {
                // put IPv4 first
                Collections.sort(hosts, new HostComparator());
                _context.portMapper().register(PortMapper.SVC_CONSOLE, hosts.get(0), lport);
                // note that we could still fail in connector.start() below
                listenHosts.addAll(hosts);
            }
        }
        // add SSL listeners
        int sslPort = 0;
        if (_sslListenPort != null) {
            try {
                sslPort = Integer.parseInt(_sslListenPort);
            } catch (NumberFormatException nfe) {
            }
            if (sslPort <= 0)
                System.err.println("Bad routerconsole SSL port " + _sslListenPort);
        }
        if (sslPort > 0) {
            File keyStore = new File(_context.getConfigDir(), "keystore/console.ks");
            // Put the list of hosts together early, so we can put it in the selfsigned cert.
            StringTokenizer tok = new StringTokenizer(_sslListenHost, " ,");
            Set<String> altNames = new HashSet<String>(4);
            while (tok.hasMoreTokens()) {
                String s = tok.nextToken().trim();
                if (!s.equals("0.0.0.0") && !s.equals("::") && !s.equals("0:0:0:0:0:0:0:0"))
                    altNames.add(s);
            }
            String allowed = _context.getProperty(PROP_ALLOWED_HOSTS);
            if (allowed != null) {
                tok = new StringTokenizer(allowed, " ,");
                while (tok.hasMoreTokens()) {
                    altNames.add(tok.nextToken().trim());
                }
            }
            if (verifyKeyStore(keyStore, altNames)) {
                // the keystore path and password
                SslContextFactory sslFactory = new SslContextFactory(keyStore.getAbsolutePath());
                sslFactory.setKeyStorePassword(_context.getProperty(PROP_KEYSTORE_PASSWORD, KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD));
                // the X.509 cert password (if not present, verifyKeyStore() returned false)
                sslFactory.setKeyManagerPassword(_context.getProperty(PROP_KEY_PASSWORD, "thisWontWork"));
                sslFactory.addExcludeProtocols(I2PSSLSocketFactory.EXCLUDE_PROTOCOLS.toArray(new String[I2PSSLSocketFactory.EXCLUDE_PROTOCOLS.size()]));
                sslFactory.addExcludeCipherSuites(I2PSSLSocketFactory.EXCLUDE_CIPHERS.toArray(new String[I2PSSLSocketFactory.EXCLUDE_CIPHERS.size()]));
                List<String> hosts = new ArrayList<String>(2);
                tok = new StringTokenizer(_sslListenHost, " ,");
                while (tok.hasMoreTokens()) {
                    String host = tok.nextToken().trim();
                    // doing it this way means we don't have to escape an IPv6 host with []
                    try {
                        // connectors are bad
                        if ((!hasIPV6) && Addresses.isIPv6Address(host))
                            throw new IOException("IPv6 addresses unsupported");
                        if ((!hasIPV4) && Addresses.isIPv4Address(host))
                            throw new IOException("IPv4 addresses unsupported");
                        ServerSocket testSock = null;
                        try {
                            // see comments above
                            testSock = new ServerSocket();
                            InetSocketAddress isa = new InetSocketAddress(host, 0);
                            testSock.bind(isa);
                        } finally {
                            if (testSock != null)
                                try {
                                    testSock.close();
                                } catch (IOException ioe) {
                                }
                        }
                        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);
                        // default 10 sec
                        ssll.setIdleTimeout(90 * 1000);
                        // all with same name will use the same thread pool
                        ssll.setName("ConsoleSocket");
                        // _server.addConnector(ssll);
                        connectors.add(ssll);
                        boundAddresses++;
                        hosts.add(host);
                    } catch (Exception e) {
                        System.err.println("Unable to bind routerconsole to " + host + " port " + sslPort + " for SSL: " + e);
                        if (SystemVersion.isGNU())
                            System.err.println("Probably because GNU classpath does not support Sun keystores");
                        System.err.println("You may ignore this warning if the console is still available at https://localhost:" + sslPort);
                    }
                }
                if (hosts.isEmpty()) {
                    _context.portMapper().register(PortMapper.SVC_HTTPS_CONSOLE, sslPort);
                } else {
                    // put IPv4 first
                    Collections.sort(hosts, new HostComparator());
                    _context.portMapper().register(PortMapper.SVC_HTTPS_CONSOLE, hosts.get(0), sslPort);
                    // note that we could still fail in connector.start() below
                    listenHosts.addAll(hosts);
                }
            } else {
                System.err.println("Unable to create or access keystore for SSL: " + keyStore.getAbsolutePath());
            }
        }
        if (boundAddresses <= 0) {
            System.err.println("Unable to bind routerconsole to any address on port " + _listenPort + (sslPort > 0 ? (" or SSL port " + sslPort) : ""));
            return;
        }
        // Each address spawns a Connector and an Acceptor thread
        // If the min is less than this, we have no thread for the handlers or the expiration thread.
        qtp.setMinThreads(MIN_THREADS + (2 * boundAddresses));
        qtp.setMaxThreads(MAX_THREADS + (2 * boundAddresses));
        File tmpdir = new SecureDirectory(workDir, ROUTERCONSOLE + "-" + (_listenPort != null ? _listenPort : _sslListenPort));
        tmpdir.mkdir();
        rootServletHandler = new ServletHandler();
        rootWebApp = new LocaleWebAppHandler(_context, "/", _webAppsDir + ROUTERCONSOLE + ".war", tmpdir, rootServletHandler);
        try {
            // Not sure who is supposed to call this, but unless we do,
            // all the jsps die NPE, because JspFactory.getDefaultContext() returns null.
            // We probably have to do this because we don't bundle the Jetty annotations jar and scanner.
            // This is only with Tomcat 8, not with the Jetty (Eclipse) jsp impl.
            // Got a clue from this ancient post for Tomcat 6:
            // https://bz.apache.org/bugzilla/show_bug.cgi?id=39804
            // see also apps/jetty/build.xml
            Class.forName("org.eclipse.jetty.apache.jsp.JettyJasperInitializer");
        } catch (ClassNotFoundException cnfe) {
            System.err.println("Warning: JettyJasperInitializer not found");
        }
        WebAppContext wac = (WebAppContext) (rootWebApp.getHandler());
        initialize(_context, wac);
        WebAppStarter.setWebAppConfiguration(wac);
        chColl.addHandler(rootWebApp);
    } catch (Exception ioe) {
        ioe.printStackTrace();
    }
    // fix up the allowed hosts set (see HostCheckHandler)
    if (listenHosts.contains("0.0.0.0") || listenHosts.contains("::") || listenHosts.contains("0:0:0:0:0:0:0:0")) {
        // empty set says all are valid
        listenHosts.clear();
    } else {
        listenHosts.add("localhost");
        listenHosts.add("127.0.0.1");
        listenHosts.add("::1");
        listenHosts.add("0:0:0:0:0:0:0:1");
        String allowed = _context.getProperty(PROP_ALLOWED_HOSTS);
        if (allowed != null) {
            StringTokenizer tok = new StringTokenizer(allowed, " ,");
            while (tok.hasMoreTokens()) {
                listenHosts.add(tok.nextToken());
            }
        }
    }
    chCollWrapper.setListenHosts(listenHosts);
    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=364936
    // WARN:oejw.WebAppContext:Failed startup of context o.e.j.w.WebAppContext{/,jar:file:/.../webapps/routerconsole.war!/},/.../webapps/routerconsole.war
    // java.lang.IllegalStateException: zip file closed
    Resource.setDefaultUseCaches(false);
    try {
        // start does a mapContexts()
        _server.start();
    } catch (Throwable me) {
        // NoClassFoundDefError from a webapp is a throwable, not an exception
        System.err.println("Error starting the Router Console server: " + me);
        me.printStackTrace();
    }
    if (_server.isRunning()) {
        // Add and start the connectors one-by-one
        boolean error = false;
        for (Connector conn : connectors) {
            try {
                _server.addConnector(conn);
                // start after adding so it gets the right thread pool
                conn.start();
            } catch (Throwable me) {
                try {
                    _server.removeConnector(conn);
                } catch (Throwable t) {
                    t.printStackTrace();
                }
                System.err.println("WARNING: Error starting " + conn + ": " + me);
                me.printStackTrace();
                error = true;
            }
        }
        if (error) {
            String port = (_listenPort != null) ? _listenPort : ((_sslListenPort != null) ? _sslListenPort : Integer.toString(DEFAULT_LISTEN_PORT));
            System.err.println("WARNING: Error starting one or more listeners of the Router Console server.\n" + "If your console is still accessible at http://127.0.0.1:" + port + "/,\n" + "this may be a problem only with binding to the IPV6 address ::1.\n" + "If so, you may ignore this error, or remove the\n" + "\"::1,\" in the \"clientApp.0.args\" line of the clients.config file.");
        }
    }
    // Start all the other webapps after the server is up,
    // so things start faster.
    // Jetty 6 starts the connector before the router console is ready
    // This also prevents one webapp from breaking the whole thing
    List<String> notStarted = new ArrayList<String>();
    if (_server.isRunning()) {
        File dir = new File(_webAppsDir);
        File[] files = dir.listFiles(WAR_FILTER);
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                String appName = files[i].getName();
                appName = appName.substring(0, appName.lastIndexOf(".war"));
                String enabled = props.getProperty(PREFIX + appName + ENABLED);
                if (appName.equals("addressbook")) {
                    // addressbook.war is now empty, thread is started by SusiDNS
                    if (enabled != null) {
                        props.remove(PREFIX + "addressbook" + ENABLED);
                        rewrite = true;
                    }
                } else if (!"false".equals(enabled)) {
                    try {
                        String path = files[i].getCanonicalPath();
                        WebAppStarter.startWebApp(_context, chColl, appName, path);
                        if (enabled == null) {
                            // do this so configclients.jsp knows about all apps from reading the config
                            props.setProperty(PREFIX + appName + ENABLED, "true");
                            rewrite = true;
                        }
                    } catch (Throwable t) {
                        System.err.println("ERROR: Failed to start " + appName + ' ' + t);
                        t.printStackTrace();
                        notStarted.add(appName);
                    }
                } else {
                    notStarted.add(appName);
                }
            }
            changeState(RUNNING);
            if (_mgr != null)
                _mgr.register(this);
        }
    } else {
        System.err.println("ERROR: Router console did not start, not starting webapps");
        changeState(START_FAILED);
    }
    if (rewrite)
        storeWebAppProperties(_context, props);
    if (rootServletHandler != null && notStarted.size() > 0) {
        // map each not-started webapp to the error page
        ServletHolder noWebApp = rootServletHandler.getServlet("net.i2p.router.web.jsp.nowebapp_jsp");
        for (int i = 0; i < notStarted.size(); i++) {
            // we want a new handler for each one since if the webapp is started we remove the handler???
            try {
                if (noWebApp != null) {
                    String path = '/' + notStarted.get(i);
                    // LocaleWebAppsHandler adds a .jsp
                    rootServletHandler.addServletWithMapping(noWebApp, path + ".jsp");
                    rootServletHandler.addServletWithMapping(noWebApp, path + "/*");
                } else {
                    System.err.println("Can't find nowebapp.jsp?");
                }
            } catch (Throwable me) {
                System.err.println(me);
                me.printStackTrace();
            }
        }
    }
    Thread t = new I2PAppThread(new StatSummarizer(), "StatSummarizer", true);
    t.setPriority(Thread.NORM_PRIORITY - 1);
    t.start();
    ConsoleUpdateManager um = new ConsoleUpdateManager(_context, _mgr, null);
    um.start();
    NewsManager nm = new NewsManager(_context, _mgr, null);
    nm.startup();
    if (PluginStarter.pluginsEnabled(_context)) {
        t = new I2PAppThread(new PluginStarter(_context), "PluginStarter", true);
        t.setPriority(Thread.NORM_PRIORITY - 1);
        t.start();
    }
    // RouterAppManager registers its own hook
    if (_mgr == null)
        _context.addShutdownTask(new ServerShutdown());
    ConfigServiceHandler.registerSignalHandler(_context);
}
Also used : Server(org.eclipse.jetty.server.Server) InetSocketAddress(java.net.InetSocketAddress) ArrayList(java.util.ArrayList) ContextHandlerCollection(org.eclipse.jetty.server.handler.ContextHandlerCollection) HttpConfiguration(org.eclipse.jetty.server.HttpConfiguration) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) ServerConnector(org.eclipse.jetty.server.ServerConnector) WebAppContext(org.eclipse.jetty.webapp.WebAppContext) NewsManager(net.i2p.router.news.NewsManager) HashSet(java.util.HashSet) File(java.io.File) AbstractConnector(org.eclipse.jetty.server.AbstractConnector) ServerConnector(org.eclipse.jetty.server.ServerConnector) Connector(org.eclipse.jetty.server.Connector) ServletHandler(org.eclipse.jetty.servlet.ServletHandler) ServletHolder(org.eclipse.jetty.servlet.ServletHolder) Properties(java.util.Properties) SslConnectionFactory(org.eclipse.jetty.server.SslConnectionFactory) HandlerWrapper(org.eclipse.jetty.server.handler.HandlerWrapper) I2PAppThread(net.i2p.util.I2PAppThread) SslContextFactory(org.eclipse.jetty.util.ssl.SslContextFactory) QueuedThreadPool(org.eclipse.jetty.util.thread.QueuedThreadPool) RequestLogHandler(org.eclipse.jetty.server.handler.RequestLogHandler) NCSARequestLog(org.eclipse.jetty.server.NCSARequestLog) ContextHandlerCollection(org.eclipse.jetty.server.handler.ContextHandlerCollection) HandlerCollection(org.eclipse.jetty.server.handler.HandlerCollection) SecureRequestCustomizer(org.eclipse.jetty.server.SecureRequestCustomizer) HttpConnectionFactory(org.eclipse.jetty.server.HttpConnectionFactory) ServerSocket(java.net.ServerSocket) ConsoleUpdateManager(net.i2p.router.update.ConsoleUpdateManager) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) Constraint(org.eclipse.jetty.util.security.Constraint) DefaultHandler(org.eclipse.jetty.server.handler.DefaultHandler) I2PAppThread(net.i2p.util.I2PAppThread) StringTokenizer(java.util.StringTokenizer) SecureDirectory(net.i2p.util.SecureDirectory)

Aggregations

ServletHandler (org.eclipse.jetty.servlet.ServletHandler)54 Server (org.eclipse.jetty.server.Server)23 ServletHolder (org.eclipse.jetty.servlet.ServletHolder)22 ServerConnector (org.eclipse.jetty.server.ServerConnector)11 ServletContextHandler (org.eclipse.jetty.servlet.ServletContextHandler)10 Test (org.junit.Test)10 FilterHolder (org.eclipse.jetty.servlet.FilterHolder)8 MockFlowFile (org.apache.nifi.util.MockFlowFile)5 ContextHandlerCollection (org.eclipse.jetty.server.handler.ContextHandlerCollection)5 HashMap (java.util.HashMap)4 HttpServletRequest (javax.servlet.http.HttpServletRequest)4 HttpServletResponse (javax.servlet.http.HttpServletResponse)4 FilterMapping (org.eclipse.jetty.servlet.FilterMapping)4 UnsupportedEncodingException (java.io.UnsupportedEncodingException)3 InetSocketAddress (java.net.InetSocketAddress)3 HttpServlet (javax.servlet.http.HttpServlet)3 ServletMapping (org.eclipse.jetty.servlet.ServletMapping)3 SslContextFactory (org.eclipse.jetty.util.ssl.SslContextFactory)3 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2