001package fr.ifremer.adagio.synchro.socket;
002
003/*
004 * #%L
005 * SIH-Adagio :: Synchronization
006 * $Id:$
007 * $HeadURL:$
008 * %%
009 * Copyright (C) 2012 - 2014 Ifremer
010 * %%
011 * This program is free software: you can redistribute it and/or modify
012 * it under the terms of the GNU Affero General Public License as published by
013 * the Free Software Foundation, either version 3 of the License, or
014 * (at your option) any later version.
015 * 
016 * This program is distributed in the hope that it will be useful,
017 * but WITHOUT ANY WARRANTY; without even the implied warranty of
018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
019 * GNU General Public License for more details.
020 * 
021 * You should have received a copy of the GNU Affero General Public License
022 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
023 * #L%
024 */
025
026import java.io.File;
027import java.net.URL;
028import java.security.KeyStore;
029
030import javax.net.ssl.KeyManager;
031import javax.net.ssl.KeyManagerFactory;
032import javax.net.ssl.SSLContext;
033import javax.net.ssl.SSLServerSocketFactory;
034
035import org.apache.commons.logging.Log;
036import org.apache.commons.logging.LogFactory;
037import org.apache.http.protocol.HttpProcessor;
038import org.apache.http.protocol.HttpProcessorBuilder;
039import org.apache.http.protocol.HttpService;
040import org.apache.http.protocol.ResponseConnControl;
041import org.apache.http.protocol.ResponseContent;
042import org.apache.http.protocol.ResponseDate;
043import org.apache.http.protocol.ResponseServer;
044import org.apache.http.protocol.UriHttpRequestHandlerMapper;
045
046import fr.ifremer.adagio.synchro.config.SynchroConfiguration;
047
048/**
049 * Basic, yet fully functional and spec compliant, HTTP/1.1 file server.
050 */
051public class SynchroHttpServer {
052    /* Logger */
053    private static final Log log = LogFactory.getLog(SynchroHttpServer.class);
054
055    public void start() throws Exception {
056        SynchroConfiguration config = SynchroConfiguration.getInstance();
057
058        int port = config.getServerPort();
059        boolean useSsl = (port == 8443 || port == 443);
060        File dataDirectory = config.getDataDirectory();
061
062        // Create the directory if not exists
063        if (!dataDirectory.exists() || !dataDirectory.isDirectory()) {
064            log.error("Working directory not exists: " + dataDirectory);
065            System.exit(0);
066        }
067
068        if (log.isInfoEnabled()) {
069            log.info("Starting synchronization server...");
070            log.info(" Port: " + port);
071            if (useSsl) {
072                log.info(" SSL: enable");
073            }
074        }
075
076        // Set up the HTTP protocol processor
077        HttpProcessor httpproc = HttpProcessorBuilder.create()
078                .add(new ResponseDate())
079                .add(new ResponseServer("Test/1.1"))
080                .add(new ResponseContent())
081                .add(new ResponseConnControl()).build();
082
083        // Set up request handlers
084        UriHttpRequestHandlerMapper reqistry = new UriHttpRequestHandlerMapper();
085        SynchroHttpHandler baseHandler = new SynchroHttpHandler(dataDirectory);
086
087        reqistry.register("*", baseHandler);
088
089        // reqistry.register("**/*.html", new SynchroBrowserHandler(dataDirectory));
090
091        // Set up the HTTP service
092        HttpService httpService = new HttpService(httpproc, reqistry);
093
094        SSLServerSocketFactory sf = null;
095        if (useSsl) {
096            // Initialize SSL context
097            ClassLoader cl = SynchroHttpServer.class.getClassLoader();
098            File sslKeyStoreFile = config.getServerSslKeyStore();
099            URL url = cl.getResource(sslKeyStoreFile.getPath());
100            if (url == null) {
101                log.error("Keystore file not found: " + sslKeyStoreFile.getPath());
102                System.exit(1);
103            }
104            KeyStore keystore = KeyStore.getInstance("jks");
105            keystore.load(url.openStream(), "secret".toCharArray());
106            KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(
107                    KeyManagerFactory.getDefaultAlgorithm());
108            kmfactory.init(keystore, "secret".toCharArray());
109            KeyManager[] keymanagers = kmfactory.getKeyManagers();
110            SSLContext sslcontext = SSLContext.getInstance("TLS");
111            sslcontext.init(keymanagers, null, null);
112            sf = sslcontext.getServerSocketFactory();
113        }
114
115        Thread t = new SynchroRequestListenerThread(port, httpService, sf);
116        t.setDaemon(false);
117        t.start();
118    }
119
120}