/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2014 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed 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 io.undertow.server.security;

import java.io.IOException;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import io.undertow.security.handlers.SinglePortConfidentialityHandler;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.testutils.DefaultServer;
import io.undertow.testutils.HttpClientUtils;
import io.undertow.testutils.TestHttpClient;
import io.undertow.util.FileUtils;
import io.undertow.util.HttpString;
import io.undertow.util.StatusCodes;

/**
 * A simple test case to verify a redirect works.
 *
 * @author <a href="mailto:darran.lofthouse@jboss.com">Darran Lofthouse</a>
 */
@RunWith(DefaultServer.class)
public class SimpleConfidentialRedirectTestCase {

    @Test
    public void simpleRedirectTestCase() throws IOException, GeneralSecurityException {
        DefaultServer.startSSLServer();

        HttpHandler current = new HttpHandler() {
            @Override
            public void handleRequest(final HttpServerExchange exchange) throws Exception {
                exchange.getResponseHeaders().put(HttpString.tryFromString("scheme"), exchange.getRequestScheme());
                exchange.getResponseHeaders().put(HttpString.tryFromString("uri"), exchange.getRequestURI());
                exchange.endExchange();
            }
        };

        current = new SinglePortConfidentialityHandler(current, DefaultServer.getHostSSLPort("default"));

        DefaultServer.setRootHandler(current);
        TestHttpClient client = new TestHttpClient();
        client.setSSLContext(DefaultServer.getClientSSLContext());
        try {
            sendRequest(client, "/foo");
            sendRequest(client, "/foo+bar");
            sendRequest(client, "/foo+bar;aa");

            //now we need to test what happens if the client send a full URI
            //see UNDERTOW-874
            Socket socket = new Socket(DefaultServer.getHostAddress(), DefaultServer.getHostPort());
            socket.getOutputStream().write(("GET " + DefaultServer.getDefaultServerURL() + "/foo HTTP/1.0\r\n\r\n").getBytes(StandardCharsets.UTF_8));
            String result = FileUtils.readFile(socket.getInputStream());
            Assert.assertTrue(result.contains("Location: https://127.0.0.1:7778/foo"));

        } finally {
            client.getConnectionManager().shutdown();
            DefaultServer.stopSSLServer();
        }
    }

    private void sendRequest(TestHttpClient client, String uri) throws IOException {
        HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + uri);
        HttpResponse result = client.execute(get);
        Assert.assertEquals(StatusCodes.OK, result.getStatusLine().getStatusCode());
        Assert.assertEquals("https", result.getFirstHeader("scheme").getValue());
        Assert.assertEquals(uri, result.getFirstHeader("uri").getValue());
        HttpClientUtils.readResponse(result);
    }

}

@@ -994,16 +994,46 @@
 Assert;%0A
+import org.junit.BeforeClass;%0A
 import o
@@ -1322,24 +1322,66 @@
 lientUtils;%0A
+import io.undertow.testutils.ProxyIgnore;%0A
 import io.un
@@ -1744,17 +1744,25 @@
  %7B%0A%0A
+%0A
     @
-Test
+BeforeClass
 %0A   
@@ -1773,73 +1773,37 @@
 lic 
-void simpleRedirectTestCase() throws IOException, GeneralSecurity
+static void setup() throws IO
 Exce
@@ -2457,24 +2457,226 @@
 r(current);%0A
+    %7D%0A%0A    public static void stop() throws IOException %7B%0A        DefaultServer.stopSSLServer();%0A    %7D%0A%0A    @Test%0A    public void simpleRedirectTestCase() throws IOException, GeneralSecurityException %7B%0A
         Test
@@ -2929,28 +2929,235 @@
 +bar;aa%22);%0A%0A
-    
+%0A        %7D finally %7B%0A            client.getConnectionManager().shutdown();%0A        %7D%0A    %7D%0A%0A    @ProxyIgnore%0A    public void testRedirectWithFullURLInPath() throws IOException %7B%0A        DefaultServer.isProxy();%0A
         //no
@@ -3225,20 +3225,16 @@
         
-    
 //see UN
@@ -3252,20 +3252,21 @@
         
- 
-   
+try (
 Socket s
@@ -3340,25 +3340,27 @@
 tHostPort())
-;
+) %7B
 %0A           
@@ -3633,154 +3633,64 @@
 on: 
-https://127.0.0.1:7778/foo%22));%0A%0A        %7D finally %7B%0A            client.getConnectionManager().shutdown();%0A            DefaultServer.stopSSLServer(
+%22 + DefaultServer.getDefaultServerSSLAddress() + %22/foo%22)
 );%0A 

Fix test issue