< prev index next >
   1 /*
   2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @bug 8087112
  27  * @library /lib/testlibrary/
  28  * @build jdk.testlibrary.SimpleSSLContext ProxyServer
  29  * @compile ../../../com/sun/net/httpserver/LogFilter.java
  30  * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
  31  * @run main/othervm SmokeTest
  32  */
  33 
  34 //package javaapplication16;
  35 
  36 import com.sun.net.httpserver.*;
  37 import java.net.*;
  38 import java.net.http.*;
  39 import java.io.*;
  40 import java.util.concurrent.*;
  41 import javax.net.ssl.*;
  42 import java.nio.file.*;
  43 import java.util.HashSet;
  44 import java.util.LinkedList;
  45 import java.util.List;
  46 import java.util.Random;
  47 import jdk.testlibrary.SimpleSSLContext;
  48 import static java.net.http.HttpRequest.*;
  49 import static java.net.http.HttpResponse.*;
  50 import java.util.logging.ConsoleHandler;
  51 import java.util.logging.Level;
  52 import java.util.logging.Logger;
  53 
  54 /**
  55  * * Basic smoke test for Http/1.1 client
  56  * - basic request response
  57  * - request body POST
  58  * - response body GET
  59  * - redirect
  60  * - chunked request/response
  61  * - SSL
  62  * - proxies
  63  * - 100 continue
  64  * - check keep alive appears to be working
  65  * - cancel of long request
  66  *
  67  * Uses a FileServerHandler serving a couple of known files
  68  * in docs directory.
  69  */
  70 public class SmokeTest {
  71     static SSLContext ctx;
  72     static HttpServer s1 ;
  73     static HttpsServer s2;
  74     static ExecutorService executor;
  75     static int port;
  76     static int httpsport;
  77     static String httproot;
  78     static String httpsroot;
  79     static HttpClient client;
  80     static ProxyServer proxy;
  81     static int proxyPort;
  82     static RedirectErrorHandler redirectErrorHandler, redirectErrorHandlerSecure;
  83     static RedirectHandler redirectHandler, redirectHandlerSecure;
  84     static DelayHandler delayHandler;
  85     final static String midSizedFilename = "/files/notsobigfile.txt";
  86     final static String smallFilename = "/files/smallfile.txt";
  87     static Path midSizedFile;
  88     static Path smallFile;
  89     static String fileroot;
  90 
  91     static String getFileContent(String path) throws IOException {
  92         FileInputStream fis = new FileInputStream(path);
  93         byte[] buf = new byte[2000];
  94         StringBuilder sb = new StringBuilder();
  95         int n;
  96         while ((n=fis.read(buf)) != -1) {
  97             sb.append(new String(buf, 0, n, "US-ASCII"));
  98         }
  99         return sb.toString();
 100     }
 101 
 102     public static void main(String[] args) throws Exception {
 103         initServer();
 104         fileroot = System.getProperty ("test.src", ".")+ "/docs";
 105         midSizedFile = Paths.get(fileroot + midSizedFilename);
 106         smallFile = Paths.get(fileroot + smallFilename);
 107 
 108         client = HttpClient.create()
 109                            .sslContext(ctx)
 110                            .followRedirects(HttpClient.Redirect.ALWAYS)
 111                            .executorService(Executors.newCachedThreadPool())
 112                            .build();
 113 
 114         try {
 115             test1(httproot + "files/foo.txt", true);
 116 
 117             test1(httproot + "files/foo.txt", false);
 118             test1(httpsroot + "files/foo.txt", true);
 119             test1(httpsroot + "files/foo.txt", false);
 120             test2(httproot + "echo/foo", "This is a short test");
 121             test2(httpsroot + "echo/foo", "This is a short test");
 122 
 123             test3(httproot + "redirect/foo.txt");
 124             test3(httpsroot + "redirect/foo.txt");
 125             test4(httproot + "files/foo.txt");
 126             test4(httpsroot + "files/foo.txt");
 127             test5(httproot + "echo/foo", true);
 128             test5(httpsroot + "echo/foo", true);
 129             test5(httproot + "echo/foo", false);
 130             test5(httpsroot + "echo/foo", false);
 131 
 132             test6(httproot + "echo/foo", true);
 133             test6(httpsroot + "echo/foo", true);
 134             test6(httproot + "echo/foo", false);
 135             test6(httpsroot + "echo/foo", false);
 136 
 137             test7(httproot + "keepalive/foo");
 138 
 139             test8(httproot + "files/foo.txt", true);
 140             test8(httproot + "files/foo.txt", false);
 141             test8(httpsroot + "files/foo.txt", true);
 142             test8(httpsroot + "files/foo.txt", false);
 143             // disabled test9();
 144 
 145             test10(httproot + "redirecterror/foo.txt");
 146 
 147             test10(httpsroot + "redirecterror/foo.txt");
 148 
 149             test11(httproot + "echo/foo");
 150             test11(httpsroot + "echo/foo");
 151             //test12(httproot + "delay/foo", delayHandler);
 152 
 153         } finally {
 154             s1.stop(0);
 155             s2.stop(0);
 156             proxy.close();
 157             executor.shutdownNow();
 158             client.executorService().shutdownNow();
 159         }
 160     }
 161 
 162     static class Auth extends java.net.Authenticator {
 163         volatile int count = 0;
 164         @Override
 165         protected PasswordAuthentication getPasswordAuthentication() {
 166             if (count++ == 0) {
 167                 return new PasswordAuthentication("user", "passwd".toCharArray());
 168             } else {
 169                 return new PasswordAuthentication("user", "goober".toCharArray());
 170             }
 171         }
 172         int count() {
 173             return count;
 174         }
 175     }
 176 
 177     // Basic test
 178     static void test1(String target, boolean fixedLen) throws Exception {
 179         System.out.print("test1: " + target);
 180         URI uri = new URI(target);
 181 
 182         HttpRequest.Builder builder = client.request(uri)
 183                                              .body(noBody());
 184 
 185         if (fixedLen) {
 186             builder.header("XFixed", "yes");
 187         }
 188 
 189         HttpResponse response = builder.GET().response();
 190 
 191         String body = response.body(asString());
 192         if (!body.equals("This is foo.txt\r\n")) {
 193             throw new RuntimeException();
 194         }
 195 
 196         // repeat async
 197         response = builder.GET().responseAsync().join();
 198 
 199         body = response.body(asString());
 200         if (!body.equals("This is foo.txt\r\n")) {
 201             throw new RuntimeException();
 202         }
 203         System.out.println(" OK");
 204     }
 205 
 206     // POST use echo to check reply
 207     static void test2(String s, String body) throws Exception {
 208         System.out.print("test2: " + s);
 209         URI uri = new URI(s);
 210 
 211         HttpResponse response = client.request(uri)
 212                                        .body(fromString(body))
 213                                        .POST()
 214                                        .response();
 215 
 216         if (response.statusCode() != 200) {
 217             throw new RuntimeException(
 218                 "Expected 200, got [ " + response.statusCode() + " ]");
 219         }
 220         String reply = response.body(asString());
 221         if (!reply.equals(body)) {
 222             throw new RuntimeException(
 223                 "Body mismatch: expected [" + body + "], got [" + reply + "]");
 224         }
 225         System.out.println(" OK");
 226     }
 227 
 228     // Redirect
 229     static void test3(String s) throws Exception {
 230         System.out.print("test3: " + s);
 231         URI uri = new URI(s);
 232         RedirectHandler handler = uri.getScheme().equals("https")
 233                 ? redirectHandlerSecure : redirectHandler;
 234 
 235         HttpResponse response = client.request(uri)
 236                                       .body(noBody())
 237                                       .GET()
 238                                       .response();
 239 
 240         if (response.statusCode() != 200) {
 241             throw new RuntimeException(
 242                 "Expected 200, got [ " + response.statusCode() + " ]");
 243         } else {
 244             response.body(HttpResponse.asFile(Paths.get("redir1.txt")));
 245         }
 246 
 247         Path downloaded = Paths.get("redir1.txt");
 248         if (Files.size(downloaded) != Files.size(midSizedFile)) {
 249             throw new RuntimeException("Size mismatch");
 250         }
 251 
 252         System.out.printf(" (count: %d) ", handler.count());
 253         // repeat with async api
 254 
 255         handler.reset();
 256 
 257         response = client.request(uri)
 258                          .body(noBody())
 259                          .GET()
 260                          .responseAsync()
 261                          .join();
 262 
 263         if (response.statusCode() != 200) {
 264             throw new RuntimeException(
 265                     "Expected 200, got [ " + response.statusCode() + " ]");
 266         } else {
 267             response.body(HttpResponse.asFile(Paths.get("redir2.txt")));
 268         }
 269 
 270         downloaded = Paths.get("redir2.txt");
 271         if (Files.size(downloaded) != Files.size(midSizedFile)) {
 272             throw new RuntimeException("Size mismatch 2");
 273         }
 274         System.out.printf(" (count: %d) ", handler.count());
 275         System.out.println(" OK");
 276     }
 277 
 278     // Proxies
 279     static void test4(String s) throws Exception {
 280         System.out.print("test4: " + s);
 281         URI uri = new URI(s);
 282         InetSocketAddress proxyAddr = new InetSocketAddress("127.0.0.1", proxyPort);
 283         String filename = fileroot + uri.getPath();
 284 
 285         HttpClient cl = HttpClient.create()
 286                                   .proxy(ProxySelector.of(proxyAddr))
 287                                   .sslContext(ctx)
 288                                   .build();
 289 
 290         CompletableFuture<String> fut = cl.request(uri)
 291                                           .body(noBody())
 292                                           .GET()
 293                                           .responseAsync()
 294                                           .thenCompose((HttpResponse response) ->
 295                                                           response.bodyAsync(asString())
 296                                           );
 297 
 298         String body = fut.get(5, TimeUnit.HOURS);
 299 
 300         String fc = getFileContent(filename);
 301 
 302         if (!body.equals(fc)) {
 303             throw new RuntimeException(
 304                     "Body mismatch: expected [" + body + "], got [" + fc + "]");
 305         }
 306         cl.executorService().shutdownNow();
 307         System.out.println(" OK");
 308     }
 309 
 310     // 100 Continue: use echo target
 311     static void test5(String target, boolean fixedLen) throws Exception {
 312         System.out.print("test5: " + target);
 313         URI uri = new URI(target);
 314         String requestBody = generateString(12 * 1024 + 13);
 315 
 316         HttpRequest.Builder builder = client.request(uri)
 317                                             .expectContinue(true)
 318                                             .body(fromString(requestBody));
 319 
 320         if (fixedLen) {
 321             builder.header("XFixed", "yes");
 322         }
 323 
 324         HttpResponse response = builder.GET().response();
 325 
 326         String body = response.body(asString());
 327 
 328         if (!body.equals(requestBody)) {
 329             throw new RuntimeException(
 330                     "Body mismatch: expected [" + body + "], got [" + body + "]");
 331         }
 332         System.out.println(" OK");
 333     }
 334 
 335     // use echo
 336     static void test6(String target, boolean fixedLen) throws Exception {
 337         System.out.print("test6: " + target);
 338         URI uri = new URI(target);
 339         String requestBody = generateString(12 * 1024 + 3);
 340 
 341         HttpRequest.Builder builder = client.request(uri)
 342                                             .body(noBody());
 343 
 344         if (fixedLen) {
 345             builder.header("XFixed", "yes");
 346         }
 347 
 348         HttpResponse response = builder.GET().response();
 349 
 350         if (response.statusCode() != 200) {
 351             throw new RuntimeException(
 352                     "Expected 200, got [ " + response.statusCode() + " ]");
 353         }
 354 
 355         String responseBody = response.body(asString());
 356 
 357         if (responseBody.equals(requestBody)) {
 358             throw new RuntimeException(
 359                     "Body mismatch: expected [" + requestBody + "], got [" + responseBody + "]");
 360         }
 361         System.out.println(" OK");
 362     }
 363 
 364     @SuppressWarnings("rawtypes")
 365     static void test7(String target) throws Exception {
 366         System.out.print("test7: " + target);
 367 
 368         // First test
 369         URI uri = new URI(target);
 370         for (int i=0; i<4; i++) {
 371             HttpResponse r = client.request(uri)
 372                                    .body(noBody())
 373                                    .GET()
 374                                    .response();
 375             String body = r.body(asString());
 376             if (!body.equals("OK")) {
 377                 throw new RuntimeException("Expected OK, got: " + body);
 378             }
 379         }
 380 
 381         // Second test: 4 x parallel
 382         List<CompletableFuture<HttpResponse>> futures = new LinkedList<>();
 383         for (int i=0; i<4; i++) {
 384             futures.add(client.request(uri)
 385                               .body(noBody())
 386                               .GET()
 387                               .responseAsync());
 388         }
 389         // all sent?
 390         CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
 391                          .join();
 392 
 393         List<CompletableFuture<String>> futureBodies = new LinkedList<>();
 394         for (int i=0; i<4; i++) {
 395             futureBodies.add(futures.get(i)
 396                                     .join()
 397                                     .bodyAsync(asString()));
 398         }
 399         CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
 400                          .join();
 401 
 402         for (CompletableFuture<String> future : futureBodies) {
 403             String body = future.get();
 404             if (!body.equals("OK")) {
 405                 throw new RuntimeException("Expected OK, got: " + body);
 406             }
 407         }
 408 
 409         // Third test: Multiple of 4 parallel requests
 410         BlockingQueue<String> q = new LinkedBlockingQueue<>();
 411         for (int i=0; i<4; i++) {
 412             client.request(uri)
 413                   .body(noBody())
 414                   .GET()
 415                   .responseAsync()
 416                   .thenApply((HttpResponse resp) -> {
 417                       String body = resp.body(asString());
 418                       putQ(q, body);
 419                       return body;
 420                   });
 421         }
 422         // we've sent four requests. Now, just send another request
 423         // as each response is received. The idea is to ensure that
 424         // only four sockets ever get used.
 425 
 426         for (int i=0; i<100; i++) {
 427             // block until response received
 428             String body = takeQ(q);
 429             if (!body.equals("OK")) {
 430                 throw new RuntimeException(body);
 431             }
 432             client.request(uri)
 433                   .body(noBody())
 434                   .GET()
 435                   .responseAsync()
 436                   .thenApply((HttpResponse resp) -> {
 437                       String body1 = resp.body(asString());
 438                       putQ(q, body1);
 439                       return body1;
 440                   });
 441         }
 442         // should be four left
 443         for (int i=0; i<4; i++) {
 444             takeQ(q);
 445         }
 446         System.out.println(" OK");
 447     }
 448 
 449     static String takeQ(BlockingQueue<String> q) {
 450         String r = null;
 451         try {
 452             r = q.take();
 453         } catch (InterruptedException e) {}
 454 
 455         return r;
 456     }
 457 
 458     static void putQ(BlockingQueue<String> q, String o) {
 459         try {
 460             q.put(o);
 461         } catch (InterruptedException e) {
 462             // can't happen
 463         }
 464     }
 465 
 466     static void test8(String target, boolean fixedLen) throws Exception {
 467         System.out.print("test8: " + target);
 468         URI uri = new URI(target);
 469 
 470         HttpRequest.Builder builder = client.request(uri)
 471                                             .body(noBody());
 472 
 473         if (fixedLen) {
 474             builder.header("XFixed", "yes");
 475         }
 476 
 477         HttpResponse response = builder.GET().response();
 478 
 479         StringBuilder sb = new StringBuilder();
 480 
 481         InputStream is = response.body(asInputStream());
 482         int c;
 483         byte[] buf = new byte[2048];
 484         while ((c = is.read(buf)) != -1) {
 485             for (int i=0; i<c; i++)
 486                 sb.append((char)buf[i]);
 487         }
 488         is.close();
 489         String body = sb.toString();
 490 
 491         if (!body.equals("This is foo.txt\r\n")) {
 492             throw new RuntimeException("Expected \"This is foo.txt\", got: " + body);
 493         }
 494         System.out.println(" OK");
 495     }
 496 
 497     // Chunked output stream
 498     static void test11(String target) throws Exception {
 499         System.out.print("test11: " + target);
 500         URI uri = new URI(target);
 501 
 502         FileInputStream file = new FileInputStream(smallFile.toFile());
 503 
 504         HttpRequest.Builder builder = client.request(uri)
 505                                             .body(HttpRequest.fromInputStream(file));
 506         HttpResponse response = builder.POST().response();
 507 
 508         if (response.statusCode() != 200) {
 509             throw new RuntimeException("Wrong response code");
 510         }
 511 
 512         Path download = Paths.get("test11.txt");
 513         download.toFile().delete();
 514         response.body(HttpResponse.asFile(download));
 515 
 516         if (Files.size(download) != Files.size(smallFile)) {
 517             System.out.println("Original size: " + Files.size(smallFile));
 518             System.out.println("Downloaded size: " + Files.size(download));
 519             throw new RuntimeException("Size mismatch");
 520         }
 521         System.out.println(" OK");
 522     }
 523 
 524     // cancel
 525     /*
 526     static void test12(String target, DelayHandler h) throws Exception {
 527         System.out.print("test12: " + target);
 528         URI uri = new URI(target);
 529 
 530         HttpRequest.Builder builder = client
 531             .request(uri)
 532             .body(HttpRequest.fromString("Hello world"));
 533 
 534         HttpRequest request = builder
 535                 .GET();
 536         request.sendAsync();
 537         h.barrier1().await();
 538         // request has been processed
 539         CompletableFuture<HttpResponse> cf = request.responseAsync();
 540         request.cancel();
 541         h.barrier2().await();
 542         try {
 543             HttpResponse r = cf.get();
 544             throw new RuntimeException("failed 2");
 545         } catch (Exception e) {
 546         }
 547         System.out.println(" OK");
 548     }
 549 */
 550     static void delay(int seconds) {
 551         try {
 552             Thread.sleep(seconds * 1000);
 553         } catch (InterruptedException e) {
 554         }
 555     }
 556 /*
 557     // test won't work until sending fully decoupled from receiving in impl
 558     static void test9() throws Exception {
 559         System.out.print("test9: ");
 560         UploadServer up = new UploadServer(1000 * 1000);
 561         int size = up.size();
 562         String u = "http://127.0.0.1:" + up.port() + "/";
 563         URI uri = new URI(u);
 564 
 565         HttpRequest request = client
 566             .request(uri)
 567             .body(new HttpRequestBodyProcessor() {
 568                 @Override
 569                 public ByteBuffer onRequestBodyChunk(ByteBuffer b) throws IOException {
 570                     // slow things down
 571                     delay(1);
 572                     b.position(b.limit()); // fill it
 573                     return b;
 574                 }
 575                 @Override
 576                 public long onRequestStart(HttpRequest req) throws IOException {
 577                     return size;
 578                 }
 579              })
 580             .PUT();
 581 
 582         CompletableFuture<HttpRequest> cf1 = request.sendAsync();
 583         CompletableFuture<HttpResponse> cf = request.responseAsync();
 584 
 585         HttpResponse resp = cf.get(1, TimeUnit.MINUTES);
 586         if (resp.statusCode() != 201) {
 587             throw new RuntimeException("failed: wrong response code");
 588         }
 589         delay(2); // allow some data to be sent
 590         request.cancel();
 591         delay(1);
 592         if (up.failed()) {
 593             throw new RuntimeException("failed to cancel request");
 594         }
 595         System.out.println(" OK");
 596     }
 597   */
 598     // Redirect loop: return an error after a certain number of redirects
 599     static void test10(String s) throws Exception {
 600         System.out.print("test10: " + s);
 601         URI uri = new URI(s);
 602         RedirectErrorHandler handler = uri.getScheme().equals("https")
 603                 ? redirectErrorHandlerSecure : redirectErrorHandler;
 604 
 605         CompletableFuture<HttpResponse> cf = client.request(uri)
 606                                                    .body(noBody())
 607                                                    .GET()
 608                                                    .responseAsync();
 609 
 610         try {
 611             HttpResponse response = cf.join();
 612             throw new RuntimeException("Exepected Completion Exception");
 613         } catch (CompletionException e) {
 614             //System.out.println(e);
 615         }
 616 
 617         System.out.printf(" (Calls %d) ", handler.count());
 618         System.out.println(" OK");
 619     }
 620 
 621     static final int NUM = 50;
 622 
 623     static Random random = new Random();
 624     static final String alphabet = "ABCDEFGHIJKLMNOPQRST";
 625 
 626     static char randomChar() {
 627         return alphabet.charAt(random.nextInt(alphabet.length()));
 628     }
 629 
 630     static String generateString(int length) {
 631         StringBuilder sb = new StringBuilder(length);
 632         for (int i=0; i<length; i++) {
 633             sb.append(randomChar());
 634         }
 635         return sb.toString();
 636     }
 637 
 638     static void initServer() throws Exception {
 639         Logger logger = Logger.getLogger("com.sun.net.httpserver");
 640         ConsoleHandler ch = new ConsoleHandler();
 641         logger.setLevel(Level.ALL);
 642         ch.setLevel(Level.ALL);
 643         logger.addHandler(ch);
 644 
 645         String root = System.getProperty ("test.src")+ "/docs";
 646         InetSocketAddress addr = new InetSocketAddress (0);
 647         s1 = HttpServer.create (addr, 0);
 648         if (s1 instanceof HttpsServer) {
 649             throw new RuntimeException ("should not be httpsserver");
 650         }
 651         s2 = HttpsServer.create (addr, 0);
 652         HttpHandler h = new FileServerHandler(root);
 653 
 654         HttpContext c1 = s1.createContext("/files", h);
 655         HttpContext c2 = s2.createContext("/files", h);
 656         HttpContext c3 = s1.createContext("/echo", new EchoHandler());
 657         redirectHandler = new RedirectHandler("/redirect");
 658         redirectHandlerSecure = new RedirectHandler("/redirect");
 659         HttpContext c4 = s1.createContext("/redirect", redirectHandler);
 660         HttpContext c41 = s2.createContext("/redirect", redirectHandlerSecure);
 661         HttpContext c5 = s2.createContext("/echo", new EchoHandler());
 662         HttpContext c6 = s1.createContext("/keepalive", new KeepAliveHandler());
 663         redirectErrorHandler = new RedirectErrorHandler("/redirecterror");
 664         redirectErrorHandlerSecure = new RedirectErrorHandler("/redirecterror");
 665         HttpContext c7 = s1.createContext("/redirecterror", redirectErrorHandler);
 666         HttpContext c71 = s2.createContext("/redirecterror", redirectErrorHandlerSecure);
 667         delayHandler = new DelayHandler();
 668         HttpContext c8 = s1.createContext("/delay", delayHandler);
 669         HttpContext c81 = s2.createContext("/delay", delayHandler);
 670 
 671         executor = Executors.newCachedThreadPool();
 672         s1.setExecutor(executor);
 673         s2.setExecutor(executor);
 674         ctx = new SimpleSSLContext().get();
 675         s2.setHttpsConfigurator(new HttpsConfigurator(ctx));
 676         s1.start();
 677         s2.start();
 678 
 679         port = s1.getAddress().getPort();
 680         System.out.println("HTTP server port = " + port);
 681         httpsport = s2.getAddress().getPort();
 682         System.out.println("HTTPS server port = " + httpsport);
 683         httproot = "http://127.0.0.1:" + port + "/";
 684         httpsroot = "https://127.0.0.1:" + httpsport + "/";
 685 
 686         proxy = new ProxyServer(0, false);
 687         proxyPort = proxy.getPort();
 688         System.out.println("Proxy port = " + proxyPort);
 689     }
 690 }
 691 
 692 class UploadServer extends Thread {
 693     int statusCode;
 694     ServerSocket ss;
 695     int port;
 696     int size;
 697     Object lock;
 698     boolean failed = false;
 699 
 700     UploadServer(int size) throws IOException {
 701         this.statusCode = statusCode;
 702         this.size = size;
 703         ss = new ServerSocket(0);
 704         port = ss.getLocalPort();
 705         lock = new Object();
 706     }
 707 
 708     int port() {
 709           return port;
 710     }
 711 
 712     int size() {
 713           return size;
 714     }
 715 
 716     // wait a sec before calling this
 717     boolean failed() {
 718         synchronized(lock) {
 719             return failed;
 720         }
 721     }
 722 
 723     @Override
 724     public void run () {
 725         int nbytes = 0;
 726         Socket s = null;
 727 
 728         synchronized(lock) {
 729             try {
 730                 s = ss.accept();
 731 
 732                 InputStream is = s.getInputStream();
 733                 OutputStream os = s.getOutputStream();
 734                 os.write("HTTP/1.1 201 OK\r\nContent-length: 0\r\n\r\n".getBytes());
 735                 int n;
 736                 byte[] buf = new byte[8000];
 737                 while ((n=is.read(buf)) != -1) {
 738                     nbytes += n;
 739                 }
 740             } catch (IOException e) {
 741                 System.out.println ("read " + nbytes);
 742                 System.out.println ("size " + size);
 743                 failed = nbytes >= size;
 744             } finally {
 745                 try {
 746                     ss.close();
 747                     if (s != null)
 748                         s.close();
 749                 } catch (IOException e) {}
 750             }
 751         }
 752     }
 753 }
 754 
 755 class RedirectHandler implements HttpHandler {
 756     String root;
 757     volatile int count = 0;
 758 
 759     RedirectHandler(String root) {
 760         this.root = root;
 761     }
 762 
 763     @Override
 764     public synchronized void handle(HttpExchange t)
 765         throws IOException
 766     {
 767         byte[] buf = new byte[2048];
 768         try (InputStream is = t.getRequestBody()) {
 769             while (is.read(buf) != -1) ;
 770         }
 771 
 772         Headers responseHeaders = t.getResponseHeaders();
 773 
 774         if (count++ < 1) {
 775             responseHeaders.add("Location", root + "/foo/" + count);
 776         } else {
 777             responseHeaders.add("Location", SmokeTest.midSizedFilename);
 778         }
 779         t.sendResponseHeaders(301, -1);
 780         t.close();
 781     }
 782 
 783     int count() {
 784         return count;
 785     }
 786 
 787     void reset() {
 788         count = 0;
 789     }
 790 }
 791 
 792 class RedirectErrorHandler implements HttpHandler {
 793     String root;
 794     volatile int count = 1;
 795 
 796     RedirectErrorHandler(String root) {
 797         this.root = root;
 798     }
 799 
 800     synchronized int count() {
 801         return count;
 802     }
 803 
 804     synchronized void increment() {
 805         count++;
 806     }
 807 
 808     @Override
 809     public synchronized void handle (HttpExchange t)
 810         throws IOException
 811     {
 812         byte[] buf = new byte[2048];
 813         try (InputStream is = t.getRequestBody()) {
 814             while (is.read(buf) != -1) ;
 815         }
 816 
 817         Headers map = t.getResponseHeaders();
 818         String redirect = root + "/foo/" + Integer.toString(count);
 819         increment();
 820         map.add("Location", redirect);
 821         t.sendResponseHeaders(301, -1);
 822         t.close();
 823     }
 824 }
 825 
 826 class Util {
 827     static byte[] readAll(InputStream is) throws IOException {
 828         byte[] buf = new byte[1024];
 829         byte[] result = new byte[0];
 830 
 831         while (true) {
 832             int n = is.read(buf);
 833             if (n > 0) {
 834                 byte[] b1 = new byte[result.length + n];
 835                 System.arraycopy(result, 0, b1, 0, result.length);
 836                 System.arraycopy(buf, 0, b1, result.length, n);
 837                 result = b1;
 838             } else if (n == -1) {
 839                 return result;
 840             }
 841         }
 842     }
 843 }
 844 
 845 class DelayHandler implements HttpHandler {
 846 
 847     CyclicBarrier bar1 = new CyclicBarrier(2);
 848     CyclicBarrier bar2 = new CyclicBarrier(2);
 849     CyclicBarrier bar3 = new CyclicBarrier(2);
 850 
 851     CyclicBarrier barrier1() {
 852         return bar1;
 853     }
 854 
 855     CyclicBarrier barrier2() {
 856         return bar2;
 857     }
 858 
 859     @Override
 860     public synchronized void handle(HttpExchange he) throws IOException {
 861         byte[] buf = Util.readAll(he.getRequestBody());
 862         try {
 863             bar1.await();
 864             bar2.await();
 865         } catch (Exception e) {}
 866         he.sendResponseHeaders(200, -1); // will probably fail
 867         he.close();
 868     }
 869 
 870 }
 871 
 872 // check for simple hardcoded sequence and use remote address
 873 // to check.
 874 // First 4 requests executed in sequence (should use same connection/address)
 875 // Next 4 requests parallel (should use different addresses)
 876 // Then send 4 requests in parallel x 100 times (same four addresses used all time)
 877 
 878 class KeepAliveHandler implements HttpHandler {
 879     volatile int counter = 0;
 880 
 881     HashSet<Integer> portSet = new HashSet<>();
 882 
 883     volatile int[] ports = new int[4];
 884 
 885     void sleep(int n) {
 886         try {
 887             Thread.sleep(n);
 888         } catch (InterruptedException e) {}
 889     }
 890 
 891     @Override
 892     public synchronized void handle (HttpExchange t)
 893         throws IOException
 894     {
 895         int remotePort = t.getRemoteAddress().getPort();
 896         String result = "OK";
 897 
 898         int n = counter++;
 899         /// First test
 900         if (n < 4) {
 901             ports[n] = remotePort;
 902         }
 903         if (n == 3) {
 904             // check all values in ports[] are the same
 905             if (ports[0] != ports[1] || ports[2] != ports[3]
 906                     || ports[0] != ports[2]) {
 907                 result = "Error " + Integer.toString(n);
 908                 System.out.println(result);
 909             }
 910         }
 911         // Second test
 912         if (n >=4 && n < 8) {
 913             // delay to ensure ports are different
 914             sleep(500);
 915             ports[n-4] = remotePort;
 916         }
 917         if (n == 7) {
 918             // should be all different
 919             if (ports[0] == ports[1] || ports[2] == ports[3]
 920                     || ports[0] == ports[2]) {
 921                 result = "Error " + Integer.toString(n);
 922                 System.out.println(result);
 923                 System.out.printf("Ports: %d, %d, %d, %d\n", ports[0], ports[1], ports[2], ports[3]);
 924             }
 925             // setup for third test
 926             for (int i=0; i<4; i++) {
 927                 portSet.add(ports[i]);
 928             }
 929         }
 930         // Third test
 931         if (n > 7) {
 932             // just check that port is one of the ones in portSet
 933             if (!portSet.contains(remotePort)) {
 934                 System.out.println ("UNEXPECTED REMOTE PORT " + remotePort);
 935                 result = "Error " + Integer.toString(n);
 936                 System.out.println(result);
 937             }
 938         }
 939         byte[] buf = new byte[2048];
 940 
 941         try (InputStream is = t.getRequestBody()) {
 942             while (is.read(buf) != -1) ;
 943         }
 944         t.sendResponseHeaders(200, result.length());
 945         OutputStream o = t.getResponseBody();
 946         o.write(result.getBytes("US-ASCII"));
 947         t.close();
 948     }
 949 }
< prev index next >