Search in sources :

Example 21 with UndertowXnioSsl

use of io.undertow.protocols.ssl.UndertowXnioSsl in project runwar by cfmlprojects.

the class Server method startServer.

public synchronized void startServer(final ServerOptions options) throws Exception {
    serverOptions = (ServerOptionsImpl) options;
    LoggerFactory.init(serverOptions);
    serverState = ServerState.STARTING;
    if (serverOptions.getAction().equals("stop")) {
        Stop.stopServer(serverOptions, true);
    }
    serverName = serverOptions.getServerName();
    portNumber = serverOptions.getPortNumber();
    socketNumber = serverOptions.getSocketNumber();
    String cfengine = serverOptions.getCFEngineName();
    String processName = serverOptions.getProcessName();
    String contextPath = serverOptions.getContextPath();
    String host = serverOptions.getHost();
    File warFile = serverOptions.getWarFile();
    if (serverOptions.getStatusFile() != null) {
        statusFile = serverOptions.getStatusFile();
    }
    String warPath = serverOptions.getWarPath();
    char[] stoppassword = serverOptions.getStopPassword();
    boolean ignoreWelcomePages = false;
    boolean ignoreRestMappings = false;
    LOG.info("Starting RunWAR " + getVersion());
    // unset this so thing that reconfigure will find theirs
    System.setProperty("log4j.configuration", "");
    ensureJavaVersion();
    securityManager = new SecurityManager();
    if (serverOptions.isBackground()) {
        setServerState(ServerState.STARTING_BACKGROUND);
        // this will eventually system.exit();
        LaunchUtil.relaunchAsBackgroundProcess(serverOptions.setBackground(false), true);
        setServerState(ServerState.STARTED_BACKGROUND);
        // just in case
        Thread.sleep(200);
        System.exit(0);
    }
    // if the war is archived, unpack it to system temp
    if (warFile.exists() && !warFile.isDirectory()) {
        URL zipResource = warFile.toURI().toURL();
        String warDir = warFile.getName().toLowerCase().replace(".war", "");
        warFile = new File(warFile.getParentFile(), warDir);
        if (!warFile.exists()) {
            warFile.mkdir();
            LOG.debug("Exploding compressed WAR to " + warFile.getAbsolutePath());
            LaunchUtil.unzipResource(zipResource, warFile, false);
        } else {
            LOG.debug("Using already exploded WAR in " + warFile.getAbsolutePath());
        }
        warPath = warFile.getAbsolutePath();
        if (serverOptions.getWarFile().getAbsolutePath().equals(serverOptions.getCfmlDirs())) {
            serverOptions.setCfmlDirs(warFile.getAbsolutePath());
        }
    }
    if (!warFile.exists()) {
        throw new RuntimeException("war does not exist: " + warFile.getAbsolutePath());
    }
    File webinf = serverOptions.getWebInfDir();
    File webXmlFile = serverOptions.getWebXmlFile();
    String libDirs = serverOptions.getLibDirs();
    URL jarURL = serverOptions.getJarURL();
    // If this folder is a proper war, add its WEB-INF/lib folder to the passed libDirs
    if (warFile.isDirectory() && webXmlFile != null && webXmlFile.exists()) {
        if (libDirs == null) {
            libDirs = "";
        } else if (libDirs.length() > 0) {
            libDirs = libDirs + ",";
        }
        libDirs = libDirs + webinf.getAbsolutePath() + "/lib";
        LOG.info("Adding additional lib dir of: " + webinf.getAbsolutePath() + "/lib");
    }
    List<URL> cp = new ArrayList<URL>();
    // cp.add(Server.class.getProtectionDomain().getCodeSource().getLocation());
    if (libDirs != null)
        cp.addAll(getJarList(libDirs));
    if (jarURL != null)
        cp.add(jarURL);
    if (serverOptions.getMariaDB4jImportSQLFile() != null) {
        System.out.println("ADDN" + serverOptions.getMariaDB4jImportSQLFile().toURI().toURL());
        cp.add(serverOptions.getMariaDB4jImportSQLFile().toURI().toURL());
    }
    cp.addAll(getClassesList(new File(webinf, "/classes")));
    initClassLoader(cp);
    serverMode = Mode.WAR;
    if (!webinf.exists()) {
        serverMode = Mode.DEFAULT;
        if (getCFMLServletClass(cfengine) != null) {
            serverMode = Mode.SERVLET;
        }
    }
    LOG.debugf("Server Mode: %s", serverMode);
    sysOutTee = null;
    sysErrTee = null;
    String osName = System.getProperties().getProperty("os.name");
    String iconPNG = System.getProperty("cfml.server.trayicon");
    if (iconPNG != null && iconPNG.length() > 0) {
        serverOptions.setIconImage(iconPNG);
    }
    String dockIconPath = System.getProperty("cfml.server.dockicon");
    if (dockIconPath == null || dockIconPath.length() == 0) {
        dockIconPath = serverOptions.getIconImage();
    }
    if (osName != null && osName.startsWith("Mac OS X")) {
        Image dockIcon = Tray.getIconImage(dockIconPath);
        System.setProperty("com.apple.mrj.application.apple.menu.about.name", processName);
        System.setProperty("com.apple.mrj.application.growbox.intrudes", "false");
        System.setProperty("apple.laf.useScreenMenuBar", "true");
        System.setProperty("-Xdock:name", processName);
        try {
            Class<?> appClass = Class.forName("com.apple.eawt.Application");
            Method getAppMethod = appClass.getMethod("getApplication");
            Object appInstance = getAppMethod.invoke(null);
            Method dockMethod = appInstance.getClass().getMethod("setDockIconImage", java.awt.Image.class);
            dockMethod.invoke(appInstance, dockIcon);
        } catch (Exception e) {
            LOG.warn("error setting dock icon image", e);
        }
    }
    LOG.info(bar);
    LOG.info("Starting - port:" + portNumber + " stop-port:" + socketNumber + " warpath:" + warPath);
    LOG.info("context: " + contextPath + "  -  version: " + getVersion());
    String cfmlDirs = serverOptions.getCfmlDirs();
    if (cfmlDirs.length() > 0) {
        LOG.info("web-dirs: " + cfmlDirs);
    }
    LOG.info("Log Directory: " + serverOptions.getLogDir().getAbsolutePath());
    LOG.info(bar);
    addShutDownHook();
    portNumber = getPortOrErrorOut(portNumber, host);
    socketNumber = getPortOrErrorOut(socketNumber, host);
    LOG.info("Adding mariadb manager");
    mariadb4jManager = new MariaDB4jManager(_classLoader);
    if (serverOptions.getWelcomeFiles() != null && serverOptions.getWelcomeFiles().length > 0) {
        ignoreWelcomePages = true;
    } else {
        serverOptions.setWelcomeFiles(defaultWelcomeFiles);
    }
    if (serverOptions.getServletRestMappings() != null && serverOptions.getServletRestMappings().length > 0) {
        ignoreRestMappings = true;
    }
    LOG.debug("Transfer Min Size: " + serverOptions.getTransferMinSize());
    xnio = Xnio.getInstance("nio", Server.class.getClassLoader());
    worker = xnio.createWorker(OptionMap.builder().set(Options.WORKER_IO_THREADS, 8).set(Options.CONNECTION_HIGH_WATER, 1000000).set(Options.CONNECTION_LOW_WATER, 1000000).set(Options.WORKER_TASK_CORE_THREADS, 30).set(Options.WORKER_TASK_MAX_THREADS, 30).set(Options.TCP_NODELAY, true).set(Options.CORK, true).getMap());
    final DeploymentInfo servletBuilder = deployment().setContextPath(contextPath.equals("/") ? "" : contextPath).setTempDir(new File(System.getProperty("java.io.tmpdir"))).setDeploymentName(warPath).setServerName("WildFly / Undertow");
    // hack to prevent . being picked up as the system path (jacob.x.dll)
    if (System.getProperty("java.library.path") == null) {
        if (webXmlFile != null) {
            System.setProperty("java.library.path", getThisJarLocation().getPath() + ':' + new File(webXmlFile.getParentFile(), "lib").getPath());
        } else {
            System.setProperty("java.library.path", getThisJarLocation().getPath() + ':' + new File(warFile, "/WEB-INF/lib/").getPath());
        }
    } else {
        System.setProperty("java.library.path", getThisJarLocation().getPath() + System.getProperty("path.separator") + System.getProperty("java.library.path"));
    }
    LOG.trace("java.library.path:" + System.getProperty("java.library.path"));
    final SessionCookieConfig sessionConfig = new SessionCookieConfig();
    final SessionAttachmentHandler sessionAttachmentHandler = new SessionAttachmentHandler(new InMemorySessionManager("", 1, true), sessionConfig);
    configureServerResourceHandler(servletBuilder, sessionConfig, warFile, webinf, webXmlFile, cfmlDirs, cfengine, ignoreWelcomePages, ignoreRestMappings);
    if (cfengine.equals("adobe")) {
        String cfclassesDir = (String) servletBuilder.getServletContextAttributes().get("coldfusion.compiler.outputDir");
        if (cfclassesDir == null || cfclassesDir.startsWith("/WEB-INF")) {
            // TODO: figure out why adobe needs the absolute path, vs. /WEB-INF/cfclasses
            File cfclassesDirFile = new File(webinf, "/cfclasses");
            cfclassesDir = cfclassesDirFile.getAbsolutePath();
            LOG.debug("ADOBE - coldfusion.compiler.outputDir set to " + cfclassesDir);
            if (!cfclassesDirFile.exists()) {
                cfclassesDirFile.mkdir();
            }
            servletBuilder.addServletContextAttribute("coldfusion.compiler.outputDir", cfclassesDir);
        }
    }
    if (serverOptions.isEnableBasicAuth()) {
        securityManager.configureAuth(servletBuilder, serverOptions);
    }
    configureURLRewrite(servletBuilder, webinf);
    configurePathInfoFilter(servletBuilder);
    if (serverOptions.isCacheEnabled()) {
        addCacheHandler(servletBuilder);
    } else {
        LOG.debug("File cache is disabled");
    }
    if (serverOptions.isCustomHTTPStatusEnabled()) {
        servletBuilder.setSendCustomReasonPhraseOnError(true);
    }
    if (serverOptions.getErrorPages() != null) {
        for (Integer errorCode : serverOptions.getErrorPages().keySet()) {
            String location = serverOptions.getErrorPages().get(errorCode);
            if (errorCode == 1) {
                servletBuilder.addErrorPage(new ErrorPage(location));
                LOG.debug("Adding default error location: " + location);
            } else {
                servletBuilder.addErrorPage(new ErrorPage(location, errorCode));
                LOG.debug("Adding " + errorCode + " error code location: " + location);
            }
        }
    }
    // someday we may wanna listen for changes
    /*
        servletBuilder.getResourceManager().registerResourceChangeListener(new ResourceChangeListener() {
            @Override
            public void handleChanges(Collection<ResourceChangeEvent> changes) {
                for(ResourceChangeEvent change : changes) {
                    RunwarLogger.ROOT_LOGGER.info("CHANGE");
                    RunwarLogger.ROOT_LOGGER.info(change.getResource());
                    RunwarLogger.ROOT_LOGGER.info(change.getType().name());
                    manager.getDeployment().getServletPaths().invalidate();
                }
            }
        });
        */
    // this prevents us from having to use our own ResourceHandler (directory listing, welcome files, see below) and error handler for now
    servletBuilder.addServlet(new ServletInfo(io.undertow.servlet.handlers.ServletPathMatches.DEFAULT_SERVLET_NAME, DefaultServlet.class).addInitParam("directory-listing", Boolean.toString(serverOptions.isDirectoryListingEnabled())));
    // servletBuilder.setExceptionHandler(LoggingExceptionHandler.DEFAULT);
    List<?> welcomePages = servletBuilder.getWelcomePages();
    if (ignoreWelcomePages) {
        LOG.debug("Ignoring web.xml welcome file, so adding server options welcome files to deployment manager.");
        servletBuilder.addWelcomePages(serverOptions.getWelcomeFiles());
    } else if (welcomePages.size() == 0) {
        LOG.debug("No welcome pages set yet, so adding defaults to deployment manager.");
        servletBuilder.addWelcomePages(defaultWelcomeFiles);
    }
    LOG.info("welcome pages in deployment manager: " + servletBuilder.getWelcomePages());
    if (ignoreRestMappings) {
        LOG.info("Overriding web.xml rest mappings with " + Arrays.toString(serverOptions.getServletRestMappings()));
        Iterator<Entry<String, ServletInfo>> it = servletBuilder.getServlets().entrySet().iterator();
        while (it.hasNext()) {
            ServletInfo restServlet = it.next().getValue();
            LOG.trace("Checking servelet named: " + restServlet.getName() + "to see if it's a REST servlet.");
            if (restServlet.getName().toLowerCase().equals("restservlet") || restServlet.getName().toLowerCase().equals("cfrestservlet")) {
                for (String path : serverOptions.getServletRestMappings()) {
                    restServlet.addMapping(path);
                    LOG.info("Added rest mapping: " + path + " to " + restServlet.getName());
                }
            }
        }
    }
    // TODO: probably best to create a new worker for websockets, if we want fastness, but for now we share
    // TODO: add buffer pool size (maybe-- direct is best at 16k), enable/disable be good I reckon tho
    servletBuilder.addServletContextAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME, new WebSocketDeploymentInfo().setBuffers(new DefaultByteBufferPool(true, 1024 * 16)).setWorker(worker));
    LOG.debug("Added websocket context");
    manager = defaultContainer().addDeployment(servletBuilder);
    manager.deploy();
    HttpHandler servletHandler = manager.start();
    LOG.debug("started servlet deployment manager");
    /*
        List welcomePages =  manager.getDeployment().getDeploymentInfo().getWelcomePages();
        CFMLResourceHandler resourceHandler = new CFMLResourceHandler(servletBuilder.getResourceManager(), servletHandler, welcomePages);
        resourceHandler.setDirectoryListingEnabled(directoryListingEnabled);
        PathHandler pathHandler = Handlers.path(Handlers.redirect(contextPath))
                .addPrefixPath(contextPath, resourceHandler);
        HttpHandler errPageHandler = new SimpleErrorPageHandler(pathHandler);
        Builder serverBuilder = Undertow.builder().addHttpListener(portNumber, host).setHandler(errPageHandler);
*/
    Builder serverBuilder = Undertow.builder();
    if (serverOptions.isEnableHTTP()) {
        serverBuilder.addHttpListener(portNumber, host);
    }
    if (serverOptions.isHTTP2Enabled()) {
        LOG.info("Enabling HTTP2 protocol");
        LaunchUtil.assertJavaVersion8();
        if (!serverOptions.isEnableSSL()) {
            LOG.warn("SSL is required for HTTP2.  Enabling default SSL server.");
            serverOptions.setEnableSSL(true);
        }
        serverOptions.setSSLPort(serverOptions.getSSLPort() + 1);
        serverBuilder.setServerOption(UndertowOptions.ENABLE_HTTP2, true);
    // serverBuilder.setSocketOption(Options.REUSE_ADDRESSES, true);
    }
    if (serverOptions.isEnableSSL()) {
        int sslPort = serverOptions.getSSLPort();
        serverOptions.setDirectBuffers(true);
        LOG.info("Enabling SSL protocol on port " + sslPort);
        try {
            if (serverOptions.getSSLCertificate() != null) {
                File certfile = serverOptions.getSSLCertificate();
                File keyfile = serverOptions.getSSLKey();
                char[] keypass = serverOptions.getSSLKeyPass();
                String[] sslAddCerts = serverOptions.getSSLAddCerts();
                sslContext = SSLUtil.createSSLContext(certfile, keyfile, keypass, sslAddCerts);
                if (keypass != null)
                    Arrays.fill(keypass, '*');
            } else {
                sslContext = SSLUtil.createSSLContext();
            }
            serverBuilder.addHttpsListener(sslPort, host, sslContext);
        } catch (Exception e) {
            LOG.error("Unable to start SSL:" + e.getMessage());
            e.printStackTrace();
            System.exit(1);
        }
    }
    if (serverOptions.isEnableAJP()) {
        LOG.info("Enabling AJP protocol on port " + serverOptions.getAJPPort());
        serverBuilder.addAjpListener(serverOptions.getAJPPort(), host);
    }
    if (serverOptions.getBufferSize() != 0) {
        LOG.info("Buffer Size: " + serverOptions.getBufferSize());
        serverBuilder.setBufferSize(serverOptions.getBufferSize());
    }
    if (serverOptions.getIoThreads() != 0) {
        LOG.info("IO Threads: " + serverOptions.getIoThreads());
        serverBuilder.setIoThreads(serverOptions.getIoThreads());
    }
    if (serverOptions.getWorkerThreads() != 0) {
        LOG.info("Worker threads: " + serverOptions.getWorkerThreads());
        serverBuilder.setWorkerThreads(serverOptions.getWorkerThreads());
    }
    LOG.info("Direct Buffers: " + serverOptions.isDirectBuffers());
    serverBuilder.setDirectBuffers(serverOptions.isDirectBuffers());
    final PathHandler pathHandler = new PathHandler(Handlers.redirect(contextPath)) {

        @Override
        public void handleRequest(final HttpServerExchange exchange) throws Exception {
            // sessionConfig.setSessionId(exchange, ""); // TODO: see if this suppresses jsessionid
            if (exchange.getRequestPath().endsWith(".svgz")) {
                exchange.getResponseHeaders().put(Headers.CONTENT_ENCODING, "gzip");
            }
            // clear any welcome-file info cached after initial request *NOT THREAD SAFE*
            if (serverOptions.isDirectoryListingRefreshEnabled() && exchange.getRequestPath().endsWith("/")) {
                // RunwarLogger.ROOT_LOGGER.trace("*** Resetting servlet path info");
                manager.getDeployment().getServletPaths().invalidate();
            }
            if (serverOptions.isDebug() && exchange.getRequestPath().endsWith("/dumprunwarrequest")) {
                new RequestDumper().handleRequest(exchange);
            } else {
                super.handleRequest(exchange);
            }
        }
    };
    pathHandler.addPrefixPath(contextPath, servletHandler);
    if (serverOptions.isSecureCookies()) {
        sessionConfig.setHttpOnly(true);
        sessionConfig.setSecure(true);
    }
    sessionAttachmentHandler.setNext(pathHandler);
    HttpHandler errPageHandler;
    if (serverOptions.isGzipEnabled()) {
        final EncodingHandler handler = new EncodingHandler(new ContentEncodingRepository().addEncodingHandler("gzip", new GzipEncodingProvider(), 50, Predicates.parse("max-content-size[5]"))).setNext(pathHandler);
        errPageHandler = new ErrorHandler(handler);
    } else {
        errPageHandler = new ErrorHandler(pathHandler);
    }
    if (serverOptions.logAccessEnable()) {
        // final String PATTERN = "cs-uri cs(test-header) x-O(aa) x-H(secure)";
        DefaultAccessLogReceiver accessLogReceiver = DefaultAccessLogReceiver.builder().setLogWriteExecutor(worker).setOutputDirectory(options.getLogAccessDir().toPath()).setLogBaseName(options.getLogAccessBaseFileName()).build();
        LOG.info("Logging combined access to " + options.getLogAccessDir());
        // errPageHandler = new AccessLogHandler(errPageHandler, logReceiver, PATTERN, new ExtendedAccessLogParser( Server.class.getClassLoader()).parse(PATTERN));
        // errPageHandler = new AccessLogHandler(errPageHandler, logReceiver,"common", Server.class.getClassLoader());
        errPageHandler = new AccessLogHandler(errPageHandler, accessLogReceiver, "combined", Server.class.getClassLoader());
    }
    if (serverOptions.logRequestsEnable()) {
        LOG.error("Request log output currently goes to server.log");
        LOG.debug("Enabling request dumper");
        DefaultAccessLogReceiver requestsLogReceiver = DefaultAccessLogReceiver.builder().setLogWriteExecutor(worker).setOutputDirectory(options.getLogRequestsDir().toPath()).setLogBaseName(options.getLogRequestsBaseFileName()).build();
        errPageHandler = new RequestDebugHandler(errPageHandler, requestsLogReceiver);
    }
    if (serverOptions.isProxyPeerAddressEnabled()) {
        LOG.debug("Enabling Proxy Peer Address handling");
        errPageHandler = new SSLHeaderHandler(new ProxyPeerAddressHandler(errPageHandler));
    }
    Undertow reverseProxy = null;
    if (serverOptions.isHTTP2Enabled()) {
        LOG.debug("Enabling HTTP2 Upgrade and LearningPushHandler");
        /**
         * To not be dependent on java9 or crazy requirements, we set up a proxy to enable http2, and swap it with the actual SSL server (thus the port++/port--)
         */
        errPageHandler = new Http2UpgradeHandler(errPageHandler);
        errPageHandler = Handlers.header(predicate(secure(), errPageHandler, new HttpHandler() {

            @Override
            public void handleRequest(HttpServerExchange exchange) throws Exception {
                exchange.getResponseHeaders().add(Headers.LOCATION, "https://" + exchange.getHostName() + ":" + (serverOptions.getSSLPort() - 1) + exchange.getRelativePath());
                exchange.setStatusCode(StatusCodes.TEMPORARY_REDIRECT);
            }
        }), "x-undertow-transport", ExchangeAttributes.transportProtocol());
        errPageHandler = new SessionAttachmentHandler(new LearningPushHandler(100, -1, errPageHandler), new InMemorySessionManager("runwarsessions"), new SessionCookieConfig());
        LoadBalancingProxyClient proxy = new LoadBalancingProxyClient().addHost(new URI("https://localhost:" + serverOptions.getSSLPort()), null, new UndertowXnioSsl(Xnio.getInstance(), OptionMap.EMPTY, SSLUtil.createClientSSLContext()), OptionMap.create(UndertowOptions.ENABLE_HTTP2, true)).setConnectionsPerThread(20);
        ProxyHandler proxyHandler = ProxyHandler.builder().setProxyClient(proxy).setMaxRequestTime(30000).setNext(ResponseCodeHandler.HANDLE_404).build();
        reverseProxy = Undertow.builder().setServerOption(UndertowOptions.ENABLE_HTTP2, true).addHttpsListener(serverOptions.getSSLPort() - 1, serverOptions.getHost(), sslContext).setHandler(proxyHandler).build();
    }
    if (serverOptions.isEnableBasicAuth()) {
        securityManager.configureAuth(errPageHandler, serverBuilder, options);
    // serverBuilder.setHandler(errPageHandler);
    } else {
        serverBuilder.setHandler(errPageHandler);
    }
    try {
        PID = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
        String pidFile = serverOptions.getPidFile();
        if (pidFile != null && pidFile.length() > 0) {
            File file = new File(pidFile);
            file.deleteOnExit();
            PrintWriter writer = new PrintWriter(file);
            writer.print(PID);
            writer.close();
        }
    } catch (Exception e) {
        LOG.error("Unable to get PID:" + e.getMessage());
    }
    serverBuilder.setWorker(worker);
    undertow = serverBuilder.build();
    // start the stop monitor thread
    assert monitor == null;
    monitor = new MonitorThread(stoppassword);
    monitor.start();
    LOG.debug("started stop monitor");
    if (serverOptions.isTrayEnabled()) {
        try {
            Tray.hookTray(this);
            LOG.debug("hooked system tray");
        } catch (Throwable e) {
            LOG.error("system tray hook failed", e);
        }
    } else {
        LOG.debug("System tray integration disabled");
    }
    if (serverOptions.isOpenbrowser()) {
        LOG.debug("Starting open browser action");
        new Server(3);
    }
    // if this println changes be sure to update the LaunchUtil so it will know success
    String sslInfo = serverOptions.isEnableSSL() ? " https-port:" + serverOptions.getSSLPort() : "";
    String msg = "Server is up - http-port:" + portNumber + sslInfo + " stop-port:" + socketNumber + " PID:" + PID + " version " + getVersion();
    LOG.info(msg);
    System.out.println(msg);
    if (serverOptions.isTrayEnabled()) {
        LaunchUtil.displayMessage("info", msg);
    }
    setServerState(ServerState.STARTED);
    if (serverOptions.isMariaDB4jEnabled()) {
        try {
            mariadb4jManager.start(serverOptions.getMariaDB4jPort(), serverOptions.getMariaDB4jBaseDir(), serverOptions.getMariaDB4jDataDir(), serverOptions.getMariaDB4jImportSQLFile());
        } catch (Exception dbStartException) {
            LOG.error("Could not start MariaDB4j", dbStartException);
            System.out.println("Error starting MariaDB4j: " + dbStartException.getMessage());
        }
    }
    try {
        undertow.start();
        if (serverOptions.isHTTP2Enabled()) {
            LOG.debug("Starting HTTP2 proxy");
            reverseProxy.start();
        }
    } catch (Exception any) {
        if (any.getCause() instanceof java.net.SocketException && any.getCause().getMessage().equals("Permission denied")) {
            System.err.println("You need to be root or Administrator to bind to a port below 1024!");
        } else {
            any.printStackTrace();
        }
        System.exit(1);
    }
}
Also used : ErrorPage(io.undertow.servlet.api.ErrorPage) Builder(io.undertow.Undertow.Builder) ArrayList(java.util.ArrayList) PathHandler(io.undertow.server.handlers.PathHandler) DefaultAccessLogReceiver(io.undertow.server.handlers.accesslog.DefaultAccessLogReceiver) Image(java.awt.Image) LearningPushHandler(io.undertow.server.handlers.LearningPushHandler) ServletInfo(io.undertow.servlet.api.ServletInfo) ProxyPeerAddressHandler(io.undertow.server.handlers.ProxyPeerAddressHandler) InMemorySessionManager(io.undertow.server.session.InMemorySessionManager) HttpHandler(io.undertow.server.HttpHandler) DefaultByteBufferPool(io.undertow.server.DefaultByteBufferPool) ProxyHandler(io.undertow.server.handlers.proxy.ProxyHandler) SSLHeaderHandler(io.undertow.server.handlers.SSLHeaderHandler) Method(java.lang.reflect.Method) LoadBalancingProxyClient(io.undertow.server.handlers.proxy.LoadBalancingProxyClient) UndertowXnioSsl(io.undertow.protocols.ssl.UndertowXnioSsl) File(java.io.File) Undertow(io.undertow.Undertow) SecurityManager(runwar.security.SecurityManager) RequestDebugHandler(runwar.undertow.RequestDebugHandler) ContentEncodingRepository(io.undertow.server.handlers.encoding.ContentEncodingRepository) RequestDumper(runwar.util.RequestDumper) EncodingHandler(io.undertow.server.handlers.encoding.EncodingHandler) URI(java.net.URI) URL(java.net.URL) GzipEncodingProvider(io.undertow.server.handlers.encoding.GzipEncodingProvider) HttpServerExchange(io.undertow.server.HttpServerExchange) Entry(java.util.Map.Entry) SessionCookieConfig(io.undertow.server.session.SessionCookieConfig) DeploymentInfo(io.undertow.servlet.api.DeploymentInfo) WebSocketDeploymentInfo(io.undertow.websockets.jsr.WebSocketDeploymentInfo) PrintWriter(java.io.PrintWriter) MariaDB4jManager(runwar.mariadb4j.MariaDB4jManager) Http2UpgradeHandler(io.undertow.server.protocol.http2.Http2UpgradeHandler) WebSocketDeploymentInfo(io.undertow.websockets.jsr.WebSocketDeploymentInfo) SocketTimeoutException(java.net.SocketTimeoutException) ConnectException(java.net.ConnectException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) FileNotFoundException(java.io.FileNotFoundException) AccessLogHandler(io.undertow.server.handlers.accesslog.AccessLogHandler) SessionAttachmentHandler(io.undertow.server.session.SessionAttachmentHandler)

Example 22 with UndertowXnioSsl

use of io.undertow.protocols.ssl.UndertowXnioSsl in project wildfly by wildfly.

the class HttpsListenerService method getSsl.

@Override
protected UndertowXnioSsl getSsl() {
    SSLContext sslContext = sslContextSupplier.get();
    OptionMap combined = getSSLOptions(sslContext);
    return new UndertowXnioSsl(worker.get().getXnio(), combined, sslContext);
}
Also used : OptionMap(org.xnio.OptionMap) SSLContext(javax.net.ssl.SSLContext) UndertowXnioSsl(io.undertow.protocols.ssl.UndertowXnioSsl)

Example 23 with UndertowXnioSsl

use of io.undertow.protocols.ssl.UndertowXnioSsl in project undertow by undertow-io.

the class Http2EndExchangeTestCase method testHttp2EndExchangeWithBrokenConnection.

@Test
public void testHttp2EndExchangeWithBrokenConnection() throws Exception {
    int port = DefaultServer.getHostPort("default");
    final CountDownLatch requestStartedLatch = new CountDownLatch(1);
    final CompletableFuture<String> testResult = new CompletableFuture<>();
    Undertow server = Undertow.builder().addHttpsListener(port + 1, DefaultServer.getHostAddress("default"), DefaultServer.getServerSslContext()).setServerOption(UndertowOptions.ENABLE_HTTP2, true).setSocketOption(Options.REUSE_ADDRESSES, true).setHandler(new BlockingHandler(new HttpHandler() {

        @Override
        public void handleRequest(HttpServerExchange exchange) throws Exception {
            if (!exchange.getProtocol().equals(Protocols.HTTP_2_0)) {
                testResult.completeExceptionally(new RuntimeException("Not HTTP/2 request"));
                return;
            }
            requestStartedLatch.countDown();
            log.debug("Received Request");
            // do some pretend work
            Thread.sleep(2000);
            if (exchange.isComplete()) {
                testResult.complete("FAILED, exchange ended in the background");
                return;
            }
            try {
                exchange.getOutputStream().write("Bogus Data".getBytes(StandardCharsets.UTF_8));
                exchange.getOutputStream().flush();
                testResult.complete("FAILED, should not have completed successfully");
                return;
            } catch (IOException expected) {
            }
            if (!exchange.isComplete()) {
                testResult.complete("Failed, should have completed the exchange");
            } else {
                testResult.complete("PASSED");
            }
        }
    })).build();
    server.start();
    try {
        ADDRESS = new URI("https://" + DefaultServer.getHostAddress() + ":" + (port + 1));
    } catch (URISyntaxException e) {
        throw new RuntimeException(e);
    }
    // Create xnio worker
    final Xnio xnio = Xnio.getInstance();
    final XnioWorker xnioWorker = xnio.createWorker(null, DEFAULT_OPTIONS);
    try {
        final UndertowClient client = createClient();
        final ClientConnection connection = client.connect(ADDRESS, xnioWorker, new UndertowXnioSsl(xnioWorker.getXnio(), OptionMap.EMPTY, DefaultServer.getClientSSLContext()), DefaultServer.getBufferPool(), OptionMap.create(UndertowOptions.ENABLE_HTTP2, true)).get();
        try {
            connection.getIoThread().execute(new Runnable() {

                @Override
                public void run() {
                    final ClientRequest request = new ClientRequest().setMethod(Methods.GET).setPath(MESSAGE);
                    request.getRequestHeaders().put(Headers.HOST, DefaultServer.getHostAddress());
                    connection.sendRequest(request, new ClientCallback<ClientExchange>() {

                        @Override
                        public void completed(ClientExchange result) {
                            try {
                                log.debug("Callback invoked");
                                new Thread(new Runnable() {

                                    @Override
                                    public void run() {
                                        try {
                                            requestStartedLatch.await(10, TimeUnit.SECONDS);
                                            result.getRequestChannel().getIoThread().execute(new Runnable() {

                                                @Override
                                                public void run() {
                                                    IoUtils.safeClose(result.getConnection());
                                                    log.debug("Closed Connection");
                                                }
                                            });
                                        } catch (Exception e) {
                                            testResult.completeExceptionally(e);
                                        }
                                    }
                                }).start();
                            } catch (Exception e) {
                                testResult.completeExceptionally(e);
                            }
                        }

                        @Override
                        public void failed(IOException e) {
                            testResult.completeExceptionally(e);
                        }
                    });
                }
            });
            Assert.assertEquals("PASSED", testResult.get(10, TimeUnit.SECONDS));
        } finally {
            IoUtils.safeClose(connection);
        }
    } finally {
        stopWorker(xnioWorker);
        server.stop();
        // sleep 1 s to prevent BindException (Address already in use) when running the CI
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ignore) {
        }
    }
}
Also used : ClientExchange(io.undertow.client.ClientExchange) ClientCallback(io.undertow.client.ClientCallback) XnioWorker(org.xnio.XnioWorker) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) HttpServerExchange(io.undertow.server.HttpServerExchange) CompletableFuture(java.util.concurrent.CompletableFuture) BlockingHandler(io.undertow.server.handlers.BlockingHandler) Xnio(org.xnio.Xnio) ClientConnection(io.undertow.client.ClientConnection) ClientRequest(io.undertow.client.ClientRequest) HttpHandler(io.undertow.server.HttpHandler) UndertowClient(io.undertow.client.UndertowClient) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) UndertowXnioSsl(io.undertow.protocols.ssl.UndertowXnioSsl) Undertow(io.undertow.Undertow) Test(org.junit.Test)

Example 24 with UndertowXnioSsl

use of io.undertow.protocols.ssl.UndertowXnioSsl in project undertow by undertow-io.

the class PushPromisesTestCase method testPushPromises.

@Test
public void testPushPromises() throws Exception {
    URI uri = new URI(DefaultServer.getDefaultServerSSLAddress());
    final UndertowClient client = UndertowClient.getInstance();
    final Map<String, ClientResponse> responses = new ConcurrentHashMap<>();
    final CountDownLatch latch = new CountDownLatch(3);
    final ClientConnection connection = client.connect(uri, worker, new UndertowXnioSsl(worker.getXnio(), OptionMap.EMPTY, DefaultServer.getClientSSLContext()), DefaultServer.getBufferPool(), OptionMap.create(UndertowOptions.ENABLE_HTTP2, true)).get();
    try {
        connection.getIoThread().execute(new Runnable() {

            @Override
            public void run() {
                final ClientRequest request = new ClientRequest().setMethod(Methods.GET).setPath("/push-example/index.html");
                request.getRequestHeaders().put(Headers.HOST, DefaultServer.getHostAddress());
                connection.sendRequest(request, createClientCallback(responses, latch));
            }
        });
        latch.await(10, TimeUnit.SECONDS);
        Assert.assertEquals(3, responses.size());
        Assert.assertTrue(responses.containsKey("/push-example/index.html"));
        Assert.assertEquals(StatusCodes.OK, responses.get("/push-example/index.html").getResponseCode());
        Assert.assertNotNull(responses.get("/push-example/index.html").getAttachment(RESPONSE_BODY));
        Assert.assertTrue(responses.containsKey("/push-example/resources/one.js"));
        Assert.assertEquals(StatusCodes.OK, responses.get("/push-example/resources/one.js").getResponseCode());
        Assert.assertNotNull(responses.get("/push-example/resources/one.js").getAttachment(RESPONSE_BODY));
        Assert.assertTrue(responses.containsKey("/push-example/resources/one.css"));
        Assert.assertEquals(StatusCodes.OK, responses.get("/push-example/resources/one.css").getResponseCode());
        Assert.assertNotNull(responses.get("/push-example/resources/one.css").getAttachment(RESPONSE_BODY));
    } finally {
        IoUtils.safeClose(connection);
    }
}
Also used : ClientResponse(io.undertow.client.ClientResponse) UndertowClient(io.undertow.client.UndertowClient) ClientConnection(io.undertow.client.ClientConnection) UndertowXnioSsl(io.undertow.protocols.ssl.UndertowXnioSsl) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) CountDownLatch(java.util.concurrent.CountDownLatch) URI(java.net.URI) ClientRequest(io.undertow.client.ClientRequest) Test(org.junit.Test)

Example 25 with UndertowXnioSsl

use of io.undertow.protocols.ssl.UndertowXnioSsl in project undertow by undertow-io.

the class Http2Server method main.

public static void main(final String[] args) throws Exception {
    String version = System.getProperty("java.version");
    System.out.println("Java version " + version);
    if (version.charAt(0) == '1' && Integer.parseInt(version.charAt(2) + "") < 8) {
        System.out.println("This example requires Java 1.8 or later");
        System.out.println("The HTTP2 spec requires certain cyphers that are not present in older JVM's");
        System.out.println("See section 9.2.2 of the HTTP2 specification for details");
        System.exit(1);
    }
    String bindAddress = System.getProperty("bind.address", "localhost");
    SSLContext sslContext = createSSLContext(loadKeyStore("server.keystore"), loadKeyStore("server.truststore"));
    Undertow server = Undertow.builder().setServerOption(UndertowOptions.ENABLE_HTTP2, true).addHttpListener(8080, bindAddress).addHttpsListener(8443, bindAddress, sslContext).setHandler(new SessionAttachmentHandler(new LearningPushHandler(100, -1, Handlers.header(predicate(secure(), resource(new PathResourceManager(Paths.get(System.getProperty("example.directory", System.getProperty("user.home"))), 100)).setDirectoryListingEnabled(true), new HttpHandler() {

        @Override
        public void handleRequest(HttpServerExchange exchange) throws Exception {
            exchange.getResponseHeaders().add(Headers.LOCATION, "https://" + exchange.getHostName() + ":" + (exchange.getHostPort() + 363) + exchange.getRelativePath());
            exchange.setStatusCode(StatusCodes.TEMPORARY_REDIRECT);
        }
    }), "x-undertow-transport", ExchangeAttributes.transportProtocol())), new InMemorySessionManager("test"), new SessionCookieConfig())).build();
    server.start();
    SSLContext clientSslContext = createSSLContext(loadKeyStore("client.keystore"), loadKeyStore("client.truststore"));
    LoadBalancingProxyClient proxy = new LoadBalancingProxyClient().addHost(new URI("https://localhost:8443"), null, new UndertowXnioSsl(Xnio.getInstance(), OptionMap.EMPTY, clientSslContext), OptionMap.create(UndertowOptions.ENABLE_HTTP2, true)).setConnectionsPerThread(20);
    Undertow reverseProxy = Undertow.builder().setServerOption(UndertowOptions.ENABLE_HTTP2, true).addHttpListener(8081, bindAddress).addHttpsListener(8444, bindAddress, sslContext).setHandler(ProxyHandler.builder().setProxyClient(proxy).setMaxRequestTime(30000).build()).build();
    reverseProxy.start();
}
Also used : HttpHandler(io.undertow.server.HttpHandler) SSLContext(javax.net.ssl.SSLContext) LearningPushHandler(io.undertow.server.handlers.LearningPushHandler) URI(java.net.URI) PathResourceManager(io.undertow.server.handlers.resource.PathResourceManager) LoadBalancingProxyClient(io.undertow.server.handlers.proxy.LoadBalancingProxyClient) HttpServerExchange(io.undertow.server.HttpServerExchange) SessionAttachmentHandler(io.undertow.server.session.SessionAttachmentHandler) SessionCookieConfig(io.undertow.server.session.SessionCookieConfig) UndertowXnioSsl(io.undertow.protocols.ssl.UndertowXnioSsl) Undertow(io.undertow.Undertow) InMemorySessionManager(io.undertow.server.session.InMemorySessionManager)

Aggregations

UndertowXnioSsl (io.undertow.protocols.ssl.UndertowXnioSsl)36 URI (java.net.URI)21 IOException (java.io.IOException)18 Test (org.junit.Test)17 XnioSsl (org.xnio.ssl.XnioSsl)15 ClientConnection (io.undertow.client.ClientConnection)9 UndertowClient (io.undertow.client.UndertowClient)9 CountDownLatch (java.util.concurrent.CountDownLatch)9 ClientRequest (io.undertow.client.ClientRequest)7 HttpHandler (io.undertow.server.HttpHandler)7 SSLContext (javax.net.ssl.SSLContext)7 InetSocketAddress (java.net.InetSocketAddress)6 HttpServerExchange (io.undertow.server.HttpServerExchange)5 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)5 OptionMap (org.xnio.OptionMap)5 LoadBalancingProxyClient (io.undertow.server.handlers.proxy.LoadBalancingProxyClient)4 HttpOpenListener (io.undertow.server.protocol.http.HttpOpenListener)4 Http2UpgradeHandler (io.undertow.server.protocol.http2.Http2UpgradeHandler)4 StringWriteChannelListener (io.undertow.util.StringWriteChannelListener)4 Undertow (io.undertow.Undertow)3