/*
 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/**
 * @test
 * @bug 4722333
 * @library ../../../sun/net/www/httptest/
 * @build HttpCallback HttpServer ClosedChannelList HttpTransaction
 * @run main B4722333
 * @summary JRE Proxy Authentication Not Working with ISA2000
 */

import java.io.*;
import java.net.*;

public class B4722333 implements HttpCallback {

    static int count = 0;

    static String [][] expected = {
       /* scheme  realm/prompt */
        {"basic", "foo"},
        {"basic", "foobar"},
        {"digest", "biz"},
        {"digest", "bizbar"},
        {"digest", "foobiz"}
    };

    public void request (HttpTransaction req) {
        try {
            if (count % 2 == 1 ) {
                req.setResponseEntityBody ("Hello .");
                req.sendResponse (200, "Ok");
                req.orderlyClose();
            } else {
                switch (count) {
                  case 0:
                    req.addResponseHeader ("Connection", "close");
                    req.addResponseHeader ("WWW-Authenticate", "Basic realm=\"foo\"");
                    req.addResponseHeader ("WWW-Authenticate", "Foo realm=\"bar\"");
                    req.sendResponse (401, "Unauthorized");
                    req.orderlyClose();
                    break;
                  case 2:
                    req.addResponseHeader ("Connection", "close");
                    req.addResponseHeader ("WWW-Authenticate", "Basic realm=\"foobar\" Foo realm=\"bar\"");
                    req.sendResponse (401, "Unauthorized");
                    break;
                  case 4:
                    req.addResponseHeader ("Connection", "close");
                    req.addResponseHeader ("WWW-Authenticate", "Digest realm=biz domain=/foo nonce=thisisanonce ");
                    req.addResponseHeader ("WWW-Authenticate", "Basic realm=bizbar");
                    req.sendResponse (401, "Unauthorized");
                    req.orderlyClose();
                    break;
                  case 6:
                    req.addResponseHeader ("Connection", "close");
                    req.addResponseHeader ("WWW-Authenticate", "Digest realm=\"bizbar\" domain=/biz nonce=\"hereisanonce\" Basic realm=\"foobar\" Foo realm=\"bar\"");
                    req.sendResponse (401, "Unauthorized");
                    req.orderlyClose();
                    break;
                  case 8:
                    req.addResponseHeader ("Connection", "close");
                    req.addResponseHeader ("WWW-Authenticate", "Foo p1=1 p2=2 p3=3 p4=4 p5=5 p6=6 p7=7 p8=8 p9=10 Digest realm=foobiz domain=/foobiz nonce=newnonce");
                    req.addResponseHeader ("WWW-Authenticate", "Basic realm=bizbar");
                    req.sendResponse (401, "Unauthorized");
                    req.orderlyClose();
                    break;
                }
            }
            count ++;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static void read (InputStream is) throws IOException {
        int c;
        System.out.println ("reading");
        while ((c=is.read()) != -1) {
            System.out.write (c);
        }
        System.out.println ("");
        System.out.println ("finished reading");
    }


    static void client (String u) throws Exception {
        URL url = new URL (u);
        System.out.println ("client opening connection to: " + u);
        URLConnection urlc = url.openConnection ();
        InputStream is = urlc.getInputStream ();
        read (is);
        is.close();
    }

    static HttpServer server;

    public static void main (String[] args) throws Exception {
        MyAuthenticator auth = new MyAuthenticator ();
        Authenticator.setDefault (auth);
        try {
            server = new HttpServer (new B4722333(), 1, 10, 0);
            System.out.println ("Server started: listening on port: " + server.getLocalPort());
            client ("http://localhost:"+server.getLocalPort()+"/d1/d2/d3/foo.html");
            client ("http://localhost:"+server.getLocalPort()+"/ASD/d3/x.html");
            client ("http://localhost:"+server.getLocalPort()+"/biz/d3/x.html");
            client ("http://localhost:"+server.getLocalPort()+"/bar/d3/x.html");
            client ("http://localhost:"+server.getLocalPort()+"/fuzz/d3/x.html");
        } catch (Exception e) {
            if (server != null) {
                server.terminate();
            }
            throw e;
        }
        int f = auth.getCount();
        if (f != expected.length) {
            except ("Authenticator was called "+f+" times. Should be " + expected.length);
        }
        server.terminate();
    }

    public static void except (String s) {
        server.terminate();
        throw new RuntimeException (s);
    }

    static class MyAuthenticator extends Authenticator {
        MyAuthenticator () {
            super ();
        }

        int count = 0;

        public PasswordAuthentication getPasswordAuthentication ()
            {
            System.out.println ("Auth called");
            String scheme = getRequestingScheme();
            System.out.println ("getRequestingScheme() returns " + scheme);
            String prompt = getRequestingPrompt();
            System.out.println ("getRequestingPrompt() returns " + prompt);

            if (!scheme.equals (expected [count][0])) {
                B4722333.except ("wrong scheme received, " + scheme + " expected " + expected [count][0]);
            }
            if (!prompt.equals (expected [count][1])) {
                B4722333.except ("wrong realm received, " + prompt + " expected " + expected [count][1]);
            }
            count ++;
            return (new PasswordAuthentication ("user", "passwordNotCheckedAnyway".toCharArray()));
        }

        public int getCount () {
            return (count);
        }
    }

}
