Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/net/www/http/HttpClient/MultiThreadTest.java
38867 views
/*1* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 463662826* @summary HttpURLConnection duplicates HTTP GET requests when used with multiple threads27*/2829/*30* This tests keep-alive behavior using chunkedinputstreams31* It checks that keep-alive connections are used and also32* that requests are not being repeated (due to errors)33*34* It also checks that the keepalive connections are closed eventually35* because the test will not terminate if the connections36* are not closed by the keep-alive timer.37*/3839import java.net.*;40import java.io.*;4142public class MultiThreadTest extends Thread {4344/*45* Is debugging enabled - start with -d to enable.46*/47static boolean debug = false;4849static Object threadlock = new Object ();50static int threadCounter = 0;5152static Object getLock() { return threadlock; }5354static void debug(String msg) {55if (debug)56System.out.println(msg);57}5859static int reqnum = 0;6061void doRequest(String uri) throws Exception {62URL url = new URL(uri + "?foo="+reqnum);63reqnum ++;64HttpURLConnection http = (HttpURLConnection)url.openConnection();6566InputStream in = http.getInputStream();67byte b[] = new byte[100];68int total = 0;69int n;70do {71n = in.read(b);72if (n > 0) total += n;73} while (n > 0);74debug ("client: read " + total + " bytes");75in.close();76http.disconnect();77}7879String uri;80byte[] b;81int requests;8283MultiThreadTest(int port, int requests) throws Exception {84uri = "http://localhost:" +85port + "/foo.html";8687b = new byte [256];88this.requests = requests;8990synchronized (threadlock) {91threadCounter ++;92}93}9495public void run () {96try {97for (int i=0; i<requests; i++) {98doRequest (uri);99}100} catch (Exception e) {101throw new RuntimeException (e.getMessage());102} finally {103synchronized (threadlock) {104threadCounter --;105if (threadCounter == 0) {106threadlock.notifyAll();107}108}109}110}111112static int threads=5;113114public static void main(String args[]) throws Exception {115116int x = 0, arg_len = args.length;117int requests = 20;118119if (arg_len > 0 && args[0].equals("-d")) {120debug = true;121x = 1;122arg_len --;123}124if (arg_len > 0) {125threads = Integer.parseInt (args[x]);126requests = Integer.parseInt (args[x+1]);127}128129/* start the server */130ServerSocket ss = new ServerSocket(0);131Server svr = new Server(ss);132svr.start();133134Object lock = MultiThreadTest.getLock();135synchronized (lock) {136for (int i=0; i<threads; i++) {137MultiThreadTest t = new MultiThreadTest(ss.getLocalPort(), requests);138t.start ();139}140try {141lock.wait();142} catch (InterruptedException e) {}143}144145// shutdown server - we're done.146svr.shutdown();147148int cnt = svr.connectionCount();149MultiThreadTest.debug("Connections = " + cnt);150int reqs = Worker.getRequests ();151MultiThreadTest.debug("Requests = " + reqs);152System.out.println ("Connection count = " + cnt + " Request count = " + reqs);153if (cnt > threads) { // could be less154throw new RuntimeException ("Expected "+threads + " connections: used " +cnt);155}156if (reqs != threads*requests) {157throw new RuntimeException ("Expected "+ threads*requests+ " requests: got " +reqs);158}159}160}161162/*163* Server thread to accept connection and create worker threads164* to service each connection.165*/166class Server extends Thread {167ServerSocket ss;168int connectionCount;169boolean shutdown = false;170171Server(ServerSocket ss) {172this.ss = ss;173}174175public synchronized int connectionCount() {176return connectionCount;177}178179public synchronized void shutdown() {180shutdown = true;181}182183public void run() {184try {185ss.setSoTimeout(2000);186187for (;;) {188Socket s;189try {190MultiThreadTest.debug("server: calling accept.");191s = ss.accept();192MultiThreadTest.debug("server: return accept.");193} catch (SocketTimeoutException te) {194MultiThreadTest.debug("server: STE");195synchronized (this) {196if (shutdown) {197MultiThreadTest.debug("server: Shuting down.");198return;199}200}201continue;202}203204int id;205synchronized (this) {206id = connectionCount++;207}208209Worker w = new Worker(s, id);210w.start();211MultiThreadTest.debug("server: Started worker " + id);212}213214} catch (Exception e) {215e.printStackTrace();216} finally {217try {218ss.close();219} catch (Exception e) { }220}221}222}223224/*225* Worker thread to service single connection - can service226* multiple http requests on same connection.227*/228class Worker extends Thread {229Socket s;230int id;231232Worker(Socket s, int id) {233this.s = s;234this.id = id;235}236237static int requests = 0;238static Object rlock = new Object();239240public static int getRequests () {241synchronized (rlock) {242return requests;243}244}245public static void incRequests () {246synchronized (rlock) {247requests++;248}249}250251int readUntil (InputStream in, char[] seq) throws IOException {252int i=0, count=0;253while (true) {254int c = in.read();255if (c == -1)256return -1;257count++;258if (c == seq[i]) {259i++;260if (i == seq.length)261return count;262continue;263} else {264i = 0;265}266}267}268269public void run() {270try {271int max = 400;272byte b[] = new byte[1000];273InputStream in = new BufferedInputStream (s.getInputStream());274// response to client275PrintStream out = new PrintStream(276new BufferedOutputStream(277s.getOutputStream() ));278279for (;;) {280281// read entire request from client282int n=0;283284n = readUntil (in, new char[] {'\r','\n', '\r','\n'});285286if (n <= 0) {287MultiThreadTest.debug("worker: " + id + ": Shutdown");288s.close();289return;290}291292MultiThreadTest.debug("worker " + id +293": Read request from client " +294"(" + n + " bytes).");295296incRequests();297out.print("HTTP/1.1 200 OK\r\n");298out.print("Transfer-Encoding: chunked\r\n");299out.print("Content-Type: text/html\r\n");300out.print("Connection: Keep-Alive\r\n");301out.print ("Keep-Alive: timeout=15, max="+max+"\r\n");302out.print("\r\n");303out.print ("6\r\nHello \r\n");304out.print ("5\r\nWorld\r\n");305out.print ("0\r\n\r\n");306out.flush();307308if (--max == 0) {309s.close();310return;311}312}313314} catch (Exception e) {315e.printStackTrace();316} finally {317try {318s.close();319} catch (Exception e) { }320}321}322}323324325