Package org.apache.directory.server.integration.http

Source Code of org.apache.directory.server.integration.http.HttpServer

/*
*   Licensed to the Apache Software Foundation (ASF) under one
*   or more contributor license agreements.  See the NOTICE file
*   distributed with this work for additional information
*   regarding copyright ownership.  The ASF licenses this file
*   to you 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.apache.directory.server.integration.http;


import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.OutputStream;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import org.apache.directory.server.HttpDirectoryService;
import org.apache.directory.server.constants.ServerDNConstants;
import org.apache.directory.server.core.DirectoryService;
import org.apache.directory.server.core.security.TlsKeyGenerator;
import org.apache.directory.server.i18n.I18n;
import org.apache.directory.server.protocol.shared.transport.TcpTransport;
import org.apache.directory.shared.ldap.model.entry.Entry;
import org.apache.directory.shared.ldap.model.name.Dn;
import org.bouncycastle.jce.provider.X509CertParser;
import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.ContextHandler;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;
import org.mortbay.xml.XmlConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
* Class to start the jetty http server
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class HttpServer
{

    /** the jetty http server instance */
    private Server jetty;

    /** jetty config file */
    private String confFile;

    /** a collection to hold the configured web applications */
    private Set<WebApp> webApps;

    /** Transport for http */
    private TcpTransport httpTransport = null;
   
    /** Transport for https */
    private TcpTransport httpsTransport = null;
   
    /** protocol identifier for http */
    public static final String HTTP_TRANSPORT_ID = "http";
   
    /** protocol identifier for https */
    public static final String HTTPS_TRANSPORT_ID = "https";
   
    /** an internal flag to check the server configuration */
    private boolean configured = false;

    private static final Logger LOG = LoggerFactory.getLogger( HttpServer.class );

    private DirectoryService dirService;

    public HttpServer()
    {
    }


    /**
     * starts the jetty http server
     *
     * @throws Exception
     */
    public void start( DirectoryService dirService ) throws Exception
    {

        this.dirService = dirService;
       
        XmlConfiguration jettyConf = null;

        if ( confFile != null )
        {
            jettyConf = new XmlConfiguration( new FileInputStream( confFile ) );

            LOG.info( "configuring jetty http server from the configuration file {}", confFile );

            try
            {
                jetty = new Server();
                jettyConf.configure( jetty );
                configured = true;
            }
            catch ( Exception e )
            {
                LOG.error( I18n.err( I18n.ERR_120 ) );
                throw e;
            }
        }
        else
        {
            LOG.info( "No configuration file set, looking for web apps" );
            configureServerThroughCode();
        }

        if ( configured )
        {
            Handler[] handlers = jetty.getHandlers();
            for( Handler h : handlers )
            {
                if( h instanceof ContextHandler )
                {
                    ContextHandler ch = ( ContextHandler ) h;
                    ch.setAttribute( HttpDirectoryService.KEY, new HttpDirectoryService( dirService ) );
                }
            }
           
            LOG.info( "starting jetty http server" );
            jetty.start();
        }
        else
        {
            jetty = null;
            LOG.warn( "Error while configuring the http server, skipping the http server startup" );
        }
    }


    /*
     * configure the jetty server programmatically without using any configuration file
     */
    private void configureServerThroughCode()
    {
        try
        {
            jetty = new Server();

            if ( httpTransport != null )
            {
                SelectChannelConnector httpConnector = new SelectChannelConnector();
                httpConnector.setPort( httpTransport.getPort() );
                httpConnector.setHost( httpTransport.getAddress() );
                jetty.addConnector( httpConnector );
            }

            if ( httpsTransport != null )
            {
                // load the admin entry to get the private key and certificate
                Dn adminDn = dirService.getDnFactory().create( ServerDNConstants.ADMIN_SYSTEM_DN );
                Entry adminEntry = dirService.getAdminSession().lookup( adminDn, "*", "+" );
               
                File confDir = dirService.getInstanceLayout().getConfDirectory();
                File ksFile = new File( confDir, "httpserver.generated.ks" );
               
                String password = UUID.randomUUID().toString();
               
                KeyStore ks = KeyStore.getInstance( KeyStore.getDefaultType() );
                ks.load( null, null );
               
                X509CertParser parser = new X509CertParser();
               
                parser.engineInit( new ByteArrayInputStream( adminEntry.get( TlsKeyGenerator.USER_CERTIFICATE_AT ).getBytes() ) );
               
                X509Certificate cert = ( X509Certificate ) parser.engineRead();
               
                ks.setCertificateEntry( "cert", cert );
               
                KeyPair keyPair = TlsKeyGenerator.getKeyPair( adminEntry );
                ks.setKeyEntry( "privatekey", keyPair.getPrivate(), password.toCharArray(), new Certificate[]{ cert } );
               
                OutputStream stream = new FileOutputStream( ksFile );
                ks.store( stream, password.toCharArray() );

                SslSocketConnector httpsConnector = new SslSocketConnector();
                httpsConnector.setPort( httpsTransport.getPort() );
                httpsConnector.setHost( httpsTransport.getAddress() );
                httpsConnector.setKeystoreType( ks.getType() );
                httpsConnector.setKeystore( ksFile.getAbsolutePath() );
                httpsConnector.setPassword( password );
                httpsConnector.setKeyPassword( password );
               
                jetty.addConnector( httpsConnector );
            }
           
            List<Handler> handlers = new ArrayList<Handler>();
            for ( WebApp w : webApps )
            {
                WebAppContext webapp = new WebAppContext();
                webapp.setWar( w.getWarFile() );
                webapp.setContextPath( w.getContextPath() );
                handlers.add( webapp );
               
                webapp.setParentLoaderPriority( true );
            }

            // add web apps from the webapps directory inside directory service's working directory
            // the exploded or archived wars
            File webAppDir = new File( dirService.getInstanceLayout().getInstanceDirectory(), "webapps" );
           
            FilenameFilter webAppFilter = new FilenameFilter()
            {
               
                public boolean accept( File dir, String name )
                {
                    return name.endsWith( ".war" );
                }
            };
           
            if ( webAppDir.exists() )
            {
                File[] appList = webAppDir.listFiles( webAppFilter );
                for( File app : appList )
                {
                    WebAppContext webapp = new WebAppContext();
                    webapp.setWar( app.getAbsolutePath() );
                    String ctxName = app.getName();
                    int pos = ctxName.indexOf( '.' );
                    if( pos > 0 )
                    {
                        ctxName = ctxName.substring( 0, pos );
                    }
                   
                    webapp.setContextPath( "/" + ctxName );
                    handlers.add( webapp );
                   
                    webapp.setParentLoaderPriority( true );
                }
            }
           
            jetty.setHandlers( handlers.toArray( new Handler[ handlers.size() ] ) );
           
            configured = true;
        }
        catch ( Exception e )
        {
            LOG.error( I18n.err( I18n.ERR_121 ), e );
        }

    }


    /**
     * stops the jetty http server
     *
     * @throws Exception
     */
    public void stop() throws Exception
    {
        if ( jetty != null && jetty.isStarted() )
        {
            LOG.info( "stopping jetty http server" );
            jetty.stop();
        }
    }


    public void setConfFile( String confFile )
    {
        this.confFile = confFile;
    }


    public Set<WebApp> getWebApps()
    {
        return webApps;
    }


    public void setWebApps( Set<WebApp> webapps )
    {
        this.webApps = webapps;
    }


    public TcpTransport getHttpTransport()
    {
        return httpTransport;
    }


    public void setHttpTransport( TcpTransport httpTransport )
    {
        this.httpTransport = httpTransport;
    }


    public TcpTransport getHttpsTransport()
    {
        return httpsTransport;
    }


    public void setHttpsTransport( TcpTransport httpsTransport )
    {
        this.httpsTransport = httpsTransport;
    }

}
TOP

Related Classes of org.apache.directory.server.integration.http.HttpServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.