jdk/test/java/net/httpclient/ProxyAuthTest.java
changeset 40560 5641adb8d196
child 41103 c0b875b35b1e
equal deleted inserted replaced
40559:e727ba540ee6 40560:5641adb8d196
       
     1 /*
       
     2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  */
       
    24 
       
    25 /*
       
    26  * @test
       
    27  * @bug 8163561
       
    28  * @modules java.base/sun.net.www
       
    29  * @summary Verify that Proxy-Authenticate header is correctly handled
       
    30  *
       
    31  * @run main/othervm ProxyAuthTest
       
    32  */
       
    33 
       
    34 import java.io.BufferedWriter;
       
    35 import java.io.IOException;
       
    36 import java.io.InputStream;
       
    37 import java.io.OutputStream;
       
    38 import java.io.OutputStreamWriter;
       
    39 import java.io.PrintWriter;
       
    40 import java.net.Authenticator;
       
    41 import java.net.InetSocketAddress;
       
    42 import java.net.PasswordAuthentication;
       
    43 import java.net.ProxySelector;
       
    44 import java.net.ServerSocket;
       
    45 import java.net.Socket;
       
    46 import java.net.URI;
       
    47 import java.net.http.HttpClient;
       
    48 import java.net.http.HttpResponse;
       
    49 import java.util.Base64;
       
    50 
       
    51 import sun.net.www.MessageHeader;
       
    52 
       
    53 public class ProxyAuthTest {
       
    54     private static final String AUTH_USER = "user";
       
    55     private static final String AUTH_PASSWORD = "password";
       
    56 
       
    57     public static void main(String[] args) throws Exception {
       
    58         try (ServerSocket ss = new ServerSocket(0)) {
       
    59             int port = ss.getLocalPort();
       
    60             MyProxy proxy = new MyProxy(ss);
       
    61             (new Thread(proxy)).start();
       
    62             System.out.println("Proxy listening port " + port);
       
    63 
       
    64             Auth auth = new Auth();
       
    65             InetSocketAddress paddr = new InetSocketAddress("localhost", port);
       
    66 
       
    67             URI uri = new URI("http://www.google.ie/");
       
    68             HttpClient client = HttpClient.create()
       
    69                     .proxy(ProxySelector.of(paddr))
       
    70                     .authenticator(auth)
       
    71                     .build();
       
    72             HttpResponse resp = client.request(uri)
       
    73                     .GET()
       
    74                     .responseAsync()
       
    75                     .get();
       
    76             if (resp.statusCode() != 404) {
       
    77                 throw new RuntimeException("Unexpected status code: " + resp.statusCode());
       
    78             }
       
    79 
       
    80             if (auth.isCalled) {
       
    81                 System.out.println("Authenticator is called");
       
    82             } else {
       
    83                 throw new RuntimeException("Authenticator is not called");
       
    84             }
       
    85 
       
    86             if (!proxy.matched) {
       
    87                 throw new RuntimeException("Proxy authentication failed");
       
    88             }
       
    89         }
       
    90     }
       
    91 
       
    92     static class Auth extends Authenticator {
       
    93         private volatile boolean isCalled;
       
    94 
       
    95         @Override
       
    96         protected PasswordAuthentication getPasswordAuthentication() {
       
    97             System.out.println("scheme: " + this.getRequestingScheme());
       
    98             isCalled = true;
       
    99             return new PasswordAuthentication(AUTH_USER,
       
   100                     AUTH_PASSWORD.toCharArray());
       
   101         }
       
   102     }
       
   103 
       
   104     static class MyProxy implements Runnable {
       
   105         final ServerSocket ss;
       
   106         private volatile boolean matched;
       
   107 
       
   108         MyProxy(ServerSocket ss) {
       
   109             this.ss = ss;
       
   110         }
       
   111 
       
   112         public void run() {
       
   113             for (int i = 0; i < 2; i++) {
       
   114                 try (Socket s = ss.accept();
       
   115                      InputStream in = s.getInputStream();
       
   116                      OutputStream os = s.getOutputStream();
       
   117                      BufferedWriter writer = new BufferedWriter(
       
   118                              new OutputStreamWriter(os));
       
   119                      PrintWriter out = new PrintWriter(writer);) {
       
   120                     MessageHeader headers = new MessageHeader(in);
       
   121                     System.out.println("Proxy: received " + headers);
       
   122 
       
   123                     String authInfo = headers
       
   124                             .findValue("Proxy-Authorization");
       
   125                     if (authInfo != null) {
       
   126                         authenticate(authInfo);
       
   127                         out.print("HTTP/1.1 404 Not found\r\n");
       
   128                         out.print("\r\n");
       
   129                         System.out.println("Proxy: 404");
       
   130                         out.flush();
       
   131                     } else {
       
   132                         out.print("HTTP/1.1 407 Proxy Authorization Required\r\n");
       
   133                         out.print(
       
   134                                 "Proxy-Authenticate: Basic realm=\"a fake realm\"\r\n");
       
   135                         out.print("\r\n");
       
   136                         System.out.println("Proxy: Authorization required");
       
   137                         out.flush();
       
   138                     }
       
   139                 } catch (IOException x) {
       
   140                     System.err.println("Unexpected IOException from proxy.");
       
   141                     x.printStackTrace();
       
   142                     break;
       
   143                 }
       
   144             }
       
   145         }
       
   146 
       
   147         private void authenticate(String authInfo) throws IOException {
       
   148             try {
       
   149                 authInfo.trim();
       
   150                 int ind = authInfo.indexOf(' ');
       
   151                 String recvdUserPlusPass = authInfo.substring(ind + 1).trim();
       
   152                 // extract encoded username:passwd
       
   153                 String value = new String(
       
   154                         Base64.getMimeDecoder().decode(recvdUserPlusPass));
       
   155                 String userPlusPassword = AUTH_USER + ":" + AUTH_PASSWORD;
       
   156                 if (userPlusPassword.equals(value)) {
       
   157                     matched = true;
       
   158                     System.out.println("Proxy: client authentication successful");
       
   159                 } else {
       
   160                     System.err.println(
       
   161                             "Proxy: client authentication failed, expected ["
       
   162                                     + userPlusPassword + "], actual [" + value
       
   163                                     + "]");
       
   164                 }
       
   165             } catch (Exception e) {
       
   166                 throw new IOException(
       
   167                         "Proxy received invalid Proxy-Authorization value: "
       
   168                                 + authInfo);
       
   169             }
       
   170         }
       
   171     }
       
   172 
       
   173 }
       
   174