//
//  ========================================================================
//  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.server.handler;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.toolchain.test.IO;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class SecuredRedirectHandlerTest
{
    private static Server server;
    private static HostnameVerifier origVerifier;
    private static SSLSocketFactory origSsf;
    private static URI serverHttpUri;
    private static URI serverHttpsUri;

    @BeforeClass
    public static void startServer() throws Exception
    {
        // Setup SSL
        File keystore = MavenTestingUtils.getTestResourceFile("keystore");
        SslContextFactory sslContextFactory = new SslContextFactory();
        sslContextFactory.setKeyStorePath(keystore.getAbsolutePath());
        sslContextFactory.setKeyStorePassword("storepwd");
        sslContextFactory.setKeyManagerPassword("keypwd");
        sslContextFactory.setTrustStorePath(keystore.getAbsolutePath());
        sslContextFactory.setTrustStorePassword("storepwd");

        server = new Server();

        int port = 32080;
        int securePort = 32443;

        // Setup HTTP Configuration
        HttpConfiguration httpConf = new HttpConfiguration();
        httpConf.setSecurePort(securePort);
        httpConf.setSecureScheme("https");

        ServerConnector httpConnector = new ServerConnector(server,new HttpConnectionFactory(httpConf));
        httpConnector.setName("unsecured");
        httpConnector.setPort(port);

        // Setup HTTPS Configuration
        HttpConfiguration httpsConf = new HttpConfiguration(httpConf);
        httpsConf.addCustomizer(new SecureRequestCustomizer());

        ServerConnector httpsConnector = new ServerConnector(server,new SslConnectionFactory(sslContextFactory,"http/1.1"),new HttpConnectionFactory(httpsConf));
        httpsConnector.setName("secured");
        httpsConnector.setPort(securePort);

        // Add connectors
        server.setConnectors(new Connector[] { httpConnector, httpsConnector });

        // Wire up contexts
        String secureHosts[] = new String[] { "@secured" };

        ContextHandler test1Context = new ContextHandler();
        test1Context.setContextPath("/test1");
        test1Context.setHandler(new HelloHandler("Hello1"));
        test1Context.setVirtualHosts(secureHosts);

        ContextHandler test2Context = new ContextHandler();
        test2Context.setContextPath("/test2");
        test2Context.setHandler(new HelloHandler("Hello2"));
        test2Context.setVirtualHosts(secureHosts);

        ContextHandler rootContext = new ContextHandler();
        rootContext.setContextPath("/");
        rootContext.setHandler(new RootHandler("/test1","/test2"));
        rootContext.setVirtualHosts(secureHosts);

        // Wire up context for unsecure handling to only
        // the named 'unsecured' connector
        ContextHandler redirectHandler = new ContextHandler();
        redirectHandler.setContextPath("/");
        redirectHandler.setHandler(new SecuredRedirectHandler());
        redirectHandler.setVirtualHosts(new String[] { "@unsecured" });

        // Establish all handlers that have a context
        ContextHandlerCollection contextHandlers = new ContextHandlerCollection();
        contextHandlers.setHandlers(new Handler[] { redirectHandler, rootContext, test1Context, test2Context });

        // Create server level handler tree
        HandlerList handlers = new HandlerList();
        handlers.addHandler(contextHandlers);
        handlers.addHandler(new DefaultHandler()); // round things out

        server.setHandler(handlers);

        server.start();

        // calculate serverUri
        String host = httpConnector.getHost();
        if (host == null)
        {
            host = "localhost";
        }
        serverHttpUri = new URI(String.format("http://%s:%d/",host,httpConnector.getLocalPort()));
        serverHttpsUri = new URI(String.format("https://%s:%d/",host,httpsConnector.getLocalPort()));

        origVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
        origSsf = HttpsURLConnection.getDefaultSSLSocketFactory();

        HttpsURLConnection.setDefaultHostnameVerifier(new AllowAllVerifier());
        HttpsURLConnection.setDefaultSSLSocketFactory(sslContextFactory.getSslContext().getSocketFactory());
    }

    @AfterClass
    public static void stopServer() throws Exception
    {
        HttpsURLConnection.setDefaultSSLSocketFactory(origSsf);
        HttpsURLConnection.setDefaultHostnameVerifier(origVerifier);

        server.stop();
        server.join();
    }

    @Test
    public void testRedirectUnsecuredRoot() throws Exception
    {
        URL url = serverHttpUri.resolve("/").toURL();
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        connection.setInstanceFollowRedirects(false);
        connection.setAllowUserInteraction(false);
        assertThat("response code",connection.getResponseCode(),is(302));
        assertThat("location header",connection.getHeaderField("Location"),is(serverHttpsUri.resolve("/").toASCIIString()));
        connection.disconnect();
    }

    @Test
    public void testRedirectSecuredRoot() throws Exception
    {
        URL url = serverHttpsUri.resolve("/").toURL();
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        connection.setInstanceFollowRedirects(false);
        connection.setAllowUserInteraction(false);
        assertThat("response code",connection.getResponseCode(),is(200));
        String content = getContent(connection);
        assertThat("response content",content,containsString("<a href=\"/test1\">"));
        connection.disconnect();
    }

    @Test
    public void testAccessUnsecuredHandler() throws Exception
    {
        URL url = serverHttpUri.resolve("/test1").toURL();
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        connection.setInstanceFollowRedirects(false);
        connection.setAllowUserInteraction(false);
        assertThat("response code",connection.getResponseCode(),is(302));
        assertThat("location header",connection.getHeaderField("Location"),is(serverHttpsUri.resolve("/test1").toASCIIString()));
        connection.disconnect();
    }

    @Test
    public void testAccessUnsecured404() throws Exception
    {
        URL url = serverHttpUri.resolve("/nothing/here").toURL();
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        connection.setInstanceFollowRedirects(false);
        connection.setAllowUserInteraction(false);
        assertThat("response code",connection.getResponseCode(),is(302));
        assertThat("location header",connection.getHeaderField("Location"),is(serverHttpsUri.resolve("/nothing/here").toASCIIString()));
        connection.disconnect();
    }

    @Test
    public void testAccessSecured404() throws Exception
    {
        URL url = serverHttpsUri.resolve("/nothing/here").toURL();
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        connection.setInstanceFollowRedirects(false);
        connection.setAllowUserInteraction(false);
        assertThat("response code",connection.getResponseCode(),is(404));
        connection.disconnect();
    }

    private String getContent(HttpURLConnection connection) throws IOException
    {
        try (InputStream in = connection.getInputStream(); InputStreamReader reader = new InputStreamReader(in))
        {
            StringWriter writer = new StringWriter();
            IO.copy(reader,writer);
            return writer.toString();
        }
    }

    public static class HelloHandler extends AbstractHandler
    {
        private final String msg;

        public HelloHandler(String msg)
        {
            this.msg = msg;
        }

        @Override
        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
        {
            response.setContentType("text/plain");
            response.getWriter().printf("%s%n",msg);
            baseRequest.setHandled(true);
        }
    }

    public static class RootHandler extends AbstractHandler
    {
        private final String[] childContexts;

        public RootHandler(String... children)
        {
            this.childContexts = children;
        }

        @Override
        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
        {
            if (!"/".equals(target))
            {
                response.sendError(404);
                return;
            }

            response.setContentType("text/html");
            PrintWriter out = response.getWriter();
            out.println("<html>");
            out.println("<head><title>Contexts</title></head>");
            out.println("<body>");
            out.println("<h4>Child Contexts</h4>");
            out.println("<ul>");
            for (String child : childContexts)
            {
                out.printf("<li><a href=\"%s\">%s</a></li>%n",child,child);
            }
            out.println("</ul>");
            out.println("</body></html>");
            baseRequest.setHandled(true);
        }
    }
}
