8224603: Replace wildcard address with loopback or local host in tests - part 11

Fixes a batch of tests that were observed failing intermittently.

Reviewed-by: chegar, vtewari
This commit is contained in:
Daniel Fuchs 2019-05-24 15:34:14 +01:00
parent 241c32ca51
commit ee040e4be2
13 changed files with 524 additions and 433 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,11 +27,14 @@
* @library /test/lib * @library /test/lib
* @build jdk.test.lib.net.SimpleSSLContext * @build jdk.test.lib.net.SimpleSSLContext
* @run main/othervm -Dsun.net.httpserver.selCacheTimeout=2 SelCacheTest * @run main/othervm -Dsun.net.httpserver.selCacheTimeout=2 SelCacheTest
* @run main/othervm -Djava.net.preferIPv6Addresses=true
-Dsun.net.httpserver.selCacheTimeout=2 SelCacheTest
* @summary Light weight HTTP server * @summary Light weight HTTP server
*/ */
import com.sun.net.httpserver.*; import com.sun.net.httpserver.*;
import jdk.test.lib.net.SimpleSSLContext; import jdk.test.lib.net.SimpleSSLContext;
import jdk.test.lib.net.URIBuilder;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
@ -49,92 +52,99 @@ public class SelCacheTest extends Test {
static SSLContext ctx; static SSLContext ctx;
public static void main (String[] args) throws Exception { public static void main(String[] args) throws Exception {
HttpServer s1 = null; HttpServer s1 = null;
HttpsServer s2 = null; HttpsServer s2 = null;
ExecutorService executor=null; ExecutorService executor=null;
InetAddress loopback = InetAddress.getLoopbackAddress();
try { try {
String root = System.getProperty ("test.src")+ "/docs"; String root = System.getProperty("test.src")+ "/docs";
System.out.print ("Test1: "); System.out.print("Test1: ");
InetSocketAddress addr = new InetSocketAddress (0); InetSocketAddress addr = new InetSocketAddress(loopback, 0);
s1 = HttpServer.create (addr, 0); s1 = HttpServer.create(addr, 0);
if (s1 instanceof HttpsServer) { if (s1 instanceof HttpsServer) {
throw new RuntimeException ("should not be httpsserver"); throw new RuntimeException("should not be httpsserver");
} }
s2 = HttpsServer.create (addr, 0); s2 = HttpsServer.create(addr, 0);
HttpHandler h = new FileServerHandler (root); HttpHandler h = new FileServerHandler(root);
HttpContext c1 = s1.createContext ("/test1", h); HttpContext c1 = s1.createContext("/test1", h);
HttpContext c2 = s2.createContext ("/test1", h); HttpContext c2 = s2.createContext("/test1", h);
executor = Executors.newCachedThreadPool(); executor = Executors.newCachedThreadPool();
s1.setExecutor (executor); s1.setExecutor(executor);
s2.setExecutor (executor); s2.setExecutor(executor);
ctx = new SimpleSSLContext().get(); ctx = new SimpleSSLContext().get();
s2.setHttpsConfigurator(new HttpsConfigurator (ctx)); s2.setHttpsConfigurator(new HttpsConfigurator(ctx));
s1.start(); s1.start();
s2.start(); s2.start();
int port = s1.getAddress().getPort(); int port = s1.getAddress().getPort();
int httpsport = s2.getAddress().getPort(); int httpsport = s2.getAddress().getPort();
test (true, "http", root+"/test1", port, "smallfile.txt", 23); test(true, "http", root+"/test1", loopback, port, "smallfile.txt", 23);
test (true, "http", root+"/test1", port, "largefile.txt", 2730088); test(true, "http", root+"/test1", loopback, port, "largefile.txt", 2730088);
test (true, "https", root+"/test1", httpsport, "smallfile.txt", 23); test(true, "https", root+"/test1", loopback, httpsport, "smallfile.txt", 23);
test (true, "https", root+"/test1", httpsport, "largefile.txt", 2730088); test(true, "https", root+"/test1", loopback, httpsport, "largefile.txt", 2730088);
test (false, "http", root+"/test1", port, "smallfile.txt", 23); test(false, "http", root+"/test1", loopback, port, "smallfile.txt", 23);
test (false, "http", root+"/test1", port, "largefile.txt", 2730088); test(false, "http", root+"/test1", loopback, port, "largefile.txt", 2730088);
test (false, "https", root+"/test1", httpsport, "smallfile.txt", 23); test(false, "https", root+"/test1", loopback, httpsport, "smallfile.txt", 23);
test (false, "https", root+"/test1", httpsport, "largefile.txt", 2730088); test(false, "https", root+"/test1", loopback, httpsport, "largefile.txt", 2730088);
System.out.println ("OK"); System.out.println("OK");
} finally { } finally {
delay(); delay();
s1.stop(2); s1.stop(2);
s2.stop(2); s2.stop(2);
executor.shutdown (); executor.shutdown();
} }
} }
static void test (boolean fixedLen, String protocol, String root, int port, String f, int size) throws Exception { static void test(boolean fixedLen, String protocol, String root,
Thread.sleep (2000); InetAddress address, int port, String f, int size) throws Exception {
URL url = new URL (protocol+"://localhost:"+port+"/test1/"+f); Thread.sleep(2000);
HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); URL url = URIBuilder.newBuilder()
.scheme(protocol)
.host(address)
.port(port)
.path("/test1/"+f)
.toURL();
HttpURLConnection urlc = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
if (urlc instanceof HttpsURLConnection) { if (urlc instanceof HttpsURLConnection) {
HttpsURLConnection urlcs = (HttpsURLConnection) urlc; HttpsURLConnection urlcs = (HttpsURLConnection) urlc;
urlcs.setHostnameVerifier (new HostnameVerifier () { urlcs.setHostnameVerifier(new HostnameVerifier() {
public boolean verify (String s, SSLSession s1) { public boolean verify(String s, SSLSession s1) {
return true; return true;
} }
}); });
urlcs.setSSLSocketFactory (ctx.getSocketFactory()); urlcs.setSSLSocketFactory(ctx.getSocketFactory());
} }
byte [] buf = new byte [4096]; byte [] buf = new byte [4096];
if (fixedLen) { if (fixedLen) {
urlc.setRequestProperty ("XFixed", "yes"); urlc.setRequestProperty("XFixed", "yes");
} }
InputStream is = urlc.getInputStream(); InputStream is = urlc.getInputStream();
File temp = File.createTempFile ("Test1", null); File temp = File.createTempFile("Test1", null);
temp.deleteOnExit(); temp.deleteOnExit();
OutputStream fout = new BufferedOutputStream (new FileOutputStream(temp)); OutputStream fout = new BufferedOutputStream(new FileOutputStream(temp));
int c, count = 0; int c, count = 0;
while ((c=is.read(buf)) != -1) { while ((c=is.read(buf)) != -1) {
count += c; count += c;
fout.write (buf, 0, c); fout.write(buf, 0, c);
} }
is.close(); is.close();
fout.close(); fout.close();
if (count != size) { if (count != size) {
throw new RuntimeException ("wrong amount of data returned"); throw new RuntimeException("wrong amount of data returned");
} }
String orig = root + "/" + f; String orig = root + "/" + f;
compare (new File(orig), temp); compare(new File(orig), temp);
temp.delete(); temp.delete();
} }
/* compare the contents of the two files */ /* compare the contents of the two files */
static void compare (File f1, File f2) throws IOException { static void compare(File f1, File f2) throws IOException {
InputStream i1 = new BufferedInputStream (new FileInputStream(f1)); InputStream i1 = new BufferedInputStream(new FileInputStream(f1));
InputStream i2 = new BufferedInputStream (new FileInputStream(f2)); InputStream i2 = new BufferedInputStream(new FileInputStream(f2));
int c1,c2; int c1,c2;
@ -142,11 +152,11 @@ public class SelCacheTest extends Test {
while ((c1=i1.read()) != -1) { while ((c1=i1.read()) != -1) {
c2 = i2.read(); c2 = i2.read();
if (c1 != c2) { if (c1 != c2) {
throw new RuntimeException ("file compare failed 1"); throw new RuntimeException("file compare failed 1");
} }
} }
if (i2.read() != -1) { if (i2.read() != -1) {
throw new RuntimeException ("file compare failed 2"); throw new RuntimeException("file compare failed 2");
} }
} finally { } finally {
i1.close(); i1.close();

View File

@ -26,6 +26,7 @@
* @bug 6725892 * @bug 6725892
* @library /test/lib * @library /test/lib
* @run main/othervm -Dsun.net.httpserver.maxReqTime=2 Test * @run main/othervm -Dsun.net.httpserver.maxReqTime=2 Test
* @run main/othervm -Djava.net.preferIPv6Addresses=true -Dsun.net.httpserver.maxReqTime=2 Test
* @summary * @summary
*/ */
@ -49,36 +50,37 @@ public class Test {
static class Handler implements HttpHandler { static class Handler implements HttpHandler {
public void handle (HttpExchange t) public void handle(HttpExchange t)
throws IOException throws IOException
{ {
InputStream is = t.getRequestBody(); InputStream is = t.getRequestBody();
InetSocketAddress rem = t.getRemoteAddress(); InetSocketAddress rem = t.getRemoteAddress();
System.out.println ("Request from: " + rem); System.out.println("Request from: " + rem);
while (is.read () != -1) ; while (is.read () != -1) ;
is.close(); is.close();
String requrl = t.getRequestURI().toString(); String requrl = t.getRequestURI().toString();
OutputStream os = t.getResponseBody(); OutputStream os = t.getResponseBody();
t.sendResponseHeaders (200, RESPONSE_BODY.length()); t.sendResponseHeaders(200, RESPONSE_BODY.length());
os.write (RESPONSE_BODY.getBytes()); os.write(RESPONSE_BODY.getBytes());
t.close(); t.close();
} }
} }
public static void main (String[] args) throws Exception { public static void main(String[] args) throws Exception {
ExecutorService exec = Executors.newCachedThreadPool(); ExecutorService exec = Executors.newCachedThreadPool();
InetAddress loopback = InetAddress.getLoopbackAddress();
try { try {
InetSocketAddress addr = new InetSocketAddress (0); InetSocketAddress addr = new InetSocketAddress(loopback, 0);
s1 = HttpServer.create (addr, 100); s1 = HttpServer.create(addr, 100);
HttpHandler h = new Handler (); HttpHandler h = new Handler();
HttpContext c1 = s1.createContext ("/", h); HttpContext c1 = s1.createContext("/", h);
s1.setExecutor(exec); s1.setExecutor(exec);
s1.start(); s1.start();
port = s1.getAddress().getPort(); port = s1.getAddress().getPort();
System.out.println ("Server on port " + port); System.out.println("Server on port " + port);
url = URIBuilder.newBuilder() url = URIBuilder.newBuilder()
.scheme("http") .scheme("http")
.loopback() .loopback()
@ -89,14 +91,14 @@ public class Test {
test1(); test1();
test2(); test2();
test3(); test3();
Thread.sleep (2000); Thread.sleep(2000);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
System.out.println ("FAIL"); System.out.println("FAIL");
throw new RuntimeException (); throw new RuntimeException();
} finally { } finally {
s1.stop(0); s1.stop(0);
System.out.println ("After Shutdown"); System.out.println("After Shutdown");
exec.shutdown(); exec.shutdown();
} }
} }
@ -105,10 +107,10 @@ public class Test {
static void test1() throws IOException { static void test1() throws IOException {
failed = false; failed = false;
Socket s = new Socket (InetAddress.getLoopbackAddress(), port); Socket s = new Socket(InetAddress.getLoopbackAddress(), port);
InputStream is = s.getInputStream(); InputStream is = s.getInputStream();
// server should close connection after 2 seconds. We wait up to 10 // server should close connection after 2 seconds. We wait up to 10
s.setSoTimeout (10000); s.setSoTimeout(10000);
try { try {
is.read(); is.read();
} catch (SocketTimeoutException e) { } catch (SocketTimeoutException e) {
@ -116,36 +118,36 @@ public class Test {
} }
s.close(); s.close();
if (failed) { if (failed) {
System.out.println ("test1: FAIL"); System.out.println("test1: FAIL");
throw new RuntimeException (); throw new RuntimeException();
} else { } else {
System.out.println ("test1: OK"); System.out.println("test1: OK");
} }
} }
// send request and don't read response. Check server closes connection // send request and don't read response. Check server closes connection
static void test2() throws IOException { static void test2() throws IOException {
HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); HttpURLConnection urlc = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
urlc.setReadTimeout (20 * 1000); urlc.setReadTimeout(20 * 1000);
InputStream is = urlc.getInputStream(); InputStream is = urlc.getInputStream();
// we won't read response and check if it times out // we won't read response and check if it times out
// on server. If it timesout at client then there is a problem // on server. If it timesout at client then there is a problem
try { try {
Thread.sleep (10 * 1000); Thread.sleep(10 * 1000);
while (is.read() != -1) ; while (is.read() != -1) ;
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.out.println (e); System.out.println(e);
System.out.println ("test2: FAIL"); System.out.println("test2: FAIL");
throw new RuntimeException ("unexpected error"); throw new RuntimeException("unexpected error");
} catch (SocketTimeoutException e1) { } catch (SocketTimeoutException e1) {
System.out.println (e1); System.out.println(e1);
System.out.println ("test2: FAIL"); System.out.println("test2: FAIL");
throw new RuntimeException ("client timedout"); throw new RuntimeException("client timedout");
} finally { } finally {
is.close(); is.close();
} }
System.out.println ("test2: OK"); System.out.println("test2: OK");
} }
// same as test2, but repeated with multiple connections // same as test2, but repeated with multiple connections
@ -174,17 +176,17 @@ public class Test {
} }
void fail(String msg) { void fail(String msg) {
System.out.println (msg); System.out.println(msg);
failed = true; failed = true;
} }
public void run () { public void run() {
HttpURLConnection urlc; HttpURLConnection urlc;
InputStream is = null; InputStream is = null;
try { try {
urlc = (HttpURLConnection) url.openConnection(); urlc = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
urlc.setReadTimeout (20 * 1000); urlc.setReadTimeout(20 * 1000);
urlc.setDoOutput(true); urlc.setDoOutput(true);
} catch (IOException e) { } catch (IOException e) {
fail("Worker: failed to connect to server"); fail("Worker: failed to connect to server");
@ -193,17 +195,17 @@ public class Test {
} }
try { try {
OutputStream os = urlc.getOutputStream(); OutputStream os = urlc.getOutputStream();
os.write ("foo".getBytes()); os.write("foo".getBytes());
if (mode == Mode.REQUEST) { if (mode == Mode.REQUEST) {
Thread.sleep (3000); Thread.sleep(3000);
} }
os.close(); os.close();
is = urlc.getInputStream(); is = urlc.getInputStream();
if (mode == Mode.RESPONSE) { if (mode == Mode.RESPONSE) {
Thread.sleep (3000); Thread.sleep(3000);
} }
if (!checkResponse (is, RESPONSE_BODY)) { if (!checkResponse(is, RESPONSE_BODY)) {
fail ("Worker: response"); fail("Worker: response");
} }
is.close(); is.close();
return; return;
@ -214,11 +216,11 @@ public class Test {
} catch (IOException e2) { } catch (IOException e2) {
switch (mode) { switch (mode) {
case NORMAL: case NORMAL:
fail ("Worker: " + e2.getMessage()); fail("Worker: " + e2.getMessage());
break; break;
case RESPONSE: case RESPONSE:
if (is == null) { if (is == null) {
fail ("Worker: " + e2.getMessage()); fail("Worker: " + e2.getMessage());
break; break;
} }
// default: is ok // default: is ok
@ -233,12 +235,12 @@ public class Test {
static void test3() throws Exception { static void test3() throws Exception {
failed = false; failed = false;
CountDownLatch l = new CountDownLatch (NUM*3); CountDownLatch l = new CountDownLatch(NUM*3);
Worker[] workers = new Worker[NUM*3]; Worker[] workers = new Worker[NUM*3];
for (int i=0; i<NUM; i++) { for (int i=0; i<NUM; i++) {
workers[i*3] = new Worker (l, Worker.Mode.NORMAL); workers[i*3] = new Worker(l, Worker.Mode.NORMAL);
workers[i*3+1] = new Worker (l, Worker.Mode.REQUEST); workers[i*3+1] = new Worker(l, Worker.Mode.REQUEST);
workers[i*3+2] = new Worker (l, Worker.Mode.RESPONSE); workers[i*3+2] = new Worker(l, Worker.Mode.RESPONSE);
workers[i*3].start(); workers[i*3].start();
workers[i*3+1].start(); workers[i*3+1].start();
workers[i*3+2].start(); workers[i*3+2].start();
@ -248,26 +250,26 @@ public class Test {
workers[i].join(); workers[i].join();
} }
if (failed) { if (failed) {
throw new RuntimeException ("test3: failed"); throw new RuntimeException("test3: failed");
} }
System.out.println ("test3: OK"); System.out.println("test3: OK");
} }
static boolean checkResponse (InputStream is, String resp) { static boolean checkResponse(InputStream is, String resp) {
try { try {
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte [64]; byte[] buf = new byte[64];
int c; int c;
while ((c=is.read(buf)) != -1) { while ((c=is.read(buf)) != -1) {
bos.write (buf, 0, c); bos.write(buf, 0, c);
} }
bos.close(); bos.close();
if (!bos.toString().equals(resp)) { if (!bos.toString().equals(resp)) {
System.out.println ("Wrong response: " + bos.toString()); System.out.println("Wrong response: " + bos.toString());
return false; return false;
} }
} catch (IOException e) { } catch (IOException e) {
System.out.println (e); System.out.println(e);
return false; return false;
} }
return true; return true;

View File

@ -27,7 +27,7 @@
* @modules java.base/sun.net.www * @modules java.base/sun.net.www
* @library ../../../sun/net/www/httptest/ * @library ../../../sun/net/www/httptest/
* @build HttpCallback TestHttpServer ClosedChannelList HttpTransaction * @build HttpCallback TestHttpServer ClosedChannelList HttpTransaction
* @run main B4722333 * @run main/othervm B4722333
* @summary JRE Proxy Authentication Not Working with ISA2000 * @summary JRE Proxy Authentication Not Working with ISA2000
*/ */
@ -38,7 +38,7 @@ public class B4722333 implements HttpCallback {
static int count = 0; static int count = 0;
static String [][] expected = { static String[][] expected = {
/* scheme realm/prompt */ /* scheme realm/prompt */
{"basic", "foo"}, {"basic", "foo"},
{"basic", "foobar"}, {"basic", "foobar"},
@ -47,44 +47,44 @@ public class B4722333 implements HttpCallback {
{"digest", "foobiz"} {"digest", "foobiz"}
}; };
public void request (HttpTransaction req) { public void request(HttpTransaction req) {
try { try {
if (count % 2 == 1 ) { if (count % 2 == 1) {
req.setResponseEntityBody ("Hello ."); req.setResponseEntityBody("Hello .");
req.sendResponse (200, "Ok"); req.sendResponse(200, "Ok");
req.orderlyClose(); req.orderlyClose();
} else { } else {
switch (count) { switch (count) {
case 0: case 0:
req.addResponseHeader ("Connection", "close"); req.addResponseHeader("Connection", "close");
req.addResponseHeader ("WWW-Authenticate", "Basic realm=\"foo\""); req.addResponseHeader("WWW-Authenticate", "Basic realm=\"foo\"");
req.addResponseHeader ("WWW-Authenticate", "Foo realm=\"bar\""); req.addResponseHeader("WWW-Authenticate", "Foo realm=\"bar\"");
req.sendResponse (401, "Unauthorized"); req.sendResponse(401, "Unauthorized");
req.orderlyClose(); req.orderlyClose();
break; break;
case 2: case 2:
req.addResponseHeader ("Connection", "close"); req.addResponseHeader("Connection", "close");
req.addResponseHeader ("WWW-Authenticate", "Basic realm=\"foobar\" Foo realm=\"bar\""); req.addResponseHeader("WWW-Authenticate", "Basic realm=\"foobar\" Foo realm=\"bar\"");
req.sendResponse (401, "Unauthorized"); req.sendResponse(401, "Unauthorized");
break; break;
case 4: case 4:
req.addResponseHeader ("Connection", "close"); req.addResponseHeader("Connection", "close");
req.addResponseHeader ("WWW-Authenticate", "Digest realm=biz domain=/foo nonce=thisisanonce "); req.addResponseHeader("WWW-Authenticate", "Digest realm=biz domain=/foo nonce=thisisanonce ");
req.addResponseHeader ("WWW-Authenticate", "Basic realm=bizbar"); req.addResponseHeader("WWW-Authenticate", "Basic realm=bizbar");
req.sendResponse (401, "Unauthorized"); req.sendResponse(401, "Unauthorized");
req.orderlyClose(); req.orderlyClose();
break; break;
case 6: case 6:
req.addResponseHeader ("Connection", "close"); req.addResponseHeader("Connection", "close");
req.addResponseHeader ("WWW-Authenticate", "Digest realm=\"bizbar\" domain=/biz nonce=\"hereisanonce\" Basic realm=\"foobar\" Foo realm=\"bar\""); req.addResponseHeader("WWW-Authenticate", "Digest realm=\"bizbar\" domain=/biz nonce=\"hereisanonce\" Basic realm=\"foobar\" Foo realm=\"bar\"");
req.sendResponse (401, "Unauthorized"); req.sendResponse(401, "Unauthorized");
req.orderlyClose(); req.orderlyClose();
break; break;
case 8: case 8:
req.addResponseHeader ("Connection", "close"); 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", "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.addResponseHeader("WWW-Authenticate", "Basic realm=bizbar");
req.sendResponse (401, "Unauthorized"); req.sendResponse(401, "Unauthorized");
req.orderlyClose(); req.orderlyClose();
break; break;
} }
@ -95,40 +95,40 @@ public class B4722333 implements HttpCallback {
} }
} }
static void read (InputStream is) throws IOException { static void read(InputStream is) throws IOException {
int c; int c;
System.out.println ("reading"); System.out.println("reading");
while ((c=is.read()) != -1) { while ((c=is.read()) != -1) {
System.out.write (c); System.out.write(c);
} }
System.out.println (""); System.out.println("");
System.out.println ("finished reading"); System.out.println("finished reading");
} }
static void client (String u) throws Exception { static void client(String u) throws Exception {
URL url = new URL (u); URL url = new URL (u);
System.out.println ("client opening connection to: " + u); System.out.println("client opening connection to: " + u);
URLConnection urlc = url.openConnection (); URLConnection urlc = url.openConnection ();
InputStream is = urlc.getInputStream (); InputStream is = urlc.getInputStream ();
read (is); read(is);
is.close(); is.close();
} }
static TestHttpServer server; static TestHttpServer server;
public static void main (String[] args) throws Exception { public static void main(String[] args) throws Exception {
MyAuthenticator auth = new MyAuthenticator (); MyAuthenticator auth = new MyAuthenticator();
Authenticator.setDefault (auth); Authenticator.setDefault(auth);
try { try {
InetAddress loopback = InetAddress.getLoopbackAddress(); InetAddress loopback = InetAddress.getLoopbackAddress();
server = new TestHttpServer (new B4722333(), 1, 10, loopback, 0); server = new TestHttpServer(new B4722333(), 1, 10, loopback, 0);
System.out.println ("Server started: listening on port: " + server.getLocalPort()); System.out.println("Server started: listening on port: " + server.getLocalPort());
client ("http://" + server.getAuthority() + "/d1/d2/d3/foo.html"); client("http://" + server.getAuthority() + "/d1/d2/d3/foo.html");
client ("http://" + server.getAuthority() + "/ASD/d3/x.html"); client("http://" + server.getAuthority() + "/ASD/d3/x.html");
client ("http://" + server.getAuthority() + "/biz/d3/x.html"); client("http://" + server.getAuthority() + "/biz/d3/x.html");
client ("http://" + server.getAuthority() + "/bar/d3/x.html"); client("http://" + server.getAuthority() + "/bar/d3/x.html");
client ("http://" + server.getAuthority() + "/fuzz/d3/x.html"); client("http://" + server.getAuthority() + "/fuzz/d3/x.html");
} catch (Exception e) { } catch (Exception e) {
if (server != null) { if (server != null) {
server.terminate(); server.terminate();
@ -137,43 +137,42 @@ public class B4722333 implements HttpCallback {
} }
int f = auth.getCount(); int f = auth.getCount();
if (f != expected.length) { if (f != expected.length) {
except ("Authenticator was called "+f+" times. Should be " + expected.length); except("Authenticator was called "+f+" times. Should be " + expected.length);
} }
server.terminate(); server.terminate();
} }
public static void except (String s) { public static void except(String s) {
server.terminate(); server.terminate();
throw new RuntimeException (s); throw new RuntimeException(s);
} }
static class MyAuthenticator extends Authenticator { static class MyAuthenticator extends Authenticator {
MyAuthenticator () { MyAuthenticator() {
super (); super();
} }
int count = 0; int count = 0;
public PasswordAuthentication getPasswordAuthentication () public PasswordAuthentication getPasswordAuthentication() {
{ System.out.println("Auth called");
System.out.println ("Auth called");
String scheme = getRequestingScheme(); String scheme = getRequestingScheme();
System.out.println ("getRequestingScheme() returns " + scheme); System.out.println("getRequestingScheme() returns " + scheme);
String prompt = getRequestingPrompt(); String prompt = getRequestingPrompt();
System.out.println ("getRequestingPrompt() returns " + prompt); System.out.println("getRequestingPrompt() returns " + prompt);
if (!scheme.equals (expected [count][0])) { if (!scheme.equals(expected [count][0])) {
B4722333.except ("wrong scheme received, " + scheme + " expected " + expected [count][0]); B4722333.except("wrong scheme received, " + scheme + " expected " + expected [count][0]);
} }
if (!prompt.equals (expected [count][1])) { if (!prompt.equals(expected [count][1])) {
B4722333.except ("wrong realm received, " + prompt + " expected " + expected [count][1]); B4722333.except("wrong realm received, " + prompt + " expected " + expected [count][1]);
} }
count ++; count ++;
return (new PasswordAuthentication ("user", "passwordNotCheckedAnyway".toCharArray())); return (new PasswordAuthentication("user", "passwordNotCheckedAnyway".toCharArray()));
} }
public int getCount () { public int getCount () {
return (count); return count;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,8 @@
* @bug 4094894 * @bug 4094894
* @summary On W95/W98 it's not possible to send a datagram >12k * @summary On W95/W98 it's not possible to send a datagram >12k
* via the loopback address. * via the loopback address.
* @run main Send12k
* @run main/othervm -Djava.net.preferIPv6Addresses=true Send12k
*/ */
import java.net.*; import java.net.*;
@ -43,21 +45,24 @@ public class Send12k {
} else { } else {
SEND_SIZE = 16 * 1024; SEND_SIZE = 16 * 1024;
} }
InetAddress localHost = InetAddress.getLocalHost();
DatagramSocket s1 = new DatagramSocket(); DatagramSocket s1 = new DatagramSocket();
DatagramSocket s2 = new DatagramSocket(); DatagramSocket s2 = new DatagramSocket(0, localHost);
byte b1[] = new byte[ SEND_SIZE ]; byte b1[] = new byte[ SEND_SIZE ];
DatagramPacket p1 = new DatagramPacket(b1, 0, b1.length, DatagramPacket p1 = new DatagramPacket(b1, 0, b1.length,
InetAddress.getLocalHost(), localHost,
s2.getLocalPort()); s2.getLocalPort());
boolean sendOkay = true; boolean sendOkay = true;
try { try {
System.out.println("Sending to: [" + localHost + "]:" + s2.getLocalPort());
s1.send(p1); s1.send(p1);
} catch (IOException e) { } catch (IOException e) {
/* /*
* Prior to merlin a send of > 12k to loopback address * Prior to merlin a send of > 12k to loopback address
* would fail silently. * would fail silently.
*/ */
System.out.println("Sending failed: " + e);
sendOkay = false; sendOkay = false;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -51,7 +51,7 @@ public class CloseAvailable {
static void testClose() throws IOException { static void testClose() throws IOException {
boolean error = true; boolean error = true;
InetAddress addr = InetAddress.getLocalHost(); InetAddress addr = InetAddress.getLocalHost();
ServerSocket ss = new ServerSocket(0); ServerSocket ss = new ServerSocket(0, 0, addr);
int port = ss.getLocalPort(); int port = ss.getLocalPort();
Thread t = new Thread(new Thread("Close-Available-1") { Thread t = new Thread(new Thread("Close-Available-1") {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -51,12 +51,13 @@ public class Restart {
public static void main(String args[]) throws Exception { public static void main(String args[]) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational(); IPSupport.throwSkippedExceptionIfNonOperational();
ServerSocket ss = new ServerSocket(0); InetAddress localHost = InetAddress.getLocalHost();
ServerSocket ss = new ServerSocket(0, 0, localHost);
Socket s1 = null, s2 = null; Socket s1 = null, s2 = null;
try { try {
int port = ss.getLocalPort(); int port = ss.getLocalPort();
s1 = new Socket(InetAddress.getLocalHost(), port); s1 = new Socket(localHost, port);
s2 = ss.accept(); s2 = ss.accept();
// close server socket and the accepted connection // close server socket and the accepted connection
@ -64,7 +65,7 @@ public class Restart {
s2.close(); s2.close();
ss = new ServerSocket(); ss = new ServerSocket();
ss.bind( new InetSocketAddress(port) ); ss.bind( new InetSocketAddress(localHost, port) );
ss.close(); ss.close();
// close the client socket // close the client socket

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,7 @@
* @run main/othervm BadProxySelector * @run main/othervm BadProxySelector
*/ */
import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Proxy; import java.net.Proxy;
import java.net.ProxySelector; import java.net.ProxySelector;
@ -41,13 +42,13 @@ import java.io.*;
public class BadProxySelector { public class BadProxySelector {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
ProxySelector.setDefault(new HTTPProxySelector()); ProxySelector.setDefault(new HTTPProxySelector());
try (ServerSocket ss = new ServerSocket(0); try (ServerSocket ss = new ServerSocket(0, 0, InetAddress.getLocalHost());
Socket s1 = new Socket(ss.getInetAddress(), ss.getLocalPort()); Socket s1 = new Socket(ss.getInetAddress(), ss.getLocalPort());
Socket s2 = ss.accept()) { Socket s2 = ss.accept()) {
} }
ProxySelector.setDefault(new NullHTTPProxySelector()); ProxySelector.setDefault(new NullHTTPProxySelector());
try (ServerSocket ss = new ServerSocket(0); try (ServerSocket ss = new ServerSocket(0, 0, InetAddress.getLocalHost());
Socket s1 = new Socket(ss.getInetAddress(), ss.getLocalPort()); Socket s1 = new Socket(ss.getInetAddress(), ss.getLocalPort());
Socket s2 = ss.accept()) { Socket s2 = ss.accept()) {
} }
@ -60,6 +61,7 @@ public class BadProxySelector {
@Override @Override
public List<Proxy> select(URI uri) { public List<Proxy> select(URI uri) {
System.out.println(this.getClass().getSimpleName() + " called for " + uri);
List<Proxy> proxies = new ArrayList<>(); List<Proxy> proxies = new ArrayList<>();
proxies.add(new Proxy(Proxy.Type.HTTP, proxies.add(new Proxy(Proxy.Type.HTTP,
new InetSocketAddress("localhost", 0))); new InetSocketAddress("localhost", 0)));
@ -75,6 +77,7 @@ public class BadProxySelector {
@Override @Override
public List<Proxy> select(URI uri) { public List<Proxy> select(URI uri) {
System.out.println(this.getClass().getSimpleName() + " called for " + uri);
List<Proxy> proxies = new ArrayList<>(); List<Proxy> proxies = new ArrayList<>();
proxies.add(null); proxies.add(null);
proxies.add(new Proxy(Proxy.Type.HTTP, proxies.add(new Proxy(Proxy.Type.HTTP,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -51,7 +51,7 @@ public class SocksProxyVersion implements Runnable {
} }
public SocksProxyVersion() throws Exception { public SocksProxyVersion() throws Exception {
ss = new ServerSocket(0); ss = new ServerSocket(0, 0, InetAddress.getLocalHost());
int port = ss.getLocalPort(); int port = ss.getLocalPort();
Thread serverThread = new Thread(this); Thread serverThread = new Thread(this);
serverThread.start(); serverThread.start();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@ import java.net.URLPermission;
* @library /test/lib * @library /test/lib
* @build jdk.test.lib.net.SimpleSSLContext * @build jdk.test.lib.net.SimpleSSLContext
* @run main/othervm URLTest * @run main/othervm URLTest
* @run main/othervm -Djava.net.preferIPv6Addresses=true URLTest
* @summary check URLPermission with Http(s)URLConnection * @summary check URLPermission with Http(s)URLConnection
*/ */
@ -77,14 +78,14 @@ public class URLTest {
if (sm != null) { if (sm != null) {
expectException = true; expectException = true;
Policy.setPolicy(new CustomPolicy( Policy.setPolicy(new CustomPolicy(
new URLPermission("http://127.0.0.1:"+httpPort+"/foo.html", "GET:X-Foo,Z-Bar"), new URLPermission("http://" + httpAuth + "/foo.html", "GET:X-Foo,Z-Bar"),
new URLPermission("https://127.0.0.1:"+httpsPort+"/foo.html", "POST:X-Fob,T-Bar"))); new URLPermission("https://" + httpsAuth + "/foo.html", "POST:X-Fob,T-Bar")));
} }
String url1 = "http://127.0.0.1:"+httpPort+"/foo.html"; String url1 = "http://" + httpAuth + "/foo.html";
String url2 = "https://127.0.0.1:"+httpsPort+"/foo.html"; String url2 = "https://" + httpsAuth + "/foo.html";
String url3 = "http://127.0.0.1:"+httpPort+"/bar.html"; String url3 = "http://" + httpAuth + "/bar.html";
String url4 = "https://127.0.0.1:"+httpsPort+"/bar.html"; String url4 = "https://" + httpsAuth + "/bar.html";
// simple positive test. Should succeed // simple positive test. Should succeed
test(url1, "GET", "X-Foo"); test(url1, "GET", "X-Foo");
@ -108,14 +109,14 @@ public class URLTest {
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
Policy.setPolicy(new CustomPolicy( Policy.setPolicy(new CustomPolicy(
new URLPermission("http://127.0.0.1:"+httpPort+"/*", "GET:X-Foo"), new URLPermission("http://" + httpAuth + "/*", "GET:X-Foo"),
new URLPermission("https://127.0.0.1:"+httpsPort+"/*", "POST:X-Fob"))); new URLPermission("https://" + httpsAuth + "/*", "POST:X-Fob")));
} }
String url1 = "http://127.0.0.1:"+httpPort+"/foo.html"; String url1 = "http://" + httpAuth + "/foo.html";
String url2 = "https://127.0.0.1:"+httpsPort+"/foo.html"; String url2 = "https://" + httpsAuth + "/foo.html";
String url3 = "http://127.0.0.1:"+httpPort+"/bar.html"; String url3 = "http://" + httpAuth + "/bar.html";
String url4 = "https://127.0.0.1:"+httpsPort+"/bar.html"; String url4 = "https://" + httpsAuth + "/bar.html";
// simple positive test. Should succeed // simple positive test. Should succeed
test(url1, "GET", "X-Foo"); test(url1, "GET", "X-Foo");
@ -132,14 +133,14 @@ public class URLTest {
if (sm != null) { if (sm != null) {
expectException = true; expectException = true;
Policy.setPolicy(new CustomPolicy( Policy.setPolicy(new CustomPolicy(
new URLPermission("http://127.0.0.1:"+httpPort+"/a/b/-", "DELETE,GET:X-Foo,Y-Foo"), new URLPermission("http://" + httpAuth + "/a/b/-", "DELETE,GET:X-Foo,Y-Foo"),
new URLPermission("https://127.0.0.1:"+httpsPort+"/a/c/-", "POST:*"))); new URLPermission("https://" + httpsAuth + "/a/c/-", "POST:*")));
} }
String url1 = "http://127.0.0.1:"+httpPort+"/foo.html"; String url1 = "http://" + httpAuth + "/foo.html";
String url2 = "https://127.0.0.1:"+httpsPort+"/a/c/d/e/foo.html"; String url2 = "https://" + httpsAuth + "/a/c/d/e/foo.html";
String url3 = "http://127.0.0.1:"+httpPort+"/a/b/c"; String url3 = "http://" + httpAuth + "/a/b/c";
String url4 = "https://127.0.0.1:"+httpsPort+"/a/b/c"; String url4 = "https://" + httpsAuth + "/a/b/c";
test(url1, "GET", "X-Foo", expectException); test(url1, "GET", "X-Foo", expectException);
test(url2, "POST", "X-Zxc"); test(url2, "POST", "X-Zxc");
@ -147,6 +148,16 @@ public class URLTest {
test(url4, "POST", "Y-Foo", expectException); test(url4, "POST", "Y-Foo", expectException);
} }
static String authority(InetSocketAddress address) {
String hostaddr = address.getAddress().getHostAddress();
int port = address.getPort();
if (hostaddr.indexOf(':') > -1) {
return "[" + hostaddr + "]:" + port;
} else {
return hostaddr + ":" + port;
}
}
// Convenience methods to simplify previous explicit test scenarios. // Convenience methods to simplify previous explicit test scenarios.
static void test(String u, String method, String header) throws IOException { static void test(String u, String method, String header) throws IOException {
test(u, method, header, null, false); test(u, method, header, null, false);
@ -175,7 +186,7 @@ public class URLTest {
System.out.println("url=" + u + " method=" + method + System.out.println("url=" + u + " method=" + method +
" header1=" + header1 + " header2=" + header2 + " header1=" + header1 + " header2=" + header2 +
" expectException=" + expectException); " expectException=" + expectException);
HttpURLConnection urlc = (HttpURLConnection)url.openConnection(); HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
if (urlc instanceof HttpsURLConnection) { if (urlc instanceof HttpsURLConnection) {
HttpsURLConnection ssl = (HttpsURLConnection)urlc; HttpsURLConnection ssl = (HttpsURLConnection)urlc;
ssl.setHostnameVerifier((host, sess) -> true); ssl.setHostnameVerifier((host, sess) -> true);
@ -220,11 +231,14 @@ public class URLTest {
static SSLContext ctx; static SSLContext ctx;
static int httpPort; static int httpPort;
static int httpsPort; static int httpsPort;
static String httpAuth;
static String httpsAuth;
static void createServers() throws Exception { static void createServers() throws Exception {
InetSocketAddress any = new InetSocketAddress(0); InetAddress loopback = InetAddress.getLoopbackAddress();
httpServer = HttpServer.create(any, 0); InetSocketAddress address = new InetSocketAddress(loopback, 0);
httpsServer = HttpsServer.create(any, 0); httpServer = HttpServer.create(address, 0);
httpsServer = HttpsServer.create(address, 0);
OkHandler h = new OkHandler(); OkHandler h = new OkHandler();
@ -243,6 +257,8 @@ public class URLTest {
httpPort = httpServer.getAddress().getPort(); httpPort = httpServer.getAddress().getPort();
httpsPort = httpsServer.getAddress().getPort(); httpsPort = httpsServer.getAddress().getPort();
httpAuth = authority(httpServer.getAddress());
httpsAuth = authority(httpsServer.getAddress());
} }
static void shutdown() { static void shutdown() {
@ -265,7 +281,9 @@ public class URLTest {
java.util.Arrays.stream(permissions).forEach(perms::add); java.util.Arrays.stream(permissions).forEach(perms::add);
// needed for the HTTP(S) server // needed for the HTTP(S) server
perms.add(new SocketPermission("localhost:1024-", "listen,resolve,accept")); InetAddress loopback = InetAddress.getLoopbackAddress();
InetSocketAddress serverBound = new InetSocketAddress(loopback,1024);
perms.add(new SocketPermission(authority(serverBound) + "-", "listen,resolve,accept"));
// needed by the test to reset the policy, per testX method // needed by the test to reset the policy, per testX method
perms.add(new SecurityPermission("setPolicy")); perms.add(new SecurityPermission("setPolicy"));
// needed to shutdown the ThreadPoolExecutor ( used by the servers ) // needed to shutdown the ThreadPoolExecutor ( used by the servers )

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,7 +24,10 @@
/** /**
* @test * @test
* @bug 5054016 * @bug 5054016
* @library /test/lib
* @summary get the failure immediately when writing individual chunks over socket fail * @summary get the failure immediately when writing individual chunks over socket fail
* @run main CheckError
* @run main/othervm -Djava.net.preferIPv6Addresses=true CheckError
*/ */
import java.io.BufferedReader; import java.io.BufferedReader;
@ -33,11 +36,16 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.net.URL; import java.net.URL;
import static java.lang.System.out; import static java.lang.System.out;
import jdk.test.lib.net.URIBuilder;
public class CheckError { public class CheckError {
static int BUFFER_SIZE = 8192; // 8k static int BUFFER_SIZE = 8192; // 8k
@ -51,8 +59,13 @@ public class CheckError {
out.println("Server listening on " + port); out.println("Server listening on " + port);
URL url = new URL("http://localhost:" + port); URL url = URIBuilder.newBuilder()
HttpURLConnection conn = (HttpURLConnection)url.openConnection(); .scheme("http")
.host(server.getAddress())
.port(port)
.toURL();
HttpURLConnection conn = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
conn.setRequestMethod("POST"); conn.setRequestMethod("POST");
conn.setDoOutput(true); conn.setDoOutput(true);
conn.setChunkedStreamingMode(1024); conn.setChunkedStreamingMode(1024);
@ -98,13 +111,19 @@ public class CheckError {
final ServerSocket serverSocket; final ServerSocket serverSocket;
HTTPServer() throws IOException { HTTPServer() throws IOException {
serverSocket = new ServerSocket(0); InetAddress loopback = InetAddress.getLoopbackAddress();
serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress(loopback, 0));
} }
int getPort() { int getPort() {
return serverSocket.getLocalPort(); return serverSocket.getLocalPort();
} }
InetAddress getAddress() {
return serverSocket.getInetAddress();
}
public void run() { public void run() {
try (Socket client = serverSocket.accept()) { try (Socket client = serverSocket.accept()) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -221,6 +221,7 @@ public class TestHttpServer {
listenerKey = schan.register (selector, SelectionKey.OP_ACCEPT); listenerKey = schan.register (selector, SelectionKey.OP_ACCEPT);
} catch (IOException e) { } catch (IOException e) {
System.err.println ("Server could not start: " + e); System.err.println ("Server could not start: " + e);
throw new RuntimeException("Server could not start: " + e, e);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,7 @@
* @modules java.base/sun.net.www * @modules java.base/sun.net.www
* @build TestHttpsServer HttpCallback * @build TestHttpsServer HttpCallback
* @run main/othervm ChunkedOutputStream * @run main/othervm ChunkedOutputStream
* @run main/othervm -Djava.net.preferIPv6Addresses=true ChunkedOutputStream
* *
* SunJSSE does not support dynamic system properties, no way to re-use * SunJSSE does not support dynamic system properties, no way to re-use
* system properties in samevm/agentvm mode. * system properties in samevm/agentvm mode.
@ -54,7 +55,7 @@ public class ChunkedOutputStream implements HttpCallback {
static final String str2 = "Helloworld1234567890abcdefghijklmnopqrstuvwxyz"+ static final String str2 = "Helloworld1234567890abcdefghijklmnopqrstuvwxyz"+
"1234567890"; "1234567890";
public void request (HttpTransaction req) { public void request(HttpTransaction req) {
try { try {
// this is needed (count++ doesn't work), 'cause we // this is needed (count++ doesn't work), 'cause we
// are doing concurrent tests // are doing concurrent tests
@ -80,19 +81,19 @@ public class ChunkedOutputStream implements HttpCallback {
case 1: /* test2 -- closes conn */ case 1: /* test2 -- closes conn */
String reqbody = req.getRequestEntityBody(); String reqbody = req.getRequestEntityBody();
if (!reqbody.equals(str1)) { if (!reqbody.equals(str1)) {
req.sendResponse (500, "Internal server error"); req.sendResponse(500, "Internal server error");
req.orderlyClose(); req.orderlyClose();
} }
String chunk = req.getRequestHeader ("Transfer-encoding"); String chunk = req.getRequestHeader("Transfer-encoding");
if (!"chunked".equals (chunk)) { if (!"chunked".equals(chunk)) {
req.sendResponse (501, "Internal server error"); req.sendResponse(501, "Internal server error");
req.orderlyClose(); req.orderlyClose();
} }
req.setResponseEntityBody (reqbody); req.setResponseEntityBody(reqbody);
if (count == 1) { if (count == 1) {
req.setResponseHeader ("Connection", "close"); req.setResponseHeader("Connection", "close");
} }
req.sendResponse (200, "OK"); req.sendResponse(200, "OK");
if (count == 1) { if (count == 1) {
req.orderlyClose(); req.orderlyClose();
} }
@ -100,35 +101,35 @@ public class ChunkedOutputStream implements HttpCallback {
case 2: /* test 3 */ case 2: /* test 3 */
reqbody = req.getRequestEntityBody(); reqbody = req.getRequestEntityBody();
if (!reqbody.equals(str2)) { if (!reqbody.equals(str2)) {
req.sendResponse (500, "Internal server error"); req.sendResponse(500, "Internal server error");
req.orderlyClose(); req.orderlyClose();
} }
int clen = Integer.parseInt ( int clen = Integer.parseInt (
req.getRequestHeader ("Content-length")); req.getRequestHeader("Content-length"));
if (clen != str2.length()) { if (clen != str2.length()) {
req.sendResponse (501, "Internal server error"); req.sendResponse(501, "Internal server error");
req.orderlyClose(); req.orderlyClose();
} }
req.setResponseEntityBody (reqbody); req.setResponseEntityBody (reqbody);
req.setResponseHeader ("Connection", "close"); req.setResponseHeader("Connection", "close");
req.sendResponse (200, "OK"); req.sendResponse(200, "OK");
req.orderlyClose(); req.orderlyClose();
break; break;
case 3: /* test 6 */ case 3: /* test 6 */
req.setResponseHeader ("Location", "https://foo.bar/"); req.setResponseHeader("Location", "https://foo.bar/");
req.setResponseHeader ("Connection", "close"); req.setResponseHeader("Connection", "close");
req.sendResponse (307, "Temporary Redirect"); req.sendResponse(307, "Temporary Redirect");
req.orderlyClose(); req.orderlyClose();
break; break;
case 4: /* test 7 */ case 4: /* test 7 */
case 5: /* test 8 */ case 5: /* test 8 */
reqbody = req.getRequestEntityBody(); reqbody = req.getRequestEntityBody();
if (reqbody != null && !"".equals (reqbody)) { if (reqbody != null && !"".equals(reqbody)) {
req.sendResponse (501, "Internal server error"); req.sendResponse(501, "Internal server error");
req.orderlyClose(); req.orderlyClose();
} }
req.setResponseHeader ("Connection", "close"); req.setResponseHeader("Connection", "close");
req.sendResponse (200, "OK"); req.sendResponse(200, "OK");
req.orderlyClose(); req.orderlyClose();
break; break;
} }
@ -137,148 +138,148 @@ public class ChunkedOutputStream implements HttpCallback {
} }
} }
static void readAndCompare (InputStream is, String cmp) throws IOException { static void readAndCompare(InputStream is, String cmp) throws IOException {
int c; int c;
byte buf[] = new byte [1024]; byte buf[] = new byte[1024];
int off = 0; int off = 0;
int len = 1024; int len = 1024;
while ((c=is.read(buf, off, len)) != -1) { while ((c=is.read(buf, off, len)) != -1) {
off += c; off += c;
len -= c; len -= c;
} }
String s1 = new String (buf, 0, off, "ISO8859_1"); String s1 = new String(buf, 0, off, "ISO8859_1");
if (!cmp.equals(s1)) { if (!cmp.equals(s1)) {
throw new IOException ("strings not same"); throw new IOException("strings not same");
} }
} }
/* basic chunked test (runs twice) */ /* basic chunked test (runs twice) */
static void test1 (String u) throws Exception { static void test1(String u) throws Exception {
URL url = new URL (u); URL url = new URL(u);
System.out.println ("client opening connection to: " + u); System.out.println("client opening connection to: " + u);
HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
urlc.setChunkedStreamingMode (20); urlc.setChunkedStreamingMode(20);
urlc.setDoOutput(true); urlc.setDoOutput(true);
urlc.setRequestMethod ("POST"); urlc.setRequestMethod("POST");
OutputStream os = urlc.getOutputStream (); OutputStream os = urlc.getOutputStream();
os.write (str1.getBytes()); os.write(str1.getBytes());
os.close(); os.close();
InputStream is = urlc.getInputStream(); InputStream is = urlc.getInputStream();
readAndCompare (is, str1); readAndCompare(is, str1);
is.close(); is.close();
} }
/* basic fixed length test */ /* basic fixed length test */
static void test3 (String u) throws Exception { static void test3(String u) throws Exception {
URL url = new URL (u); URL url = new URL(u);
System.out.println ("client opening connection to: " + u); System.out.println("client opening connection to: " + u);
HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
urlc.setFixedLengthStreamingMode (str2.length()); urlc.setFixedLengthStreamingMode(str2.length());
urlc.setDoOutput(true); urlc.setDoOutput(true);
urlc.setRequestMethod ("POST"); urlc.setRequestMethod("POST");
OutputStream os = urlc.getOutputStream (); OutputStream os = urlc.getOutputStream();
os.write (str2.getBytes()); os.write (str2.getBytes());
os.close(); os.close();
InputStream is = urlc.getInputStream(); InputStream is = urlc.getInputStream();
readAndCompare (is, str2); readAndCompare(is, str2);
is.close(); is.close();
} }
/* write too few bytes */ /* write too few bytes */
static void test4 (String u) throws Exception { static void test4(String u) throws Exception {
URL url = new URL (u); URL url = new URL(u);
System.out.println ("client opening connection to: " + u); System.out.println("client opening connection to: " + u);
HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
urlc.setFixedLengthStreamingMode (str2.length()+1); urlc.setFixedLengthStreamingMode(str2.length()+1);
urlc.setDoOutput(true); urlc.setDoOutput(true);
urlc.setRequestMethod ("POST"); urlc.setRequestMethod("POST");
OutputStream os = urlc.getOutputStream (); OutputStream os = urlc.getOutputStream();
os.write (str2.getBytes()); os.write(str2.getBytes());
try { try {
os.close(); os.close();
throw new Exception ("should have thrown IOException"); throw new Exception("should have thrown IOException");
} catch (IOException e) {} } catch (IOException e) {}
} }
/* write too many bytes */ /* write too many bytes */
static void test5 (String u) throws Exception { static void test5(String u) throws Exception {
URL url = new URL (u); URL url = new URL(u);
System.out.println ("client opening connection to: " + u); System.out.println("client opening connection to: " + u);
HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
urlc.setFixedLengthStreamingMode (str2.length()-1); urlc.setFixedLengthStreamingMode(str2.length()-1);
urlc.setDoOutput(true); urlc.setDoOutput(true);
urlc.setRequestMethod ("POST"); urlc.setRequestMethod("POST");
OutputStream os = urlc.getOutputStream (); OutputStream os = urlc.getOutputStream();
try { try {
os.write (str2.getBytes()); os.write(str2.getBytes());
throw new Exception ("should have thrown IOException"); throw new Exception("should have thrown IOException");
} catch (IOException e) {} } catch (IOException e) {}
} }
/* check for HttpRetryException on redirection */ /* check for HttpRetryException on redirection */
static void test6 (String u) throws Exception { static void test6(String u) throws Exception {
URL url = new URL (u); URL url = new URL(u);
System.out.println ("client opening connection to: " + u); System.out.println("client opening connection to: " + u);
HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
urlc.setChunkedStreamingMode (20); urlc.setChunkedStreamingMode(20);
urlc.setDoOutput(true); urlc.setDoOutput(true);
urlc.setRequestMethod ("POST"); urlc.setRequestMethod("POST");
OutputStream os = urlc.getOutputStream (); OutputStream os = urlc.getOutputStream();
os.write (str1.getBytes()); os.write(str1.getBytes());
os.close(); os.close();
try { try {
InputStream is = urlc.getInputStream(); InputStream is = urlc.getInputStream();
throw new Exception ("should have gotten HttpRetryException"); throw new Exception("should have gotten HttpRetryException");
} catch (HttpRetryException e) { } catch (HttpRetryException e) {
if (e.responseCode() != 307) { if (e.responseCode() != 307) {
throw new Exception ("Wrong response code " + e.responseCode()); throw new Exception("Wrong response code " + e.responseCode());
} }
if (!e.getLocation().equals ("https://foo.bar/")) { if (!e.getLocation().equals("https://foo.bar/")) {
throw new Exception ("Wrong location " + e.getLocation()); throw new Exception("Wrong location " + e.getLocation());
} }
} }
} }
/* next two tests send zero length posts */ /* next two tests send zero length posts */
static void test7 (String u) throws Exception { static void test7(String u) throws Exception {
URL url = new URL (u); URL url = new URL(u);
System.out.println ("client opening connection to: " + u); System.out.println("client opening connection to: " + u);
HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
urlc.setChunkedStreamingMode (20); urlc.setChunkedStreamingMode(20);
urlc.setDoOutput(true); urlc.setDoOutput(true);
urlc.setRequestMethod ("POST"); urlc.setRequestMethod("POST");
OutputStream os = urlc.getOutputStream (); OutputStream os = urlc.getOutputStream();
os.close(); os.close();
int ret = urlc.getResponseCode(); int ret = urlc.getResponseCode();
if (ret != 200) { if (ret != 200) {
throw new Exception ("Expected 200: got " + ret); throw new Exception("Expected 200: got " + ret);
} }
} }
static void test8 (String u) throws Exception { static void test8(String u) throws Exception {
URL url = new URL (u); URL url = new URL(u);
System.out.println ("client opening connection to: " + u); System.out.println("client opening connection to: " + u);
HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
urlc.setFixedLengthStreamingMode (0); urlc.setFixedLengthStreamingMode(0);
urlc.setDoOutput(true); urlc.setDoOutput(true);
urlc.setRequestMethod ("POST"); urlc.setRequestMethod("POST");
OutputStream os = urlc.getOutputStream (); OutputStream os = urlc.getOutputStream();
os.close(); os.close();
int ret = urlc.getResponseCode(); int ret = urlc.getResponseCode();
if (ret != 200) { if (ret != 200) {
throw new Exception ("Expected 200: got " + ret); throw new Exception("Expected 200: got " + ret);
} }
} }
static TestHttpsServer server; static TestHttpsServer server;
public static void main (String[] args) throws Exception { public static void main(String[] args) throws Exception {
// setup properties to do ssl // setup properties to do ssl
String keyFilename = String keyFilename =
System.getProperty("test.src", "./") + "/" + pathToStores + System.getProperty("test.src", "./") + "/" + pathToStores +
@ -287,6 +288,8 @@ public class ChunkedOutputStream implements HttpCallback {
System.getProperty("test.src", "./") + "/" + pathToStores + System.getProperty("test.src", "./") + "/" + pathToStores +
"/" + trustStoreFile; "/" + trustStoreFile;
InetAddress loopback = InetAddress.getLoopbackAddress();
HostnameVerifier reservedHV = HostnameVerifier reservedHV =
HttpsURLConnection.getDefaultHostnameVerifier(); HttpsURLConnection.getDefaultHostnameVerifier();
try { try {
@ -298,17 +301,17 @@ public class ChunkedOutputStream implements HttpCallback {
try { try {
server = new TestHttpsServer( server = new TestHttpsServer(
new ChunkedOutputStream(), 1, 10, 0); new ChunkedOutputStream(), 1, 10, loopback, 0);
System.out.println ("Server started: listening on port: " + server.getLocalPort()); System.out.println("Server started: listening on: " + server.getAuthority());
// the test server doesn't support keep-alive yet // the test server doesn't support keep-alive yet
// test1("http://localhost:"+server.getLocalPort()+"/d0"); // test1("http://" + server.getAuthority() + "/d0");
test1("https://localhost:"+server.getLocalPort()+"/d01"); test1("https://" + server.getAuthority() + "/d01");
test3("https://localhost:"+server.getLocalPort()+"/d3"); test3("https://" + server.getAuthority() + "/d3");
test4("https://localhost:"+server.getLocalPort()+"/d4"); test4("https://" + server.getAuthority() + "/d4");
test5("https://localhost:"+server.getLocalPort()+"/d5"); test5("https://" + server.getAuthority() + "/d5");
test6("https://localhost:"+server.getLocalPort()+"/d6"); test6("https://" + server.getAuthority() + "/d6");
test7("https://localhost:"+server.getLocalPort()+"/d7"); test7("https://" + server.getAuthority() + "/d7");
test8("https://localhost:"+server.getLocalPort()+"/d8"); test8("https://" + server.getAuthority() + "/d8");
} catch (Exception e) { } catch (Exception e) {
if (server != null) { if (server != null) {
server.terminate(); server.terminate();
@ -327,8 +330,8 @@ public class ChunkedOutputStream implements HttpCallback {
} }
} }
public static void except (String s) { public static void except(String s) {
server.terminate(); server.terminate();
throw new RuntimeException (s); throw new RuntimeException(s);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -70,8 +70,8 @@ public class TestHttpsServer {
* incoming request * incoming request
*/ */
public TestHttpsServer (HttpCallback cb) throws IOException { public TestHttpsServer(HttpCallback cb) throws IOException {
this (cb, 1, 10, 0); this(cb, 1, 10, 0);
} }
/** /**
@ -86,9 +86,9 @@ public class TestHttpsServer {
* handle per thread * handle per thread
*/ */
public TestHttpsServer (HttpCallback cb, int threads, int cperthread) public TestHttpsServer(HttpCallback cb, int threads, int cperthread)
throws IOException { throws IOException {
this (cb, threads, cperthread, 0); this(cb, threads, cperthread, 0);
} }
/** /**
@ -106,12 +106,34 @@ public class TestHttpsServer {
* @param port the port number to bind the server to. <code>Zero</code> * @param port the port number to bind the server to. <code>Zero</code>
* means choose any free port. * means choose any free port.
*/ */
public TestHttpsServer(HttpCallback cb, int threads, int cperthread, int port)
public TestHttpsServer (HttpCallback cb, int threads, int cperthread, int port)
throws IOException { throws IOException {
schan = ServerSocketChannel.open (); this(cb, threads, cperthread, null, port);
InetSocketAddress addr = new InetSocketAddress (port); }
schan.socket().bind (addr);
/**
* Create a <code>TestHttpsServer<code> instance with the specified number
* of threads and maximum number of connections per thread and running on
* the specified port. The specified number of threads are created to
* handle incoming requests, and each thread is allowed
* to handle a number of simultaneous TCP connections.
* @param cb the callback object which is invoked to handle
* each incoming request
* @param threads the number of threads to create to handle
* requests in parallel
* @param cperthread the number of simultaneous TCP connections
* to handle per thread
* @param address the InetAddress to bind to. {@code Null} means the
* wildcard address.
* @param port the port number to bind the server to. {@code Zero}
* means choose any free port.
*/
public TestHttpsServer(HttpCallback cb, int threads, int cperthread, InetAddress address, int port)
throws IOException {
schan = ServerSocketChannel.open();
InetSocketAddress addr = new InetSocketAddress(address, port);
schan.socket().bind(addr);
this.threads = threads; this.threads = threads;
this.cb = cb; this.cb = cb;
this.cperthread = cperthread; this.cperthread = cperthread;
@ -135,9 +157,9 @@ public class TestHttpsServer {
sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
servers = new Server [threads]; servers = new Server[threads];
for (int i=0; i<threads; i++) { for (int i=0; i<threads; i++) {
servers[i] = new Server (cb, schan, cperthread); servers[i] = new Server(cb, schan, cperthread);
servers[i].start(); servers[i].start();
} }
} catch (Exception ex) { } catch (Exception ex) {
@ -150,7 +172,7 @@ public class TestHttpsServer {
* all channels in that thread waiting to be closed are forceably closed. * all channels in that thread waiting to be closed are forceably closed.
*/ */
public void terminate () { public void terminate() {
for (int i=0; i<threads; i++) { for (int i=0; i<threads; i++) {
servers[i].terminate (); servers[i].terminate ();
} }
@ -165,6 +187,14 @@ public class TestHttpsServer {
return schan.socket().getLocalPort (); return schan.socket().getLocalPort ();
} }
public String getAuthority() {
InetAddress address = schan.socket().getInetAddress();
String hostaddr = address.getHostAddress();
if (address.isAnyLocalAddress()) hostaddr = "localhost";
if (hostaddr.indexOf(':') > -1) hostaddr = "[" + hostaddr + "]";
return hostaddr + ":" + getLocalPort();
}
static class Server extends Thread { static class Server extends Thread {
ServerSocketChannel schan; ServerSocketChannel schan;
@ -178,65 +208,65 @@ public class TestHttpsServer {
ClosedChannelList clist; ClosedChannelList clist;
boolean shutdown; boolean shutdown;
Server (HttpCallback cb, ServerSocketChannel schan, int maxconn) { Server(HttpCallback cb, ServerSocketChannel schan, int maxconn) {
this.schan = schan; this.schan = schan;
this.maxconn = maxconn; this.maxconn = maxconn;
this.cb = cb; this.cb = cb;
nconn = 0; nconn = 0;
consumeBuffer = ByteBuffer.allocate (512); consumeBuffer = ByteBuffer.allocate(512);
clist = new ClosedChannelList (); clist = new ClosedChannelList();
try { try {
selector = Selector.open (); selector = Selector.open();
schan.configureBlocking (false); schan.configureBlocking(false);
listenerKey = schan.register (selector, SelectionKey.OP_ACCEPT); listenerKey = schan.register(selector, SelectionKey.OP_ACCEPT);
} catch (IOException e) { } catch (IOException e) {
System.err.println ("Server could not start: " + e); System.err.println("Server could not start: " + e);
} }
} }
/* Stop the thread as soon as possible */ /* Stop the thread as soon as possible */
public synchronized void terminate () { public synchronized void terminate() {
shutdown = true; shutdown = true;
} }
public void run () { public void run() {
try { try {
while (true) { while (true) {
selector.select (1000); selector.select(1000);
Set selected = selector.selectedKeys(); Set selected = selector.selectedKeys();
Iterator iter = selected.iterator(); Iterator iter = selected.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
key = (SelectionKey)iter.next(); key = (SelectionKey)iter.next();
if (key.equals (listenerKey)) { if (key.equals (listenerKey)) {
SocketChannel sock = schan.accept (); SocketChannel sock = schan.accept();
if (sock == null) { if (sock == null) {
/* false notification */ /* false notification */
iter.remove(); iter.remove();
continue; continue;
} }
sock.configureBlocking (true); sock.configureBlocking(true);
SSLEngine sslEng = sslCtx.createSSLEngine(); SSLEngine sslEng = sslCtx.createSSLEngine();
sslEng.setUseClientMode(false); sslEng.setUseClientMode(false);
new ServerWorker(cb, sock, sslEng).start(); new ServerWorker(cb, sock, sslEng).start();
nconn ++; nconn ++;
if (nconn == maxconn) { if (nconn == maxconn) {
/* deregister */ /* deregister */
listenerKey.cancel (); listenerKey.cancel();
listenerKey = null; listenerKey = null;
} }
} else { } else {
if (key.isReadable()) { if (key.isReadable()) {
boolean closed = false; boolean closed = false;
SocketChannel chan = (SocketChannel) key.channel(); SocketChannel chan = (SocketChannel)key.channel();
if (key.attachment() != null) { if (key.attachment() != null) {
closed = consume (chan); closed = consume(chan);
} }
if (closed) { if (closed) {
chan.close (); chan.close();
key.cancel (); key.cancel();
if (nconn == maxconn) { if (nconn == maxconn) {
listenerKey = schan.register (selector, SelectionKey.OP_ACCEPT); listenerKey = schan.register(selector, SelectionKey.OP_ACCEPT);
} }
nconn --; nconn --;
} }
@ -248,13 +278,13 @@ public class TestHttpsServer {
synchronized (this) { synchronized (this) {
if (shutdown) { if (shutdown) {
clist.terminate (); clist.terminate();
return; return;
} }
} }
} }
} catch (IOException e) { } catch (IOException e) {
System.out.println ("Server exception: " + e); System.out.println("Server exception: " + e);
// TODO finish // TODO finish
} }
} }
@ -262,10 +292,10 @@ public class TestHttpsServer {
/* read all the data off the channel without looking at it /* read all the data off the channel without looking at it
* return true if connection closed * return true if connection closed
*/ */
boolean consume (SocketChannel chan) { boolean consume(SocketChannel chan) {
try { try {
consumeBuffer.clear (); consumeBuffer.clear();
int c = chan.read (consumeBuffer); int c = chan.read(consumeBuffer);
if (c == -1) if (c == -1)
return true; return true;
} catch (IOException e) { } catch (IOException e) {
@ -298,7 +328,7 @@ public class TestHttpsServer {
*/ */
private int appBBSize; private int appBBSize;
ServerWorker (HttpCallback cb, SocketChannel schan, SSLEngine sslEng) { ServerWorker(HttpCallback cb, SocketChannel schan, SSLEngine sslEng) {
this.sslEng = sslEng; this.sslEng = sslEng;
this.schan = schan; this.schan = schan;
this.cb = cb; this.cb = cb;
@ -431,21 +461,21 @@ needIO:
/* return true if the connection is closed, false otherwise */ /* return true if the connection is closed, false otherwise */
private boolean read (SocketChannel chan, SSLEngine sslEng) { private boolean read(SocketChannel chan, SSLEngine sslEng) {
HttpTransaction msg; HttpTransaction msg;
boolean res; boolean res;
try { try {
InputStream is = new BufferedInputStream (new NioInputStream (chan, sslEng, inNetBB, inAppBB)); InputStream is = new BufferedInputStream(new NioInputStream(chan, sslEng, inNetBB, inAppBB));
String requestline = readLine (is); String requestline = readLine(is);
MessageHeader mhead = new MessageHeader (is); MessageHeader mhead = new MessageHeader(is);
String clen = mhead.findValue ("Content-Length"); String clen = mhead.findValue("Content-Length");
String trferenc = mhead.findValue ("Transfer-Encoding"); String trferenc = mhead.findValue("Transfer-Encoding");
String data = null; String data = null;
if (trferenc != null && trferenc.equals ("chunked")) if (trferenc != null && trferenc.equals("chunked"))
data = new String (readChunkedData (is)); data = new String(readChunkedData(is));
else if (clen != null) else if (clen != null)
data = new String (readNormalData (is, Integer.parseInt (clen))); data = new String(readNormalData(is, Integer.parseInt(clen)));
String[] req = requestline.split (" "); String[] req = requestline.split(" ");
if (req.length < 2) { if (req.length < 2) {
/* invalid request line */ /* invalid request line */
return false; return false;
@ -453,13 +483,13 @@ needIO:
String cmd = req[0]; String cmd = req[0];
URI uri = null; URI uri = null;
try { try {
uri = new URI (req[1]); uri = new URI(req[1]);
msg = new HttpTransaction (this, cmd, uri, mhead, data, null, chan); msg = new HttpTransaction(this, cmd, uri, mhead, data, null, chan);
cb.request (msg); cb.request(msg);
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
System.err.println ("Invalid URI: " + e); System.err.println ("Invalid URI: " + e);
msg = new HttpTransaction (this, cmd, null, null, null, null, chan); msg = new HttpTransaction(this, cmd, null, null, null, null, chan);
msg.sendResponse (501, "Whatever"); msg.sendResponse(501, "Whatever");
} }
res = false; res = false;
} catch (IOException e) { } catch (IOException e) {
@ -468,8 +498,8 @@ needIO:
return res; return res;
} }
byte[] readNormalData (InputStream is, int len) throws IOException { byte[] readNormalData(InputStream is, int len) throws IOException {
byte [] buf = new byte [len]; byte[] buf = new byte[len];
int c, off=0, remain=len; int c, off=0, remain=len;
while (remain > 0 && ((c=is.read (buf, off, remain))>0)) { while (remain > 0 && ((c=is.read (buf, off, remain))>0)) {
remain -= c; remain -= c;
@ -489,31 +519,31 @@ needIO:
} }
} }
byte[] readChunkedData (InputStream is) throws IOException { byte[] readChunkedData(InputStream is) throws IOException {
LinkedList l = new LinkedList (); LinkedList l = new LinkedList();
int total = 0; int total = 0;
for (int len=readChunkLen(is); len!=0; len=readChunkLen(is)) { for (int len=readChunkLen(is); len!=0; len=readChunkLen(is)) {
l.add (readNormalData(is, len)); l.add(readNormalData(is, len));
total += len; total += len;
readCRLF(is); // CRLF at end of chunk readCRLF(is); // CRLF at end of chunk
} }
readCRLF(is); // CRLF at end of Chunked Stream. readCRLF(is); // CRLF at end of Chunked Stream.
byte[] buf = new byte [total]; byte[] buf = new byte[total];
Iterator i = l.iterator(); Iterator i = l.iterator();
int x = 0; int x = 0;
while (i.hasNext()) { while (i.hasNext()) {
byte[] b = (byte[])i.next(); byte[] b = (byte[])i.next();
System.arraycopy (b, 0, buf, x, b.length); System.arraycopy(b, 0, buf, x, b.length);
x += b.length; x += b.length;
} }
return buf; return buf;
} }
private int readChunkLen (InputStream is) throws IOException { private int readChunkLen(InputStream is) throws IOException {
int c, len=0; int c, len=0;
boolean done=false, readCR=false; boolean done=false, readCR=false;
while (!done) { while (!done) {
c = is.read (); c = is.read();
if (c == '\n' && readCR) { if (c == '\n' && readCR) {
done = true; done = true;
} else { } else {
@ -535,13 +565,13 @@ needIO:
return len; return len;
} }
private String readLine (InputStream is) throws IOException { private String readLine(InputStream is) throws IOException {
boolean done=false, readCR=false; boolean done=false, readCR=false;
byte[] b = new byte [512]; byte[] b = new byte[512];
int c, l = 0; int c, l = 0;
while (!done) { while (!done) {
c = is.read (); c = is.read();
if (c == '\n' && readCR) { if (c == '\n' && readCR) {
done = true; done = true;
} else { } else {
@ -552,7 +582,7 @@ needIO:
} }
} }
} }
return new String (b); return new String(b);
} }
/** close the channel associated with the current key by: /** close the channel associated with the current key by:
@ -561,13 +591,13 @@ needIO:
* 3. After a period, close the socket * 3. After a period, close the socket
*/ */
synchronized void orderlyCloseChannel (SocketChannel ch) throws IOException { synchronized void orderlyCloseChannel(SocketChannel ch) throws IOException {
ch.socket().shutdownOutput(); ch.socket().shutdownOutput();
} }
synchronized void abortiveCloseChannel (SocketChannel ch) throws IOException { synchronized void abortiveCloseChannel(SocketChannel ch) throws IOException {
Socket s = ch.socket (); Socket s = ch.socket();
s.setSoLinger (true, 0); s.setSoLinger(true, 0);
ch.close(); ch.close();
} }
} }
@ -592,27 +622,27 @@ needIO:
boolean reset; boolean reset;
int readlimit; int readlimit;
public NioInputStream (SocketChannel chan, SSLEngine sslEng, ByteBuffer inNetBB, ByteBuffer inAppBB) throws IOException { public NioInputStream(SocketChannel chan, SSLEngine sslEng, ByteBuffer inNetBB, ByteBuffer inAppBB) throws IOException {
this.sslEng = sslEng; this.sslEng = sslEng;
this.channel = chan; this.channel = chan;
selector = Selector.open(); selector = Selector.open();
this.inNetBB = inNetBB; this.inNetBB = inNetBB;
this.inAppBB = inAppBB; this.inAppBB = inAppBB;
key = chan.register (selector, SelectionKey.OP_READ); key = chan.register(selector, SelectionKey.OP_READ);
available = 0; available = 0;
one = new byte[1]; one = new byte[1];
closed = marked = reset = false; closed = marked = reset = false;
} }
public synchronized int read (byte[] b) throws IOException { public synchronized int read(byte[] b) throws IOException {
return read (b, 0, b.length); return read(b, 0, b.length);
} }
public synchronized int read () throws IOException { public synchronized int read() throws IOException {
return read (one, 0, 1); return read(one, 0, 1);
} }
public synchronized int read (byte[] b, int off, int srclen) throws IOException { public synchronized int read(byte[] b, int off, int srclen) throws IOException {
int canreturn, willreturn; int canreturn, willreturn;
@ -620,8 +650,8 @@ needIO:
return -1; return -1;
if (reset) { /* satisfy from markBuf */ if (reset) { /* satisfy from markBuf */
canreturn = markBuf.remaining (); canreturn = markBuf.remaining();
willreturn = canreturn>srclen ? srclen : canreturn; willreturn = canreturn > srclen ? srclen : canreturn;
markBuf.get(b, off, willreturn); markBuf.get(b, off, willreturn);
if (canreturn == willreturn) { if (canreturn == willreturn) {
reset = false; reset = false;
@ -629,16 +659,16 @@ needIO:
} else { /* satisfy from channel */ } else { /* satisfy from channel */
canreturn = available(); canreturn = available();
if (canreturn == 0) { if (canreturn == 0) {
block (); block();
canreturn = available(); canreturn = available();
} }
willreturn = canreturn>srclen ? srclen : canreturn; willreturn = canreturn > srclen ? srclen : canreturn;
inAppBB.get(b, off, willreturn); inAppBB.get(b, off, willreturn);
available -= willreturn; available -= willreturn;
if (marked) { /* copy into markBuf */ if (marked) { /* copy into markBuf */
try { try {
markBuf.put (b, off, willreturn); markBuf.put(b, off, willreturn);
} catch (BufferOverflowException e) { } catch (BufferOverflowException e) {
marked = false; marked = false;
} }
@ -647,9 +677,9 @@ needIO:
return willreturn; return willreturn;
} }
public synchronized int available () throws IOException { public synchronized int available() throws IOException {
if (closed) if (closed)
throw new IOException ("Stream is closed"); throw new IOException("Stream is closed");
if (reset) if (reset)
return markBuf.remaining(); return markBuf.remaining();
@ -657,8 +687,8 @@ needIO:
if (available > 0) if (available > 0)
return available; return available;
inAppBB.clear (); inAppBB.clear();
int bytes = channel.read (inNetBB); int bytes = channel.read(inNetBB);
int needed = sslEng.getSession().getApplicationBufferSize(); int needed = sslEng.getSession().getApplicationBufferSize();
if (needed > inAppBB.remaining()) { if (needed > inAppBB.remaining()) {
@ -672,45 +702,45 @@ needIO:
if (available > 0) if (available > 0)
inAppBB.flip(); inAppBB.flip();
else if (available == -1) else if (available == -1)
throw new IOException ("Stream is closed"); throw new IOException("Stream is closed");
return available; return available;
} }
/** /**
* block() only called when available==0 and buf is empty * block() only called when available==0 and buf is empty
*/ */
private synchronized void block () throws IOException { private synchronized void block() throws IOException {
//assert available == 0; //assert available == 0;
int n = selector.select (); int n = selector.select();
//assert n == 1; //assert n == 1;
selector.selectedKeys().clear(); selector.selectedKeys().clear();
available (); available();
} }
public void close () throws IOException { public void close() throws IOException {
if (closed) if (closed)
return; return;
channel.close (); channel.close();
closed = true; closed = true;
} }
public synchronized void mark (int readlimit) { public synchronized void mark(int readlimit) {
if (closed) if (closed)
return; return;
this.readlimit = readlimit; this.readlimit = readlimit;
markBuf = ByteBuffer.allocate (readlimit); markBuf = ByteBuffer.allocate(readlimit);
marked = true; marked = true;
reset = false; reset = false;
} }
public synchronized void reset () throws IOException { public synchronized void reset() throws IOException {
if (closed ) if (closed )
return; return;
if (!marked) if (!marked)
throw new IOException ("Stream not marked"); throw new IOException("Stream not marked");
marked = false; marked = false;
reset = true; reset = true;
markBuf.flip (); markBuf.flip();
} }
} }
@ -724,33 +754,33 @@ needIO:
boolean closed; boolean closed;
byte[] one; byte[] one;
public NioOutputStream (SocketChannel channel, SSLEngine sslEng, ByteBuffer outNetBB, ByteBuffer outAppBB) throws IOException { public NioOutputStream(SocketChannel channel, SSLEngine sslEng, ByteBuffer outNetBB, ByteBuffer outAppBB) throws IOException {
this.sslEng = sslEng; this.sslEng = sslEng;
this.channel = channel; this.channel = channel;
this.outNetBB = outNetBB; this.outNetBB = outNetBB;
this.outAppBB = outAppBB; this.outAppBB = outAppBB;
selector = Selector.open (); selector = Selector.open();
key = channel.register (selector, SelectionKey.OP_WRITE); key = channel.register(selector, SelectionKey.OP_WRITE);
closed = false; closed = false;
one = new byte [1]; one = new byte[1];
} }
public synchronized void write (int b) throws IOException { public synchronized void write(int b) throws IOException {
one[0] = (byte)b; one[0] = (byte)b;
write (one, 0, 1); write(one, 0, 1);
} }
public synchronized void write (byte[] b) throws IOException { public synchronized void write(byte[] b) throws IOException {
write (b, 0, b.length); write(b, 0, b.length);
} }
public synchronized void write (byte[] b, int off, int len) throws IOException { public synchronized void write(byte[] b, int off, int len) throws IOException {
if (closed) if (closed)
throw new IOException ("stream is closed"); throw new IOException("stream is closed");
outAppBB = ByteBuffer.allocate (len); outAppBB = ByteBuffer.allocate(len);
outAppBB.put (b, off, len); outAppBB.put(b, off, len);
outAppBB.flip (); outAppBB.flip();
int n; int n;
outNetBB.clear(); outNetBB.clear();
int needed = sslEng.getSession().getPacketBufferSize(); int needed = sslEng.getSession().getPacketBufferSize();
@ -764,15 +794,15 @@ needIO:
newLen -= n; newLen -= n;
if (newLen == 0) if (newLen == 0)
return; return;
selector.select (); selector.select();
selector.selectedKeys().clear (); selector.selectedKeys().clear();
} }
} }
public void close () throws IOException { public void close() throws IOException {
if (closed) if (closed)
return; return;
channel.close (); channel.close();
closed = true; closed = true;
} }
} }
@ -802,18 +832,18 @@ needIO:
*/ */
private static class IValue { private static class IValue {
int v; int v;
IValue (int i) { IValue(int i) {
v =i; v =i;
} }
} }
private static BValue getCond (String condition) { private static BValue getCond(String condition) {
synchronized (conditions) { synchronized (conditions) {
BValue cond = (BValue) conditions.get (condition); BValue cond = (BValue) conditions.get(condition);
if (cond == null) { if (cond == null) {
cond = new BValue(); cond = new BValue();
conditions.put (condition, cond); conditions.put(condition, cond);
} }
return cond; return cond;
} }
@ -827,8 +857,8 @@ needIO:
* first. * first.
*/ */
public static void setCondition (String condition) { public static void setCondition(String condition) {
BValue cond = getCond (condition); BValue cond = getCond(condition);
synchronized (cond) { synchronized (cond) {
if (cond.v) { if (cond.v) {
return; return;
@ -846,8 +876,8 @@ needIO:
* immediately without blocking. * immediately without blocking.
*/ */
public static void waitForCondition (String condition) { public static void waitForCondition(String condition) {
BValue cond = getCond (condition); BValue cond = getCond(condition);
synchronized (cond) { synchronized (cond) {
if (!cond.v) { if (!cond.v) {
try { try {
@ -872,7 +902,7 @@ needIO:
* will be a hang. * will be a hang.
*/ */
public static void rendezvous (String condition, int N) { public static void rendezvous(String condition, int N) {
BValue cond; BValue cond;
IValue iv; IValue iv;
String name = "RV_"+condition; String name = "RV_"+condition;
@ -880,30 +910,30 @@ needIO:
/* get the condition */ /* get the condition */
synchronized (conditions) { synchronized (conditions) {
cond = (BValue)conditions.get (name); cond = (BValue)conditions.get(name);
if (cond == null) { if (cond == null) {
/* we are first caller */ /* we are first caller */
if (N < 2) { if (N < 2) {
throw new RuntimeException ("rendezvous must be called with N >= 2"); throw new RuntimeException("rendezvous must be called with N >= 2");
} }
cond = new BValue (); cond = new BValue();
conditions.put (name, cond); conditions.put(name, cond);
iv = new IValue (N-1); iv = new IValue(N-1);
rv.put (name, iv); rv.put(name, iv);
} else { } else {
/* already initialised, just decrement the counter */ /* already initialised, just decrement the counter */
iv = (IValue) rv.get (name); iv = (IValue) rv.get(name);
iv.v --; iv.v--;
} }
} }
if (iv.v > 0) { if (iv.v > 0) {
waitForCondition (name); waitForCondition(name);
} else { } else {
setCondition (name); setCondition(name);
synchronized (conditions) { synchronized (conditions) {
clearCondition (name); clearCondition(name);
rv.remove (name); rv.remove(name);
} }
} }
} }
@ -919,13 +949,13 @@ needIO:
public static void clearCondition(String condition) { public static void clearCondition(String condition) {
BValue cond; BValue cond;
synchronized (conditions) { synchronized (conditions) {
cond = (BValue) conditions.get (condition); cond = (BValue) conditions.get(condition);
if (cond == null) { if (cond == null) {
return; return;
} }
synchronized (cond) { synchronized (cond) {
if (cond.v) { if (cond.v) {
conditions.remove (condition); conditions.remove(condition);
} }
} }
} }