001package org.apache.maven.wagon.tck.http.fixture;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.log4j.Logger;
023import org.mortbay.jetty.Connector;
024import org.mortbay.jetty.Handler;
025import org.mortbay.jetty.Server;
026import org.mortbay.jetty.handler.DefaultHandler;
027import org.mortbay.jetty.handler.HandlerCollection;
028import org.mortbay.jetty.nio.SelectChannelConnector;
029import org.mortbay.jetty.security.Constraint;
030import org.mortbay.jetty.security.ConstraintMapping;
031import org.mortbay.jetty.security.HashUserRealm;
032import org.mortbay.jetty.security.SecurityHandler;
033import org.mortbay.jetty.security.SslSocketConnector;
034import org.mortbay.jetty.servlet.AbstractSessionManager;
035import org.mortbay.jetty.servlet.FilterHolder;
036import org.mortbay.jetty.servlet.FilterMapping;
037import org.mortbay.jetty.servlet.ServletHolder;
038import org.mortbay.jetty.servlet.SessionHandler;
039import org.mortbay.jetty.webapp.WebAppContext;
040
041import javax.servlet.Filter;
042import javax.servlet.Servlet;
043import java.io.File;
044import java.io.IOException;
045import java.net.URISyntaxException;
046
047import static org.apache.maven.wagon.tck.http.util.TestUtil.getResource;
048
049public class ServerFixture
050{
051    private static Logger logger = Logger.getLogger( ServerFixture.class );
052
053    public static final String SERVER_ROOT_RESOURCE_PATH = "default-server-root";
054
055    // it seems that some JDKs have a problem if you use different key stores
056    // so we gonna reuse the keystore which is is used in the wagon implementations already
057    public static final String SERVER_SSL_KEYSTORE_RESOURCE_PATH = "ssl/keystore";
058
059    public static final String SERVER_SSL_KEYSTORE_PASSWORD = "wagonhttp";
060
061    public static final String SERVER_HOST = "localhost";
062
063    private final Server server;
064
065    private final WebAppContext webappContext;
066
067    private final HashUserRealm securityRealm;
068
069    private final SecurityHandler securityHandler;
070
071    private int filterCount = 0;
072
073    private int httpPort;
074
075    public ServerFixture( final boolean ssl )
076        throws URISyntaxException, IOException
077    {
078        server = new Server();
079        if ( ssl )
080        {
081            SslSocketConnector connector = new SslSocketConnector();
082            String keystore = getResource( SERVER_SSL_KEYSTORE_RESOURCE_PATH ).getAbsolutePath();
083
084            Logger.getLogger( ServerFixture.class ).info( "TCK Keystore path: " + keystore );
085            System.setProperty( "javax.net.ssl.keyStore", keystore );
086            System.setProperty( "javax.net.ssl.trustStore", keystore );
087
088            // connector.setHost( SERVER_HOST );
089            //connector.setPort( port );
090            connector.setKeystore( keystore );
091            connector.setPassword( SERVER_SSL_KEYSTORE_PASSWORD );
092            connector.setKeyPassword( SERVER_SSL_KEYSTORE_PASSWORD );
093
094            server.addConnector( connector );
095        }
096        else
097        {
098            Connector connector = new SelectChannelConnector();
099            connector.setHost( "localhost" );
100            //connector.setPort( port );
101            server.addConnector( connector );
102        }
103
104        Constraint constraint = new Constraint();
105        constraint.setName( Constraint.__BASIC_AUTH );
106
107        constraint.setRoles( new String[]{ "allowed" } );
108        constraint.setAuthenticate( true );
109
110        ConstraintMapping cm = new ConstraintMapping();
111        cm.setConstraint( constraint );
112        cm.setPathSpec( "/protected/*" );
113
114        securityHandler = new SecurityHandler();
115
116        securityRealm = new HashUserRealm( "Test Server" );
117
118        securityHandler.setUserRealm( securityRealm );
119        securityHandler.setConstraintMappings( new ConstraintMapping[]{ cm } );
120
121        webappContext = new WebAppContext();
122        webappContext.setContextPath( "/" );
123
124        File base = getResource( SERVER_ROOT_RESOURCE_PATH );
125        logger.info( "docroot: " + base );
126        webappContext.setWar( base.getAbsolutePath() );
127        webappContext.addHandler( securityHandler );
128
129        SessionHandler sessionHandler = webappContext.getSessionHandler();
130        ( (AbstractSessionManager) sessionHandler.getSessionManager() ).setUsingCookies( false );
131
132        HandlerCollection handlers = new HandlerCollection();
133        handlers.setHandlers( new Handler[]{ webappContext, new DefaultHandler() } );
134
135        server.setHandler( handlers );
136    }
137
138    public void addFilter( final String pathSpec, final Filter filter )
139    {
140        String name = "filter" + filterCount++;
141
142        FilterMapping fm = new FilterMapping();
143        fm.setPathSpec( pathSpec );
144        fm.setFilterName( name );
145
146        FilterHolder fh = new FilterHolder( filter );
147        fh.setName( name );
148
149        webappContext.getServletHandler().addFilter( fh, fm );
150    }
151
152    public void addServlet( final String pathSpec, final Servlet servlet )
153    {
154        webappContext.getServletHandler().addServletWithMapping( new ServletHolder( servlet ), pathSpec );
155    }
156
157    public void addUser( final String user, final String password )
158    {
159        securityRealm.put( user, password );
160        securityRealm.addUserToRole( user, "allowed" );
161    }
162
163    public Server getServer()
164    {
165        return server;
166    }
167
168    public WebAppContext getWebappContext()
169    {
170        return webappContext;
171    }
172
173    public void stop()
174        throws Exception
175    {
176        if ( server != null )
177        {
178            server.stop();
179        }
180    }
181
182    public void start()
183        throws Exception
184    {
185        if ( server.isStarted() || server.isRunning() )
186        {
187            return;
188        }
189        server.start();
190
191        int total = 0;
192        while ( total < 3000 && !server.isStarted() )
193        {
194            server.wait( 10 );
195            total += 10;
196        }
197
198        if ( !server.isStarted() )
199        {
200            throw new IllegalStateException( "Server didn't start in: " + total + "ms." );
201        }
202        this.httpPort = server.getConnectors()[0].getLocalPort();
203    }
204
205    public int getHttpPort()
206    {
207        return httpPort;
208    }
209}