1/* 2 * Copyright (c) 2014, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/* 25 * @test 26 * @bug 8027308 27 * @modules jdk.httpserver 28 * @summary verifies that HttpURLConnection does not send the zone id in the 29 * 'Host' field of the header: 30 * Host: [fe80::a00:27ff:aaaa:aaaa] instead of 31 * Host: [fe80::a00:27ff:aaaa:aaaa%eth0]" 32 */ 33 34import com.sun.net.httpserver.Headers; 35import com.sun.net.httpserver.HttpExchange; 36import com.sun.net.httpserver.HttpHandler; 37import com.sun.net.httpserver.HttpServer; 38 39import java.io.IOException; 40import java.net.*; 41import java.util.Enumeration; 42import java.util.List; 43import java.util.Optional; 44import java.util.concurrent.CompletableFuture; 45import static java.lang.System.out; 46import static java.net.Proxy.NO_PROXY; 47 48public class ZoneId { 49 50 public static void main(String[] args) throws Exception { 51 52 InetAddress address = getIPv6LookbackAddress(); 53 54 if (address == null) { 55 out.println("Cannot find the IPv6 loopback address. Skipping test."); 56 return; 57 } 58 String ip6_literal = address.getHostAddress(); 59 60 out.println("Found an appropriate IPv6 address: " + address); 61 62 out.println("Starting http server..."); 63 HttpServer server = HttpServer.create(new InetSocketAddress(0), 0); 64 CompletableFuture<Headers> headers = new CompletableFuture<>(); 65 server.createContext("/", createCapturingHandler(headers)); 66 server.start(); 67 out.println("Started at " + server.getAddress()); 68 69 try { 70 int port = server.getAddress().getPort(); 71 String spec = "http://[" + address.getHostAddress() + "]:" + port; 72 out.println("Client is connecting to: " + spec); 73 URL url = new URL(spec); 74 HttpURLConnection uc = (HttpURLConnection)url.openConnection(NO_PROXY); 75 uc.getResponseCode(); 76 } finally { 77 out.println("Shutting down the server..."); 78 server.stop(0); 79 } 80 81 int idx = ip6_literal.lastIndexOf('%'); 82 String ip6_address = ip6_literal.substring(0, idx); 83 List<String> hosts = headers.get().get("Host"); 84 85 out.println("Host: " + hosts); 86 87 if (hosts.size() != 1 || hosts.get(0).contains("%") || 88 !hosts.get(0).contains(ip6_address)) { 89 throw new RuntimeException("FAIL"); 90 } 91 } 92 93 static InetAddress getIPv6LookbackAddress() throws SocketException { 94 out.println("Searching for the IPv6 loopback address..."); 95 Enumeration<NetworkInterface> is = NetworkInterface.getNetworkInterfaces(); 96 97 // The IPv6 loopback address contains a scope id, and is "connect-able". 98 while (is.hasMoreElements()) { 99 NetworkInterface i = is.nextElement(); 100 if (!i.isLoopback()) 101 continue; 102 Optional<InetAddress> addr = i.inetAddresses() 103 .filter(x -> x instanceof Inet6Address) 104 .filter(y -> y.toString().contains("%")) 105 .findFirst(); 106 if (addr.isPresent()) 107 return addr.get(); 108 } 109 110 return null; 111 } 112 113 static HttpHandler createCapturingHandler(CompletableFuture<Headers> headers) { 114 return new HttpHandler() { 115 @Override 116 public void handle(HttpExchange exchange) throws IOException { 117 headers.complete(exchange.getRequestHeaders()); 118 exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, -1); 119 exchange.close(); 120 } 121 }; 122 } 123} 124