test/jdk/java/net/httpclient/LargeResponseContent.java
changeset 52283 ef0fed0a3953
child 54314 46cf212cdcca
equal deleted inserted replaced
52282:003c062e16ea 52283:ef0fed0a3953
       
     1 /*
       
     2  * Copyright (c) 2018, 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 import java.io.IOException;
       
    25 import java.io.InputStream;
       
    26 import java.io.OutputStream;
       
    27 import java.net.InetAddress;
       
    28 import java.net.InetSocketAddress;
       
    29 import java.net.ServerSocket;
       
    30 import java.net.Socket;
       
    31 import java.net.URI;
       
    32 import java.net.http.HttpClient;
       
    33 import java.net.http.HttpHeaders;
       
    34 import java.net.http.HttpRequest;
       
    35 import java.net.http.HttpResponse;
       
    36 import java.nio.ByteBuffer;
       
    37 import java.nio.charset.StandardCharsets;
       
    38 import java.util.List;
       
    39 import java.util.concurrent.CompletableFuture;
       
    40 import java.util.concurrent.CompletionStage;
       
    41 import java.util.concurrent.Flow;
       
    42 
       
    43 /**
       
    44  * @test
       
    45  * @bug 8212926
       
    46  * @summary Basic tests for response timeouts
       
    47  * @run main/othervm LargeResponseContent
       
    48  */
       
    49 
       
    50 public class LargeResponseContent {
       
    51     final ServerSocket server;
       
    52     final int port;
       
    53 
       
    54     public LargeResponseContent() throws Exception {
       
    55         server = new ServerSocket(0, 10, InetAddress.getLoopbackAddress());
       
    56         Thread serverThread = new Thread(this::handleConnection);
       
    57         serverThread.setDaemon(false);
       
    58         port = server.getLocalPort();
       
    59         serverThread.start();
       
    60     }
       
    61 
       
    62     void runClient() throws IOException, InterruptedException {
       
    63         URI uri = URI.create("http://127.0.0.1:" + Integer.toString(port) + "/foo");
       
    64         HttpClient client = HttpClient.newHttpClient();
       
    65         HttpRequest request = HttpRequest.newBuilder(uri)
       
    66                 .GET()
       
    67                 .build();
       
    68         HttpResponse<Long> response = client.send(request, new ClientHandler());
       
    69         System.out.println("Response code = " + response.statusCode());
       
    70         long blen = response.body();
       
    71         if (blen != CONTENT_LEN)
       
    72             throw new RuntimeException("wrong content length");
       
    73     }
       
    74 
       
    75     public static void main(String[] args) throws Exception {
       
    76         System.out.println ("CONTENT_LEN = " + CONTENT_LEN);
       
    77         System.out.println ("CLEN_STR = " + CLEN_STR);
       
    78         LargeResponseContent test = new LargeResponseContent();
       
    79         test.runClient();
       
    80     }
       
    81 
       
    82     static class ClientHandler implements HttpResponse.BodyHandler<Long> {
       
    83 
       
    84         @Override
       
    85         public HttpResponse.BodySubscriber<Long> apply(HttpResponse.ResponseInfo responseInfo) {
       
    86             HttpHeaders headers = responseInfo.headers();
       
    87             headers.firstValue("content-length");
       
    88             long  clen = headers.firstValueAsLong("content-length").orElse(-1);
       
    89             if (clen != CONTENT_LEN)
       
    90                 return new Subscriber(new RuntimeException("Wrong content length received"));
       
    91             return new Subscriber(null);
       
    92         }
       
    93     }
       
    94 
       
    95     static class Subscriber implements HttpResponse.BodySubscriber<Long> {
       
    96         final CompletableFuture<Long> cf = new CompletableFuture<>();
       
    97         volatile Flow.Subscription subscription;
       
    98         volatile long counter = 0;
       
    99 
       
   100         Subscriber(Throwable t) {
       
   101             if (t != null)
       
   102                 cf.completeExceptionally(t);
       
   103         }
       
   104 
       
   105         @Override
       
   106         public CompletionStage<Long> getBody() {
       
   107             return cf;
       
   108         }
       
   109 
       
   110         @Override
       
   111         public void onSubscribe(Flow.Subscription subscription) {
       
   112             this.subscription = subscription;
       
   113             subscription.request(Long.MAX_VALUE);
       
   114         }
       
   115 
       
   116         @Override
       
   117         public void onNext(List<ByteBuffer> item) {
       
   118             long v = 0;
       
   119             for (ByteBuffer b : item)
       
   120                 v+= b.remaining();
       
   121             counter += v;
       
   122         }
       
   123 
       
   124         @Override
       
   125         public void onError(Throwable throwable) {
       
   126             throwable.printStackTrace();
       
   127         }
       
   128 
       
   129         @Override
       
   130         public void onComplete() {
       
   131             cf.complete(counter);
       
   132         }
       
   133     }
       
   134 
       
   135     static final long CONTENT_LEN = Integer.MAX_VALUE + 1000L;
       
   136     static final String CLEN_STR = Long.valueOf(CONTENT_LEN).toString();
       
   137 
       
   138     static String RESPONSE = "HTTP/1.1 200 OK\r\n" +
       
   139             "Content-length: " + CLEN_STR + "\r\n" +
       
   140             "\r\n";
       
   141 
       
   142 
       
   143     void readHeaders(InputStream is) throws IOException {
       
   144         String s = "";
       
   145         byte[] buf = new byte[128];
       
   146         while (!s.endsWith("\r\n\r\n")) {
       
   147             int c = is.read(buf);
       
   148             String f = new String(buf, 0, c, StandardCharsets.ISO_8859_1);
       
   149             s = s + f;
       
   150         }
       
   151     }
       
   152 
       
   153     public void handleConnection() {
       
   154         long remaining = CONTENT_LEN;
       
   155         try {
       
   156             Socket socket = server.accept();
       
   157             InputStream is = socket.getInputStream();
       
   158             readHeaders(is); // read first byte
       
   159             OutputStream os = socket.getOutputStream();
       
   160             os.write(RESPONSE.getBytes());
       
   161             byte[] buf = new byte[64 * 1024];
       
   162             while (remaining > 0) {
       
   163                 int amount = (int)Math.min(remaining, buf.length);
       
   164                 os.write(buf, 0, amount);
       
   165                 remaining -= amount;
       
   166             }
       
   167             System.out.println("Server: finished writing");
       
   168             os.close();
       
   169 
       
   170         } catch (IOException e) {
       
   171             long sent = CONTENT_LEN - remaining;
       
   172             System.out.println("Sent " + sent);
       
   173             e.printStackTrace();
       
   174         }
       
   175     }
       
   176 }
       
   177