//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.client;

import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.security.cert.CertificateException;
import java.util.concurrent.ExecutionException;

import javax.net.ssl.SSLHandshakeException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * This test class runs tests to make sure that hostname verification (http://www.ietf.org/rfc/rfc2818.txt
 * section 3.1) is configurable in SslContextFactory and works as expected.
 */
public class HostnameVerificationTest
{
    private SslContextFactory clientSslContextFactory = new SslContextFactory();
    private Server server = new Server();
    private HttpClient client;
    private NetworkConnector connector;

    @Before
    public void setUp() throws Exception
    {
        SslContextFactory serverSslContextFactory = new SslContextFactory();
        serverSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
        serverSslContextFactory.setKeyStorePassword("storepwd");
        connector = new ServerConnector(server, serverSslContextFactory);
        server.addConnector(connector);
        server.setHandler(new DefaultHandler()
        {
            @Override
            public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
            {
                baseRequest.setHandled(true);
                response.getWriter().write("foobar");
            }
        });
        server.start();

        // keystore contains a hostname which doesn't match localhost
        clientSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
        clientSslContextFactory.setKeyStorePassword("storepwd");

        QueuedThreadPool executor = new QueuedThreadPool();
        executor.setName(executor.getName() + "-client");
        client = new HttpClient(clientSslContextFactory);
        client.setExecutor(executor);
        client.start();
    }

    @After
    public void tearDown() throws Exception
    {
        client.stop();
        server.stop();
        server.join();
    }

    /**
     * This test is supposed to verify that hostname verification works as described in:
     * http://www.ietf.org/rfc/rfc2818.txt section 3.1. It uses a certificate with a common name different to localhost
     * and sends a request to localhost. This should fail with a SSLHandshakeException.
     *
     * @throws Exception
     */
    @Test
    public void simpleGetWithHostnameVerificationEnabledTest() throws Exception
    {
        clientSslContextFactory.setEndpointIdentificationAlgorithm("HTTPS");
        String uri = "https://localhost:" + connector.getLocalPort() + "/";
        try
        {
            client.GET(uri);
            Assert.fail("sending request to client should have failed with an Exception!");
        }
        catch (ExecutionException x)
        {
            // The test may fail in 2 ways, since the CertificateException thrown because of the hostname
            // verification failure is not rethrown immediately by the JDK SSL implementation, but only
            // rethrown on the next read or write.
            // Therefore this test may catch a SSLHandshakeException, or a ClosedChannelException.
            // If it is the former, we verify that its cause is a CertificateException.

            // ExecutionException wraps an SSLHandshakeException
            Throwable cause = x.getCause();
            if (cause==null)
            {
                x.printStackTrace();
                Assert.fail("No cause?");
            }
            if (cause instanceof SSLHandshakeException)
                Assert.assertThat(cause.getCause().getCause(), Matchers.instanceOf(CertificateException.class));
            else
                Assert.assertThat(cause, Matchers.instanceOf(ClosedChannelException.class));
        }
    }

    /**
     * This test has hostname verification disabled and connecting, ssl handshake and sending the request should just
     * work fine.
     *
     * @throws Exception
     */
    @Test
    public void simpleGetWithHostnameVerificationDisabledTest() throws Exception
    {
        clientSslContextFactory.setEndpointIdentificationAlgorithm(null);
        String uri = "https://localhost:" + connector.getLocalPort() + "/";
        try
        {
            client.GET(uri);
        }
        catch (ExecutionException e)
        {
            Assert.fail("SSLHandshake should work just fine as hostname verification is disabled! " + e.getMessage());
        }
    }

    /**
     * This test has hostname verification disabled by setting trustAll to true and connecting,
     * ssl handshake and sending the request should just work fine.
     *
     * @throws Exception
     */
    @Test
    public void trustAllDisablesHostnameVerificationTest() throws Exception
    {
        clientSslContextFactory.setTrustAll(true);
        String uri = "https://localhost:" + connector.getLocalPort() + "/";
        try
        {
            client.GET(uri);
        }
        catch (ExecutionException e)
        {
            Assert.fail("SSLHandshake should work just fine as hostname verification is disabled! " + e.getMessage());
        }
    }
}
