test/jdk/java/net/httpclient/ShortResponseBody.java
author dfuchs
Tue, 01 Oct 2019 12:10:33 +0100
changeset 58423 54de0c861d32
parent 53256 bd8df96decba
child 58968 7f1daafda27b
permissions -rw-r--r--
8231506: Fix some instabilities in a few networking tests Reviewed-by: alanb, chegar, msheppar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
     1
/*
53256
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
     2
 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
     4
 *
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
     7
 * published by the Free Software Foundation.
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
     8
 *
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    13
 * accompanied this code).
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    14
 *
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    18
 *
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    21
 * questions.
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    22
 */
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    23
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    24
/*
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    25
 * @test
53256
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
    26
 * @bug 8216498
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    27
 * @summary Tests Exception detail message when too few response bytes are
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    28
 *          received before a socket exception or eof.
52121
934969c63223 8211978: Move testlibrary/jdk/testlibrary/SimpleSSLContext.java and testkeys to network testlibrary
jjiang
parents: 50985
diff changeset
    29
 * @library /test/lib
934969c63223 8211978: Move testlibrary/jdk/testlibrary/SimpleSSLContext.java and testkeys to network testlibrary
jjiang
parents: 50985
diff changeset
    30
 * @build jdk.test.lib.net.SimpleSSLContext
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    31
 * @run testng/othervm
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    32
 *       -Djdk.httpclient.HttpClient.log=headers,errors,channel
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    33
 *       ShortResponseBody
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    34
 */
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    35
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    36
import java.io.IOException;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    37
import java.io.InputStream;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    38
import java.io.OutputStream;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    39
import java.io.UncheckedIOException;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    40
import java.net.InetAddress;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    41
import java.net.InetSocketAddress;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    42
import java.net.ServerSocket;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    43
import java.net.Socket;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    44
import java.net.URI;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    45
import java.net.http.HttpClient;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    46
import java.net.http.HttpRequest;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    47
import java.net.http.HttpRequest.BodyPublishers;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    48
import java.net.http.HttpResponse;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    49
import java.util.ArrayList;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    50
import java.util.Arrays;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    51
import java.util.List;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    52
import java.util.concurrent.ExecutionException;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    53
import java.util.concurrent.Executor;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    54
import java.util.concurrent.ExecutorService;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    55
import java.util.concurrent.Executors;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    56
import java.util.concurrent.ThreadFactory;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    57
import java.util.concurrent.atomic.AtomicLong;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    58
import java.util.stream.Stream;
52121
934969c63223 8211978: Move testlibrary/jdk/testlibrary/SimpleSSLContext.java and testkeys to network testlibrary
jjiang
parents: 50985
diff changeset
    59
import jdk.test.lib.net.SimpleSSLContext;
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    60
import org.testng.annotations.AfterTest;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    61
import org.testng.annotations.BeforeTest;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    62
import org.testng.annotations.DataProvider;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    63
import org.testng.annotations.Test;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    64
import javax.net.ssl.SSLContext;
53256
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
    65
import javax.net.ssl.SSLHandshakeException;
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    66
import javax.net.ssl.SSLServerSocketFactory;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    67
import javax.net.ssl.SSLParameters;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    68
import javax.net.ssl.SSLSocket;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    69
import static java.lang.System.out;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    70
import static java.net.http.HttpClient.Builder.NO_PROXY;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    71
import static java.net.http.HttpResponse.BodyHandlers.ofString;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    72
import static java.nio.charset.StandardCharsets.US_ASCII;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    73
import static java.util.stream.Collectors.toList;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    74
import static org.testng.Assert.assertTrue;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    75
import static org.testng.Assert.assertEquals;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    76
import static org.testng.Assert.fail;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    77
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    78
public class ShortResponseBody {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    79
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    80
    Server closeImmediatelyServer;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    81
    Server closeImmediatelyHttpsServer;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    82
    Server variableLengthServer;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    83
    Server variableLengthHttpsServer;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    84
    Server fixedLengthServer;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    85
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    86
    String httpURIClsImed;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    87
    String httpsURIClsImed;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    88
    String httpURIVarLen;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    89
    String httpsURIVarLen;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    90
    String httpURIFixLen;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    91
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    92
    SSLContext sslContext;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    93
    SSLParameters sslParameters;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    94
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    95
    static final String EXPECTED_RESPONSE_BODY =
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    96
            "<html><body><h1>Heading</h1><p>Some Text</p></body></html>";
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    97
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    98
    final static AtomicLong ids = new AtomicLong();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
    99
    final ThreadFactory factory = new ThreadFactory() {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   100
        @Override
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   101
        public Thread newThread(Runnable r) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   102
            Thread thread = new Thread(r,  "HttpClient-Worker-" + ids.incrementAndGet());
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   103
            thread.setDaemon(true);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   104
            return thread;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   105
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   106
    };
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   107
    final ExecutorService service = Executors.newCachedThreadPool(factory);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   108
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   109
    @DataProvider(name = "sanity")
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   110
    public Object[][] sanity() {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   111
        return new Object[][]{
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   112
            { httpURIVarLen  + "?length=all" },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   113
            { httpsURIVarLen + "?length=all" },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   114
            { httpURIFixLen  + "?length=all" },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   115
        };
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   116
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   117
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   118
    @Test(dataProvider = "sanity")
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   119
    void sanity(String url) throws Exception {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   120
        HttpClient client = newHttpClient();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   121
        HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   122
        HttpResponse<String> response = client.send(request, ofString());
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   123
        String body = response.body();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   124
        assertEquals(body, EXPECTED_RESPONSE_BODY);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   125
        client.sendAsync(request, ofString())
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   126
                .thenApply(resp -> resp.body())
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   127
                .thenAccept(b -> assertEquals(b, EXPECTED_RESPONSE_BODY))
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   128
                .join();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   129
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   130
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   131
    @DataProvider(name = "uris")
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   132
    public Object[][] variants() {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   133
        String[][] cases = new String[][] {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   134
            // The length query string is the total number of bytes in the reply,
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   135
            // including headers, before the server closes the connection. The
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   136
            // second arg is a partial-expected-detail message in the exception.
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   137
            { httpURIVarLen + "?length=0",   "no bytes"     }, // EOF without receiving anything
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   138
            { httpURIVarLen + "?length=1",   "status line"  }, // EOF during status-line
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   139
            { httpURIVarLen + "?length=2",   "status line"  },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   140
            { httpURIVarLen + "?length=10",  "status line"  },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   141
            { httpURIVarLen + "?length=19",  "header"       }, // EOF during Content-Type header
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   142
            { httpURIVarLen + "?length=30",  "header"       },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   143
            { httpURIVarLen + "?length=45",  "header"       },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   144
            { httpURIVarLen + "?length=48",  "header"       },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   145
            { httpURIVarLen + "?length=51",  "header"       },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   146
            { httpURIVarLen + "?length=98",  "header"       }, // EOF during Connection header
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   147
            { httpURIVarLen + "?length=100", "header"       },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   148
            { httpURIVarLen + "?length=101", "header"       },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   149
            { httpURIVarLen + "?length=104", "header"       },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   150
            { httpURIVarLen + "?length=106", "chunked transfer encoding" }, // EOF during chunk header ( length )
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   151
            { httpURIVarLen + "?length=110", "chunked transfer encoding" }, // EOF during chunk response body data
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   152
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   153
            { httpsURIVarLen + "?length=0",   "no bytes"    },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   154
            { httpsURIVarLen + "?length=1",   "status line" },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   155
            { httpsURIVarLen + "?length=2",   "status line" },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   156
            { httpsURIVarLen + "?length=10",  "status line" },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   157
            { httpsURIVarLen + "?length=19",  "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   158
            { httpsURIVarLen + "?length=30",  "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   159
            { httpsURIVarLen + "?length=45",  "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   160
            { httpsURIVarLen + "?length=48",  "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   161
            { httpsURIVarLen + "?length=51",  "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   162
            { httpsURIVarLen + "?length=98",  "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   163
            { httpsURIVarLen + "?length=100", "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   164
            { httpsURIVarLen + "?length=101", "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   165
            { httpsURIVarLen + "?length=104", "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   166
            { httpsURIVarLen + "?length=106", "chunked transfer encoding" },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   167
            { httpsURIVarLen + "?length=110", "chunked transfer encoding" },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   168
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   169
            { httpURIFixLen + "?length=0",   "no bytes"    }, // EOF without receiving anything
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   170
            { httpURIFixLen + "?length=1",   "status line" }, // EOF during status-line
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   171
            { httpURIFixLen + "?length=2",   "status line" },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   172
            { httpURIFixLen + "?length=10",  "status line" },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   173
            { httpURIFixLen + "?length=19",  "header"      }, // EOF during Content-Type header
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   174
            { httpURIFixLen + "?length=30",  "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   175
            { httpURIFixLen + "?length=45",  "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   176
            { httpURIFixLen + "?length=48",  "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   177
            { httpURIFixLen + "?length=51",  "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   178
            { httpURIFixLen + "?length=78",  "header"      }, // EOF during Connection header
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   179
            { httpURIFixLen + "?length=79",  "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   180
            { httpURIFixLen + "?length=86",  "header"      },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   181
            { httpURIFixLen + "?length=104", "fixed content-length" }, // EOF during body
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   182
            { httpURIFixLen + "?length=106", "fixed content-length" },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   183
            { httpURIFixLen + "?length=110", "fixed content-length" },
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   184
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   185
            // ## ADD https fixed
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   186
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   187
            { httpURIClsImed,  "no bytes"},
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   188
            { httpsURIClsImed, "no bytes"},
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   189
        };
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   190
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   191
        List<Object[]> list = new ArrayList<>();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   192
        Arrays.asList(cases).stream()
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   193
                .map(e -> new Object[] {e[0], e[1], true})  // reuse client
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   194
                .forEach(list::add);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   195
        Arrays.asList(cases).stream()
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   196
                .map(e -> new Object[] {e[0], e[1], false}) // do not reuse client
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   197
                .forEach(list::add);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   198
        return list.stream().toArray(Object[][]::new);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   199
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   200
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   201
    static final int ITERATION_COUNT = 3;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   202
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   203
    HttpClient newHttpClient() {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   204
        return HttpClient.newBuilder()
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   205
                .proxy(NO_PROXY)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   206
                .sslContext(sslContext)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   207
                .sslParameters(sslParameters)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   208
                .executor(service)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   209
                .build();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   210
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   211
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   212
    @Test(dataProvider = "uris")
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   213
    void testSynchronousGET(String url, String expectedMsg, boolean sameClient)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   214
        throws Exception
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   215
    {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   216
        out.print("---\n");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   217
        HttpClient client = null;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   218
        for (int i=0; i< ITERATION_COUNT; i++) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   219
            if (!sameClient || client == null)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   220
                client = newHttpClient();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   221
            HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   222
            try {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   223
                HttpResponse<String> response = client.send(request, ofString());
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   224
                String body = response.body();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   225
                out.println(response + ": " + body);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   226
                fail("UNEXPECTED RESPONSE: " + response);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   227
            } catch (IOException ioe) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   228
                out.println("Caught expected exception:" + ioe);
53256
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   229
                assertExpectedMessage(request, ioe, expectedMsg);
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   230
                // synchronous API must have the send method on the stack
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   231
                assertSendMethodOnStack(ioe);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   232
                assertNoConnectionExpiredException(ioe);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   233
            }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   234
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   235
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   236
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   237
    @Test(dataProvider = "uris")
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   238
    void testAsynchronousGET(String url, String expectedMsg, boolean sameClient)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   239
        throws Exception
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   240
    {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   241
        out.print("---\n");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   242
        HttpClient client = null;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   243
        for (int i=0; i< ITERATION_COUNT; i++) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   244
            if (!sameClient || client == null)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   245
                client = newHttpClient();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   246
            HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   247
            try {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   248
                HttpResponse<String> response = client.sendAsync(request, ofString()).get();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   249
                String body = response.body();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   250
                out.println(response + ": " + body);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   251
                fail("UNEXPECTED RESPONSE: " + response);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   252
            } catch (ExecutionException ee) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   253
                if (ee.getCause() instanceof IOException) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   254
                    IOException ioe = (IOException) ee.getCause();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   255
                    out.println("Caught expected exception:" + ioe);
53256
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   256
                    assertExpectedMessage(request, ioe, expectedMsg);
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   257
                    assertNoConnectionExpiredException(ioe);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   258
                } else {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   259
                    throw ee;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   260
                }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   261
            }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   262
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   263
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   264
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   265
    // can be used to prolong request body publication
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   266
    static final class InfiniteInputStream extends InputStream {
50985
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   267
        int count = 0;
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   268
        int k16 = 0;
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   269
        @Override
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   270
        public int read() throws IOException {
50985
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   271
            if (++count == 1) {
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   272
                System.out.println("Start sending 1 byte");
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   273
            }
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   274
            if (count > 16 * 1024) {
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   275
                k16++;
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   276
                System.out.println("... 16K sent.");
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   277
                count = count % (16 * 1024);
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   278
            }
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   279
            if (k16 > 128) {
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   280
                System.out.println("WARNING: InfiniteInputStream: " +
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   281
                        "more than 128 16k buffers generated: returning EOF");
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   282
                return -1;
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   283
            }
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   284
            return 1;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   285
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   286
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   287
        @Override
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   288
        public int read(byte[] buf, int offset, int length) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   289
            //int count = offset;
50985
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   290
            length = Math.max(0, Math.min(buf.length - offset, length));
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   291
            //for (; count < length; count++)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   292
            //    buf[offset++] = 0x01;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   293
            //return count;
50985
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   294
            if (count == 0) {
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   295
                System.out.println("Start sending " + length);
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   296
            } else if (count > 16 * 1024) {
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   297
                k16++;
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   298
                System.out.println("... 16K sent.");
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   299
                count = count % (16 * 1024);
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   300
            }
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   301
            if (k16 > 128) {
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   302
                System.out.println("WARNING: InfiniteInputStream: " +
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   303
                        "more than 128 16k buffers generated: returning EOF");
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   304
                return -1;
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   305
            }
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   306
            count += length;
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   307
            return length;
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   308
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   309
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   310
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   311
    // POST tests are racy in what may be received before writing may cause a
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   312
    // broken pipe or reset exception, before all the received data can be read.
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   313
    // Any message up to, and including, the "expected" error message can occur.
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   314
    // Strictly ordered list, in order of possible occurrence.
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   315
    static final List<String> MSGS_ORDER =
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   316
            List.of("no bytes", "status line", "header");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   317
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   318
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   319
    @Test(dataProvider = "uris")
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   320
    void testSynchronousPOST(String url, String expectedMsg, boolean sameClient)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   321
        throws Exception
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   322
    {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   323
        out.print("---\n");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   324
        HttpClient client = null;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   325
        for (int i=0; i< ITERATION_COUNT; i++) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   326
            if (!sameClient || client == null)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   327
                client = newHttpClient();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   328
            HttpRequest request = HttpRequest.newBuilder(URI.create(url))
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   329
                    .POST(BodyPublishers.ofInputStream(() -> new InfiniteInputStream()))
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   330
                    .build();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   331
            try {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   332
                HttpResponse<String> response = client.send(request, ofString());
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   333
                String body = response.body();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   334
                out.println(response + ": " + body);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   335
                fail("UNEXPECTED RESPONSE: " + response);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   336
            } catch (IOException ioe) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   337
                out.println("Caught expected exception:" + ioe);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   338
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   339
                List<String> expectedMessages = new ArrayList<>();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   340
                expectedMessages.add(expectedMsg);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   341
                MSGS_ORDER.stream().takeWhile(s -> !s.equals(expectedMsg))
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   342
                                   .forEach(expectedMessages::add);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   343
53256
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   344
                assertExpectedMessage(request, ioe, expectedMessages);
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   345
                // synchronous API must have the send method on the stack
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   346
                assertSendMethodOnStack(ioe);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   347
                assertNoConnectionExpiredException(ioe);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   348
            }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   349
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   350
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   351
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   352
    @Test(dataProvider = "uris")
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   353
    void testAsynchronousPOST(String url, String expectedMsg, boolean sameClient)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   354
        throws Exception
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   355
    {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   356
        out.print("---\n");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   357
        HttpClient client = null;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   358
        for (int i=0; i< ITERATION_COUNT; i++) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   359
            if (!sameClient || client == null)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   360
                client = newHttpClient();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   361
            HttpRequest request = HttpRequest.newBuilder(URI.create(url))
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   362
                    .POST(BodyPublishers.ofInputStream(() -> new InfiniteInputStream()))
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   363
                    .build();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   364
            try {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   365
                HttpResponse<String> response = client.sendAsync(request, ofString()).get();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   366
                String body = response.body();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   367
                out.println(response + ": " + body);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   368
                fail("UNEXPECTED RESPONSE: " + response);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   369
            } catch (ExecutionException ee) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   370
                if (ee.getCause() instanceof IOException) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   371
                    IOException ioe = (IOException) ee.getCause();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   372
                    out.println("Caught expected exception:" + ioe);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   373
                    String msg = ioe.getMessage();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   374
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   375
                    List<String> expectedMessages = new ArrayList<>();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   376
                    expectedMessages.add(expectedMsg);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   377
                    MSGS_ORDER.stream().takeWhile(s -> !s.equals(expectedMsg))
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   378
                            .forEach(expectedMessages::add);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   379
53256
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   380
                    assertExpectedMessage(request, ioe, expectedMessages);
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   381
                    assertNoConnectionExpiredException(ioe);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   382
                } else {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   383
                    throw ee;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   384
                }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   385
            }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   386
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   387
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   388
53256
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   389
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   390
    void assertExpectedMessage(HttpRequest request, Throwable t, String expected) {
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   391
        if (request.uri().getScheme().equalsIgnoreCase("https")
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   392
                && (t instanceof SSLHandshakeException)) {
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   393
            // OK
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   394
            out.println("Skipping expected " + t);
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   395
        } else {
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   396
            String msg = t.getMessage();
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   397
            assertTrue(msg.contains(expected),
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   398
                    "exception msg:[" + msg + "]");
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   399
        }
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   400
    }
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   401
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   402
    void assertExpectedMessage(HttpRequest request, Throwable t, List<String> expected) {
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   403
        if (request.uri().getScheme().equalsIgnoreCase("https")
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   404
                && (t instanceof SSLHandshakeException)) {
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   405
            // OK
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   406
            out.println("Skipping expected " + t);
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   407
        } else {
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   408
            String msg = t.getMessage();
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   409
            assertTrue(expected.stream().anyMatch(msg::contains),
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   410
                    "exception msg:[" + msg + "] not in " + Arrays.asList(expected));
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   411
        }
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   412
    }
bd8df96decba 8216498: Confusing and unneeded wrapping of SSLHandshakeException
dfuchs
parents: 52121
diff changeset
   413
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   414
    // Asserts that the "send" method appears in the stack of the given
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   415
    // exception. The synchronous API must contain the send method on the stack.
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   416
    static void assertSendMethodOnStack(IOException ioe) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   417
        final String cn = "jdk.internal.net.http.HttpClientImpl";
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   418
        List<StackTraceElement> list = Stream.of(ioe.getStackTrace())
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   419
                .filter(ste -> ste.getClassName().equals(cn)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   420
                        && ste.getMethodName().equals("send"))
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   421
                .collect(toList());
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   422
        if (list.size() != 1) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   423
            ioe.printStackTrace(out);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   424
            fail(cn + ".send method not found in stack.");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   425
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   426
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   427
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   428
    // Asserts that the implementation-specific ConnectionExpiredException does
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   429
    // NOT appear anywhere in the exception or its causal chain.
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   430
    static void assertNoConnectionExpiredException(IOException ioe) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   431
        Throwable throwable = ioe;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   432
        do {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   433
            String cn = throwable.getClass().getSimpleName();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   434
            if (cn.equals("ConnectionExpiredException")) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   435
                ioe.printStackTrace(out);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   436
                fail("UNEXPECTED ConnectionExpiredException in:[" + ioe + "]");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   437
            }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   438
        } while ((throwable = throwable.getCause()) != null);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   439
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   440
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   441
    // -- infra
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   442
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   443
    /**
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   444
     * A server that, listens on a port, accepts new connections, and can be
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   445
     * closed.
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   446
     */
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   447
    static abstract class Server extends Thread implements AutoCloseable {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   448
        protected final ServerSocket ss;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   449
        protected volatile boolean closed;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   450
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   451
        Server(String name) throws IOException {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   452
            super(name);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   453
            ss = newServerSocket();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   454
            ss.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   455
            this.start();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   456
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   457
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   458
        protected ServerSocket newServerSocket() throws IOException {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   459
            return new ServerSocket();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   460
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   461
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   462
        public int getPort() { return ss.getLocalPort(); }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   463
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   464
        @Override
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   465
        public void close() {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   466
            if (closed)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   467
                return;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   468
            closed = true;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   469
            try {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   470
                ss.close();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   471
            } catch (IOException e) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   472
                throw new UncheckedIOException("Unexpected", e);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   473
            }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   474
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   475
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   476
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   477
    /**
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   478
     * A server that closes the connection immediately, without reading or writing.
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   479
     */
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   480
    static class PlainCloseImmediatelyServer extends Server {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   481
        PlainCloseImmediatelyServer() throws IOException {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   482
            super("PlainCloseImmediatelyServer");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   483
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   484
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   485
        protected PlainCloseImmediatelyServer(String name) throws IOException {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   486
            super(name);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   487
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   488
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   489
        @Override
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   490
        public void run() {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   491
            while (!closed) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   492
                try (Socket s = ss.accept()) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   493
                    if (s instanceof SSLSocket) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   494
                        ((SSLSocket)s).startHandshake();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   495
                    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   496
                    out.println("Server: got connection, closing immediately ");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   497
                } catch (IOException e) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   498
                    if (!closed)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   499
                        throw new UncheckedIOException("Unexpected", e);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   500
                }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   501
            }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   502
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   503
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   504
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   505
    /**
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   506
     * A server that closes the connection immediately, without reading or writing,
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   507
     * after completing the SSL handshake.
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   508
     */
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   509
    static final class SSLCloseImmediatelyServer extends PlainCloseImmediatelyServer {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   510
        SSLCloseImmediatelyServer() throws IOException {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   511
            super("SSLCloseImmediatelyServer");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   512
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   513
        @Override
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   514
        public ServerSocket newServerSocket() throws IOException {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   515
            return SSLServerSocketFactory.getDefault().createServerSocket();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   516
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   517
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   518
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   519
    /**
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   520
     * A server that replies with headers and a, possibly partial, reply, before
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   521
     * closing the connection. The number of bytes of written ( header + body),
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   522
     * is controllable through the "length" query string param in the requested
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   523
     * URI.
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   524
     */
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   525
    static abstract class ReplyingServer extends Server {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   526
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   527
        private final String name;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   528
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   529
        ReplyingServer(String name) throws IOException {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   530
            super(name);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   531
            this.name = name;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   532
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   533
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   534
        abstract String response();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   535
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   536
        @Override
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   537
        public void run() {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   538
            while (!closed) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   539
                try (Socket s = ss.accept()) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   540
                    out.print(name + ": got connection ");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   541
                    InputStream is = s.getInputStream();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   542
                    URI requestMethod = readRequestMethod(is);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   543
                    out.print(requestMethod + " ");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   544
                    URI uriPath = readRequestPath(is);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   545
                    out.println(uriPath);
50985
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   546
                    String headers = readRequestHeaders(is);
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   547
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   548
                    String query = uriPath.getRawQuery();
50985
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   549
                    if (query == null) {
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   550
                        out.println("Request headers: [" + headers + "]");
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   551
                    }
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   552
                    assert query != null : "null query for uriPath: " + uriPath;
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   553
                    String qv = query.split("=")[1];
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   554
                    int len;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   555
                    if (qv.equals("all")) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   556
                        len = response().getBytes(US_ASCII).length;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   557
                    } else {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   558
                        len = Integer.parseInt(query.split("=")[1]);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   559
                    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   560
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   561
                    OutputStream os = s.getOutputStream();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   562
                    out.println(name + ": writing " + len  + " bytes");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   563
                    byte[] responseBytes = response().getBytes(US_ASCII);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   564
                    for (int i = 0; i< len; i++) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   565
                        os.write(responseBytes[i]);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   566
                        os.flush();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   567
                    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   568
                } catch (IOException e) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   569
                    if (!closed)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   570
                        throw new UncheckedIOException("Unexpected", e);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   571
                }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   572
            }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   573
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   574
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   575
        static final byte[] requestEnd = new byte[] { '\r', '\n', '\r', '\n' };
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   576
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   577
        // Read the request method
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   578
        static URI readRequestMethod(InputStream is) throws IOException {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   579
            StringBuilder sb = new StringBuilder();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   580
            int r;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   581
            while ((r = is.read()) != -1 && r != 0x20) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   582
                sb.append((char)r);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   583
            }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   584
            return URI.create(sb.toString());
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   585
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   586
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   587
        // Read the request URI path
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   588
        static URI readRequestPath(InputStream is) throws IOException {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   589
            StringBuilder sb = new StringBuilder();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   590
            int r;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   591
            while ((r = is.read()) != -1 && r != 0x20) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   592
                sb.append((char)r);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   593
            }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   594
            return URI.create(sb.toString());
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   595
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   596
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   597
        // Read until the end of a HTTP request headers
50985
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   598
        static String readRequestHeaders(InputStream is) throws IOException {
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   599
            int requestEndCount = 0, r;
50985
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   600
            StringBuilder sb = new StringBuilder();
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   601
            while ((r = is.read()) != -1) {
50985
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   602
                sb.append((char) r);
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   603
                if (r == requestEnd[requestEndCount]) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   604
                    requestEndCount++;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   605
                    if (requestEndCount == 4) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   606
                        break;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   607
                    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   608
                } else {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   609
                    requestEndCount = 0;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   610
                }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   611
            }
50985
cd41f34e548c 8206001: Enable TLS1.3 by default in Http Client
michaelm
parents: 50681
diff changeset
   612
            return sb.toString();
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   613
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   614
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   615
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   616
    /** A server that issues a, possibly-partial, chunked reply. */
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   617
    static class PlainVariableLengthServer extends ReplyingServer {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   618
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   619
        static final String CHUNKED_RESPONSE_BODY =
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   620
                "6\r\n"+ "<html>\r\n" +
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   621
                "6\r\n"+ "<body>\r\n" +
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   622
                "10\r\n"+ "<h1>Heading</h1>\r\n" +
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   623
                "10\r\n"+ "<p>Some Text</p>\r\n" +
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   624
                "7\r\n"+ "</body>\r\n" +
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   625
                "7\r\n"+ "</html>\r\n" +
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   626
                "0\r\n"+ "\r\n";
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   627
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   628
        static final String RESPONSE_HEADERS =
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   629
                "HTTP/1.1 200 OK\r\n" +
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   630
                "Content-Type: text/html; charset=utf-8\r\n" +
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   631
                "Transfer-Encoding: chunked\r\n" +
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   632
                "Connection: close\r\n\r\n";
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   633
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   634
        static final String RESPONSE = RESPONSE_HEADERS + CHUNKED_RESPONSE_BODY;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   635
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   636
        PlainVariableLengthServer() throws IOException {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   637
            super("PlainVariableLengthServer");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   638
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   639
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   640
        protected PlainVariableLengthServer(String name) throws IOException {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   641
            super(name);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   642
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   643
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   644
        @Override
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   645
        String response( ) { return RESPONSE; }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   646
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   647
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   648
    /** A server that issues a, possibly-partial, chunked reply over SSL. */
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   649
    static final class SSLVariableLengthServer extends PlainVariableLengthServer {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   650
        SSLVariableLengthServer() throws IOException {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   651
            super("SSLVariableLengthServer");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   652
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   653
        @Override
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   654
        public ServerSocket newServerSocket() throws IOException {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   655
            return SSLServerSocketFactory.getDefault().createServerSocket();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   656
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   657
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   658
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   659
    /** A server that issues a fixed-length reply. */
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   660
    static final class FixedLengthServer extends ReplyingServer {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   661
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   662
        static final String RESPONSE_BODY = EXPECTED_RESPONSE_BODY;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   663
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   664
        static final String RESPONSE_HEADERS =
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   665
                "HTTP/1.1 200 OK\r\n" +
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   666
                "Content-Type: text/html; charset=utf-8\r\n" +
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   667
                "Content-Length: " + RESPONSE_BODY.length() + "\r\n" +
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   668
                "Connection: close\r\n\r\n";
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   669
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   670
        static final String RESPONSE = RESPONSE_HEADERS + RESPONSE_BODY;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   671
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   672
        FixedLengthServer() throws IOException {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   673
            super("FixedLengthServer");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   674
        }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   675
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   676
        @Override
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   677
        String response( ) { return RESPONSE; }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   678
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   679
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   680
    static String serverAuthority(Server server) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   681
        return InetAddress.getLoopbackAddress().getHostName() + ":"
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   682
                + server.getPort();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   683
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   684
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   685
    @BeforeTest
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   686
    public void setup() throws Exception {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   687
        sslContext = new SimpleSSLContext().get();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   688
        if (sslContext == null)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   689
            throw new AssertionError("Unexpected null sslContext");
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   690
        SSLContext.setDefault(sslContext);
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   691
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   692
        sslParameters = new SSLParameters();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   693
        sslParameters.setProtocols(new String[] {"TLSv1.2"});
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   694
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   695
        closeImmediatelyServer = new PlainCloseImmediatelyServer();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   696
        httpURIClsImed = "http://" + serverAuthority(closeImmediatelyServer)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   697
                + "/http1/closeImmediately/foo";
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   698
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   699
        closeImmediatelyHttpsServer = new SSLCloseImmediatelyServer();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   700
        httpsURIClsImed = "https://" + serverAuthority(closeImmediatelyHttpsServer)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   701
                + "/https1/closeImmediately/foo";
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   702
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   703
        variableLengthServer = new PlainVariableLengthServer();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   704
        httpURIVarLen = "http://" + serverAuthority(variableLengthServer)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   705
                + "/http1/variable/bar";
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   706
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   707
        variableLengthHttpsServer = new SSLVariableLengthServer();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   708
        httpsURIVarLen = "https://" + serverAuthority(variableLengthHttpsServer)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   709
                + "/https1/variable/bar";
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   710
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   711
        fixedLengthServer = new FixedLengthServer();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   712
        httpURIFixLen = "http://" + serverAuthority(fixedLengthServer)
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   713
                + "/http1/fixed/baz";
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   714
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   715
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   716
    @AfterTest
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   717
    public void teardown() throws Exception {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   718
        closeImmediatelyServer.close();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   719
        closeImmediatelyHttpsServer.close();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   720
        variableLengthServer.close();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   721
        variableLengthHttpsServer.close();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   722
        fixedLengthServer.close();
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   723
    }
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents:
diff changeset
   724
}