jdk/test/sun/net/www/protocol/http/B5017051.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/protocol/http/B5017051.java	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 5017051 6360774
+ * @run main/othervm B5017051
+ * @summary Tests CR 5017051 & 6360774
+ */
+
+import java.net.*;
+import java.util.*;
+import java.io.*;
+import com.sun.net.httpserver.*;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+
+/*
+ * Part 1:
+ *  First request sent to the http server will not have an "Authorization" header set and
+ *  the server will respond with a 401, but not until it has set a cookie in the response
+ *  headers. The subsequent request ( comes from HttpURLConnection's authentication retry )
+ *  will have the appropriate Authorization header and the servers context handler will be
+ *  invoked. The test passes only if the client (HttpURLConnection) has sent the cookie
+ *  in its second request that had been set via the first response from the server.
+ *
+ * Part 2:
+ *  Preload the CookieManager with a cookie. Make a http request that requires authentication
+ *  The cookie will be sent in the first request (without the Authorization header), the
+ *  server will respond with a 401 (from MyBasicAuthFilter) and the client will add the
+ *  appropriate Authorization header. This tests ensures that there is only one Cookie header
+ *  in the request that actually makes it to the Http servers context handler.
+ */
+
+public class B5017051
+{
+    com.sun.net.httpserver.HttpServer httpServer;
+    ExecutorService executorService;
+
+    public static void main(String[] args)
+    {
+        new B5017051();
+    }
+
+    public B5017051()
+    {
+        try {
+            startHttpServer();
+            doClient();
+        } catch (IOException ioe) {
+            System.err.println(ioe);
+        }
+    }
+
+    void doClient() {
+        java.net.Authenticator.setDefault(new MyAuthenticator());
+        CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
+
+        try {
+            InetSocketAddress address = httpServer.getAddress();
+
+            // Part 1
+            URL url = new URL("http://" + address.getHostName() + ":" + address.getPort() + "/test/");
+            HttpURLConnection uc = (HttpURLConnection)url.openConnection();
+            int resp = uc.getResponseCode();
+            if (resp != 200)
+                throw new RuntimeException("Failed: Part 1, Response code is not 200");
+
+            System.out.println("Response code from Part 1 = 200 OK");
+
+            // Part 2
+            URL url2 = new URL("http://" + address.getHostName() + ":" + address.getPort() + "/test2/");
+
+            // can use the global CookieHandler used for the first test as the URL's are different
+            CookieHandler ch = CookieHandler.getDefault();
+            Map<String,List<String>> header = new HashMap<String,List<String>>();
+            List<String> values = new LinkedList<String>();
+            values.add("Test2Cookie=\"TEST2\"; path=\"/test2/\"");
+            header.put("Set-Cookie2", values);
+
+            // preload the CookieHandler with a cookie for our URL
+            // so that it will be sent during the first request
+            ch.put(url2.toURI(), header);
+
+            uc = (HttpURLConnection)url2.openConnection();
+            resp = uc.getResponseCode();
+            if (resp != 200)
+                throw new RuntimeException("Failed: Part 2, Response code is not 200");
+
+            System.out.println("Response code from Part 2 = 200 OK");
+
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (URISyntaxException ue) {
+            ue.printStackTrace();
+        } finally {
+            httpServer.stop(1);
+            executorService.shutdown();
+        }
+    }
+
+    /**
+     * Http Server
+     */
+    public void startHttpServer() throws IOException {
+        httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0);
+
+        // create HttpServer context for Part 1.
+        HttpContext ctx = httpServer.createContext("/test/", new MyHandler());
+        ctx.setAuthenticator( new MyBasicAuthenticator("foo"));
+        // CookieFilter needs to be executed before Authenticator.
+        ctx.getFilters().add(0, new CookieFilter());
+
+        // create HttpServer context for Part 2.
+        HttpContext ctx2 = httpServer.createContext("/test2/", new MyHandler2());
+        ctx2.setAuthenticator( new MyBasicAuthenticator("foobar"));
+
+        executorService = Executors.newCachedThreadPool();
+        httpServer.setExecutor(executorService);
+        httpServer.start();
+    }
+
+    class MyHandler implements HttpHandler {
+        public void handle(HttpExchange t) throws IOException {
+            InputStream is = t.getRequestBody();
+            Headers reqHeaders = t.getRequestHeaders();
+            Headers resHeaders = t.getResponseHeaders();
+            while (is.read () != -1) ;
+            is.close();
+
+            if (!reqHeaders.containsKey("Authorization"))
+                t.sendResponseHeaders(400, -1);
+
+            List<String> cookies = reqHeaders.get("Cookie");
+            if (cookies != null) {
+                for (String str : cookies) {
+                    if (str.equals("Customer=WILE_E_COYOTE"))
+                        t.sendResponseHeaders(200, -1);
+                }
+            }
+            t.sendResponseHeaders(400, -1);
+        }
+    }
+
+    class MyHandler2 implements HttpHandler {
+        public void handle(HttpExchange t) throws IOException {
+            InputStream is = t.getRequestBody();
+            Headers reqHeaders = t.getRequestHeaders();
+            Headers resHeaders = t.getResponseHeaders();
+            while (is.read () != -1) ;
+            is.close();
+
+            if (!reqHeaders.containsKey("Authorization"))
+                t.sendResponseHeaders(400, -1);
+
+            List<String> cookies = reqHeaders.get("Cookie");
+
+            // there should only be one Cookie header
+            if (cookies != null && (cookies.size() == 1)) {
+                t.sendResponseHeaders(200, -1);
+            }
+            t.sendResponseHeaders(400, -1);
+        }
+    }
+
+    class MyAuthenticator extends java.net.Authenticator {
+        public PasswordAuthentication getPasswordAuthentication () {
+            return new PasswordAuthentication("tester", "passwd".toCharArray());
+        }
+    }
+
+    class MyBasicAuthenticator extends BasicAuthenticator
+    {
+        public MyBasicAuthenticator(String realm) {
+            super(realm);
+        }
+
+        public boolean checkCredentials (String username, String password) {
+            return username.equals("tester") && password.equals("passwd");
+        }
+    }
+
+    class CookieFilter extends Filter
+    {
+        public void doFilter(HttpExchange t, Chain chain) throws IOException
+        {
+            Headers resHeaders = t.getResponseHeaders();
+            Headers reqHeaders = t.getRequestHeaders();
+
+            if (!reqHeaders.containsKey("Authorization"))
+                resHeaders.set("Set-Cookie2", "Customer=\"WILE_E_COYOTE\"; path=\"/test/\"");
+
+            chain.doFilter(t);
+        }
+
+        public void destroy(HttpContext c) { }
+
+        public void init(HttpContext c) { }
+
+        public String description() {
+            return new String("Filter for setting a cookie for requests without an \"Authorization\" header.");
+        }
+    }
+}