/*
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

import java.io.*;
import java.net.*;
import com.sun.ejte.ccl.reporter.*;

/*
 * Unit test for https://glassfish.dev.java.net/issues/show_bug.cgi?id=815
 * ("Impossible for JSP error page to set response encoding when invoked
 * from another JSP"):
 *
 * Test configures error pages for 403 response code and Throwable, see
 * web.xml.
 *
 * Test accesses 403.jsp, which sets the response code to 403 and therefore
 * causes a forward to the error403.jsp error page, which sets the response
 * content type to text/xml;charset=Shift_JIS.
 * 
 * Test then accesses throwable.jsp, which throws a Throwable and therefore
 * causes a forward to the errorThrowable.jsp error page, which sets the
 * response content type to text/xml;charset=Shift_JIS.
 *
 * Test enforces that both responses carry this content type, and reports
 * an error otherwise.
 */
public class WebTest {

    private static SimpleReporterAdapter stat
        = new SimpleReporterAdapter("appserv-tests");

    private static final String TEST_NAME
        = "jsp-allow-error-page-to-set-response-charset-if-no-output-written";

    private static final String EXPECTED_CONTENT_TYPE
        = " text/xml;charset=Shift_JIS";

    private String host;
    private String port;
    private String contextRoot;

    public WebTest(String[] args) {
        host = args[0];
        port = args[1];
        contextRoot = args[2];
    }
    
    public static void main(String[] args) {
        stat.addDescription("Unit test for GlassFish Issue 815");
        WebTest webTest = new WebTest(args);
        webTest.doTest();
        stat.printSummary(TEST_NAME);
    }

    public void doTest() {     
        try { 
            invoke("/403.jsp", "HTTP/1.1 403");
            invoke("/throwable.jsp", "HTTP/1.1 500");
            stat.addStatus(TEST_NAME, stat.PASS);
        } catch (Exception ex) {
            stat.addStatus(TEST_NAME, stat.FAIL);
            ex.printStackTrace();
        }
    }

    private void invoke(String uri, String expectedResponseCode)
            throws Exception {

        Socket sock = null;
        OutputStream os = null;
        InputStream is = null;
        BufferedReader bis = null;
        try {
            sock = new Socket(host, new Integer(port).intValue());
            os = sock.getOutputStream();
            String get = "GET " + contextRoot + uri + " HTTP/1.0\n";
            System.out.println(get);
            os.write(get.getBytes());
            os.write("\n".getBytes());

            is = sock.getInputStream();
            bis = new BufferedReader(new InputStreamReader(is));

            String line = null;
            boolean expectedResponseCodeSeen = false;
            while ((line = bis.readLine()) != null) {
                if (line.contains(expectedResponseCode)) {
                    expectedResponseCodeSeen = true;
                }
                if (line.toLowerCase().startsWith("content-type:")) {
                    break;
                }
            }

            if (!expectedResponseCodeSeen) {
                throw new Exception("Response does not have expected response "
                                    + "code: " + expectedResponseCode);
            }

            if ((line == null) || (line.toLowerCase().startsWith("content-type:") && !line.contains(EXPECTED_CONTENT_TYPE))) {
                throw new Exception("Wrong response content type. Expected: "
                                    + EXPECTED_CONTENT_TYPE + ", received: "
                                    + line);
            }
        } finally {
            try {
                if (os != null) os.close();
            } catch (IOException ex) {}
            try {
                if (is != null) is.close();
            } catch (IOException ex) {}
            try {
                if (sock != null) sock.close();
            } catch (IOException ex) {}
            try {
                if (bis != null) bis.close();
            } catch (IOException ex) {}
        }
    }
}
