Skip to content

Commit 6b2e444

Browse files
committed
8223714: HTTPSetAuthenticatorTest could be made more resilient
HTTPTestServer (in the test infrastructure) will no longer stop accepting requests if a previous request processing failed Reviewed-by: dfuchs
1 parent 47e0055 commit 6b2e444

File tree

1 file changed

+115
-68
lines changed

1 file changed

+115
-68
lines changed

test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestServer.java

Lines changed: 115 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,8 @@ static class HttpsProxyTunnel extends HTTPTestServer
980980
implements Runnable {
981981

982982
final ServerSocket ss;
983+
private volatile boolean stop;
984+
983985
public HttpsProxyTunnel(HttpServer server, HTTPTestServer target,
984986
HttpHandler delegate)
985987
throws IOException {
@@ -998,9 +1000,10 @@ final void start() throws IOException {
9981000

9991001
@Override
10001002
public void stop() {
1001-
super.stop();
1002-
try {
1003-
ss.close();
1003+
try (var toClose = ss) {
1004+
stop = true;
1005+
System.out.println("Server " + ss + " stop requested");
1006+
super.stop();
10041007
} catch (IOException ex) {
10051008
if (DEBUG) ex.printStackTrace(System.out);
10061009
}
@@ -1050,6 +1053,9 @@ String readLine(InputStream r) throws IOException {
10501053
if (c == '\n') break;
10511054
b.appendCodePoint(c);
10521055
}
1056+
if (b.length() == 0) {
1057+
return "";
1058+
}
10531059
if (b.codePointAt(b.length() -1) == '\r') {
10541060
b.delete(b.length() -1, b.length());
10551061
}
@@ -1059,80 +1065,121 @@ String readLine(InputStream r) throws IOException {
10591065
@Override
10601066
public void run() {
10611067
Socket clientConnection = null;
1062-
try {
1063-
while (true) {
1064-
System.out.println("Tunnel: Waiting for client at: " + ss);
1065-
Socket previous = clientConnection;
1068+
while (!stop) {
1069+
System.out.println("Tunnel: Waiting for client at: " + ss);
1070+
final Socket previous = clientConnection;
1071+
try {
1072+
clientConnection = ss.accept();
1073+
} catch (IOException io) {
10661074
try {
1067-
clientConnection = ss.accept();
1068-
} catch (IOException io) {
1069-
if (DEBUG) io.printStackTrace(System.out);
1070-
break;
1071-
} finally {
1072-
// close the previous connection
1073-
if (previous != null) previous.close();
1075+
ss.close();
1076+
} catch (IOException ex) {
1077+
if (DEBUG) {
1078+
ex.printStackTrace(System.out);
1079+
}
10741080
}
1075-
System.out.println("Tunnel: Client accepted");
1076-
Socket targetConnection = null;
1077-
InputStream ccis = clientConnection.getInputStream();
1078-
OutputStream ccos = clientConnection.getOutputStream();
1079-
Writer w = new OutputStreamWriter(
1080-
clientConnection.getOutputStream(), "UTF-8");
1081-
PrintWriter pw = new PrintWriter(w);
1082-
System.out.println("Tunnel: Reading request line");
1083-
String requestLine = readLine(ccis);
1084-
System.out.println("Tunnel: Request line: " + requestLine);
1085-
if (requestLine.startsWith("CONNECT ")) {
1086-
// We should probably check that the next word following
1087-
// CONNECT is the host:port of our HTTPS serverImpl.
1088-
// Some improvement for a followup!
1089-
1090-
// Read all headers until we find the empty line that
1091-
// signals the end of all headers.
1092-
while(!requestLine.equals("")) {
1093-
System.out.println("Tunnel: Reading header: "
1094-
+ (requestLine = readLine(ccis)));
1081+
// log the reason that caused the server to stop accepting connections
1082+
if (!stop) {
1083+
System.err.println("Server will stop accepting connections due to an exception:");
1084+
io.printStackTrace();
1085+
}
1086+
break;
1087+
} finally {
1088+
// close the previous connection
1089+
if (previous != null) {
1090+
try {
1091+
previous.close();
1092+
} catch (IOException e) {
1093+
// ignore
1094+
if (DEBUG) {
1095+
System.out.println("Ignoring exception that happened while closing " +
1096+
"an older connection:");
1097+
e.printStackTrace(System.out);
1098+
}
10951099
}
1096-
1097-
targetConnection = new Socket(
1098-
serverImpl.getAddress().getAddress(),
1099-
serverImpl.getAddress().getPort());
1100-
1101-
// Then send the 200 OK response to the client
1102-
System.out.println("Tunnel: Sending "
1103-
+ "HTTP/1.1 200 OK\r\n\r\n");
1104-
pw.print("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
1105-
pw.flush();
1106-
} else {
1107-
// This should not happen. If it does let our serverImpl
1108-
// deal with it.
1109-
throw new IOException("Tunnel: Unexpected status line: "
1110-
+ requestLine);
11111100
}
1112-
1113-
// Pipe the input stream of the client connection to the
1114-
// output stream of the target connection and conversely.
1115-
// Now the client and target will just talk to each other.
1116-
System.out.println("Tunnel: Starting tunnel pipes");
1117-
Thread t1 = pipe(ccis, targetConnection.getOutputStream(), '+');
1118-
Thread t2 = pipe(targetConnection.getInputStream(), ccos, '-');
1119-
t1.start();
1120-
t2.start();
1121-
1122-
// We have only 1 client... wait until it has finished before
1123-
// accepting a new connection request.
1124-
t1.join();
1125-
t2.join();
11261101
}
1127-
} catch (Throwable ex) {
1102+
System.out.println("Tunnel: Client accepted");
11281103
try {
1129-
ss.close();
1130-
} catch (IOException ex1) {
1131-
ex.addSuppressed(ex1);
1104+
// We have only 1 client... process the current client
1105+
// request and wait until it has finished before
1106+
// accepting a new connection request.
1107+
processRequestAndWaitToComplete(clientConnection);
1108+
} catch (IOException ioe) {
1109+
// close the client connection
1110+
try {
1111+
clientConnection.close();
1112+
} catch (IOException io) {
1113+
// ignore
1114+
if (DEBUG) {
1115+
System.out.println("Ignoring exception that happened during client" +
1116+
" connection close:");
1117+
io.printStackTrace(System.out);
1118+
}
1119+
} finally {
1120+
clientConnection = null;
1121+
}
1122+
} catch (Throwable t) {
1123+
// don't close the client connection for non-IOExceptions, instead
1124+
// just log it and move on to accept next connection
1125+
if (!stop) {
1126+
t.printStackTrace();
1127+
}
11321128
}
1133-
ex.printStackTrace(System.err);
11341129
}
11351130
}
11361131

1132+
private void processRequestAndWaitToComplete(final Socket clientConnection)
1133+
throws IOException, InterruptedException {
1134+
final Socket targetConnection;
1135+
InputStream ccis = clientConnection.getInputStream();
1136+
OutputStream ccos = clientConnection.getOutputStream();
1137+
Writer w = new OutputStreamWriter(
1138+
clientConnection.getOutputStream(), "UTF-8");
1139+
PrintWriter pw = new PrintWriter(w);
1140+
System.out.println("Tunnel: Reading request line");
1141+
String requestLine = readLine(ccis);
1142+
System.out.println("Tunnel: Request line: " + requestLine);
1143+
if (requestLine.startsWith("CONNECT ")) {
1144+
// We should probably check that the next word following
1145+
// CONNECT is the host:port of our HTTPS serverImpl.
1146+
// Some improvement for a followup!
1147+
1148+
// Read all headers until we find the empty line that
1149+
// signals the end of all headers.
1150+
while(!requestLine.equals("")) {
1151+
System.out.println("Tunnel: Reading header: "
1152+
+ (requestLine = readLine(ccis)));
1153+
}
1154+
1155+
targetConnection = new Socket(
1156+
serverImpl.getAddress().getAddress(),
1157+
serverImpl.getAddress().getPort());
1158+
1159+
// Then send the 200 OK response to the client
1160+
System.out.println("Tunnel: Sending "
1161+
+ "HTTP/1.1 200 OK\r\n\r\n");
1162+
pw.print("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
1163+
pw.flush();
1164+
} else {
1165+
// This should not happen. If it does then consider it a
1166+
// client error and throw an IOException
1167+
System.out.println("Tunnel: Throwing an IOException due to unexpected" +
1168+
" request line: " + requestLine);
1169+
throw new IOException("Client request error - Unexpected request line");
1170+
}
1171+
1172+
// Pipe the input stream of the client connection to the
1173+
// output stream of the target connection and conversely.
1174+
// Now the client and target will just talk to each other.
1175+
System.out.println("Tunnel: Starting tunnel pipes");
1176+
Thread t1 = pipe(ccis, targetConnection.getOutputStream(), '+');
1177+
Thread t2 = pipe(targetConnection.getInputStream(), ccos, '-');
1178+
t1.start();
1179+
t2.start();
1180+
// wait for the request to complete
1181+
t1.join();
1182+
t2.join();
1183+
}
11371184
}
11381185
}

0 commit comments

Comments
 (0)