/* * Copyright 2014 Harald Wellmann. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. * * See the License for the specific language governing permissions and * limitations under the License. */ package org.ops4j.pax.web.undertow; import static org.ops.pax.web.spi.WebContainerConstants.PROPERTY_HTTP_ENABLED; import static org.ops.pax.web.spi.WebContainerConstants.PROPERTY_HTTP_PORT; import static org.ops.pax.web.spi.WebContainerConstants.PROPERTY_HTTP_SECURE_ENABLED; import static org.ops.pax.web.spi.WebContainerConstants.PROPERTY_HTTP_SECURE_PORT; import io.undertow.Handlers; import io.undertow.Undertow; import io.undertow.Undertow.Builder; import io.undertow.server.HttpHandler; import io.undertow.server.handlers.PathHandler; import io.undertow.server.handlers.accesslog.AccessLogHandler; import io.undertow.server.handlers.accesslog.JBossLoggingAccessLogReceiver; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Properties; import javax.net.ssl.SSLContext; import org.ops4j.pax.web.undertow.ssl.SslContextFactory; import org.ops4j.util.property.DictionaryPropertyResolver; import org.ops4j.util.property.PropertiesPropertyResolver; import org.ops4j.util.property.PropertyResolver; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Component(service = UndertowHttpServer.class, configurationPid = "org.ops4j.pax.web.undertow") public class UndertowHttpServer { private static Logger log = LoggerFactory.getLogger(UndertowHttpServer.class); private Undertow server; private PathHandler pathHandler; private HttpHandler rootHandler; private Map<String, PathHandler> virtualHostMap = new HashMap<>(); @Activate public void activate(ComponentContext cc) throws IOException { Builder builder = Undertow.builder(); pathHandler = Handlers.path(); PropertyResolver resolver = buildPropertyResolver(cc); boolean httpEnabled = Boolean.parseBoolean(resolver.get(PROPERTY_HTTP_ENABLED)); boolean httpsEnabled = Boolean.parseBoolean(resolver.get(PROPERTY_HTTP_SECURE_ENABLED)); boolean accessLogEnabled = Boolean.parseBoolean(resolver.get("org.ops4j.pax.web.undertow.accesslog.enabled")); Integer httpPort = null; Integer httpsPort = null; if (httpEnabled) { // get HTTP port String httpPortNumber = resolver.get(PROPERTY_HTTP_PORT); httpPort = Integer.valueOf(httpPortNumber); builder.addHttpListener(httpPort, "0.0.0.0"); } if (httpsEnabled) { // get HTTPS port String httpsPortNumber = resolver.get(PROPERTY_HTTP_SECURE_PORT); httpsPort = Integer.valueOf(httpsPortNumber); SslContextFactory sslContextFactory = new SslContextFactory(resolver); SSLContext sslContext = sslContextFactory.createSslContext(); builder.addHttpsListener(httpsPort, "0.0.0.0", sslContext); } rootHandler = pathHandler; configureVirtualHosts(resolver); if (accessLogEnabled) { String format = resolver.get("org.ops4j.pax.undertow.accesslog.format"); rootHandler = new AccessLogHandler(pathHandler, new JBossLoggingAccessLogReceiver(), format, AccessLogHandler.class.getClassLoader()); } server = builder.setHandler(rootHandler).build(); log.info("starting Undertow server"); server.start(); } private void configureVirtualHosts(PropertyResolver resolver) { String hostsConfig = resolver.get("org.ops4j.pax.web.hosts"); if (hostsConfig == null) { return; } String[] hosts = hostsConfig.trim().split(",\\s*"); for (String host : hosts) { configureVirtualHost(host, resolver); } } private void configureVirtualHost(String host, PropertyResolver resolver) { String aliasesConfig = resolver.get(String.format("org.ops4j.pax.web.host.%s.aliases", host)); if (aliasesConfig == null) { return; } String[] aliases = aliasesConfig.trim().split(",\\s*"); PathHandler hostPathHandler = Handlers.path(); virtualHostMap.put(host, hostPathHandler); rootHandler = Handlers.virtualHost(pathHandler, hostPathHandler, aliases); } private PropertyResolver buildPropertyResolver(ComponentContext cc) throws IOException { Properties defaultProperties = new Properties(); defaultProperties.load(UndertowHttpServer.class.getResourceAsStream("/default.properties")); PropertyResolver defaultResolver = new PropertiesPropertyResolver(defaultProperties); PropertyResolver fallbackResolver = new PropertiesPropertyResolver(System.getProperties(), defaultResolver); PropertyResolver resolver = new DictionaryPropertyResolver(cc.getProperties(), fallbackResolver); return resolver; } @Deactivate public void deactivate(ComponentContext cc) { server.stop(); } public Undertow getServer() { return server; } public PathHandler getPathHandler() { return pathHandler; } public PathHandler findPathHandlerForHost(String virtualHostId) { if (virtualHostId == null) { return pathHandler; } return virtualHostMap.get(virtualHostId); } }