test/jdk/java/net/httpclient/http2/ServerPushWithDiffTypes.java
author jjiang
Mon, 15 Oct 2018 22:47:03 +0800
changeset 52121 934969c63223
parent 50681 4254bed3c09d
permissions -rw-r--r--
8211978: Move testlibrary/jdk/testlibrary/SimpleSSLContext.java and testkeys to network testlibrary Summary: Move SimpleSSLContext.java and testkeys to test/lib/jdk/test/lib/net Reviewed-by: chegar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
49765
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
     1
/*
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
     2
 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
     4
 *
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
     7
 * published by the Free Software Foundation.
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
     8
 *
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    13
 * accompanied this code).
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    14
 *
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    18
 *
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    21
 * questions.
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    22
 */
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    23
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    24
/*
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    25
 * @test
52121
934969c63223 8211978: Move testlibrary/jdk/testlibrary/SimpleSSLContext.java and testkeys to network testlibrary
jjiang
parents: 50681
diff changeset
    26
 * @library /test/lib server
934969c63223 8211978: Move testlibrary/jdk/testlibrary/SimpleSSLContext.java and testkeys to network testlibrary
jjiang
parents: 50681
diff changeset
    27
 * @build jdk.test.lib.net.SimpleSSLContext
49765
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    28
 * @modules java.base/sun.net.www.http
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    29
 *          java.net.http/jdk.internal.net.http.common
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    30
 *          java.net.http/jdk.internal.net.http.frame
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    31
 *          java.net.http/jdk.internal.net.http.hpack
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    32
 * @run testng/othervm
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    33
 *       -Djdk.internal.httpclient.debug=true
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    34
 *       -Djdk.httpclient.HttpClient.log=errors,requests,responses
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    35
 *       ServerPushWithDiffTypes
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    36
 */
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    37
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    38
import java.io.*;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    39
import java.net.*;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    40
import java.nio.ByteBuffer;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    41
import java.nio.file.*;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    42
import java.net.http.*;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    43
import java.net.http.HttpResponse.BodyHandler;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    44
import java.net.http.HttpResponse.PushPromiseHandler;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    45
import java.net.http.HttpResponse.BodySubscriber;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    46
import java.net.http.HttpResponse.BodySubscribers;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    47
import java.util.*;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    48
import java.util.concurrent.*;
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents: 49765
diff changeset
    49
import java.util.function.BiPredicate;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents: 49765
diff changeset
    50
49765
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    51
import org.testng.annotations.Test;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    52
import static java.nio.charset.StandardCharsets.UTF_8;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    53
import static org.testng.Assert.assertEquals;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    54
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    55
public class ServerPushWithDiffTypes {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    56
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    57
    static Map<String,String> PUSH_PROMISES = Map.of(
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    58
            "/x/y/z/1", "the first push promise body",
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    59
            "/x/y/z/2", "the second push promise body",
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    60
            "/x/y/z/3", "the third push promise body",
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    61
            "/x/y/z/4", "the fourth push promise body",
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    62
            "/x/y/z/5", "the fifth push promise body",
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    63
            "/x/y/z/6", "the sixth push promise body",
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    64
            "/x/y/z/7", "the seventh push promise body",
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    65
            "/x/y/z/8", "the eighth push promise body",
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    66
            "/x/y/z/9", "the ninth push promise body"
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    67
    );
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    68
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    69
    @Test
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    70
    public static void test() throws Exception {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    71
        Http2TestServer server = null;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    72
        try {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    73
            server = new Http2TestServer(false, 0);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    74
            Http2Handler handler =
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    75
                    new ServerPushHandler("the main response body",
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    76
                                          PUSH_PROMISES);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    77
            server.addHandler(handler, "/");
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    78
            server.start();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    79
            int port = server.getAddress().getPort();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    80
            System.err.println("Server listening on port " + port);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    81
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    82
            HttpClient client = HttpClient.newHttpClient();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    83
            // use multi-level path
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    84
            URI uri = new URI("http://localhost:" + port + "/foo/a/b/c");
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    85
            HttpRequest request = HttpRequest.newBuilder(uri).GET().build();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    86
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    87
            ConcurrentMap<HttpRequest,CompletableFuture<HttpResponse<BodyAndType<?>>>>
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    88
                    results = new ConcurrentHashMap<>();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    89
            PushPromiseHandler<BodyAndType<?>> bh = PushPromiseHandler.of(
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    90
                    (pushRequest) -> new BodyAndTypeHandler(pushRequest), results);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    91
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    92
            CompletableFuture<HttpResponse<BodyAndType<?>>> cf =
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    93
                    client.sendAsync(request, new BodyAndTypeHandler(request), bh);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    94
            results.put(request, cf);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    95
            cf.join();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    96
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    97
            assertEquals(results.size(), PUSH_PROMISES.size() + 1);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    98
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
    99
            for (HttpRequest r : results.keySet()) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   100
                URI u = r.uri();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   101
                BodyAndType<?> body = results.get(r).get().body();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   102
                String result;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   103
                // convert all body types to String for easier comparison
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   104
                if (body.type() == String.class) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   105
                    result = (String)body.getBody();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   106
                } else if (body.type() == byte[].class) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   107
                    byte[] bytes = (byte[])body.getBody();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   108
                    result = new String(bytes, UTF_8);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   109
                } else if (Path.class.isAssignableFrom(body.type())) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   110
                    Path path = (Path)body.getBody();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   111
                    result = new String(Files.readAllBytes(path), UTF_8);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   112
                } else {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   113
                    throw new AssertionError("Unknown:" + body.type());
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   114
                }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   115
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   116
                System.err.printf("%s -> %s\n", u.toString(), result.toString());
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   117
                String expected = PUSH_PROMISES.get(r.uri().getPath());
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   118
                if (expected == null)
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   119
                    expected = "the main response body";
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   120
                assertEquals(result, expected);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   121
            }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   122
        } finally {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   123
            server.stop();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   124
        }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   125
    }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   126
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   127
    interface BodyAndType<T> {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   128
        Class<T> type();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   129
        T getBody();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   130
    }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   131
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   132
    static final Path WORK_DIR = Paths.get(".");
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   133
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   134
    static class BodyAndTypeHandler implements BodyHandler<BodyAndType<?>> {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   135
        int count;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   136
        final HttpRequest request;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   137
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   138
        BodyAndTypeHandler(HttpRequest request) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   139
            this.request = request;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   140
        }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   141
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   142
        @Override
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   143
        public HttpResponse.BodySubscriber<BodyAndType<?>> apply(HttpResponse.ResponseInfo info) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   144
            int whichType = count++ % 3;  // real world may base this on the request metadata
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   145
            switch (whichType) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   146
                case 0: // String
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   147
                    return new BodyAndTypeSubscriber(BodySubscribers.ofString(UTF_8));
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   148
                case 1: // byte[]
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   149
                    return new BodyAndTypeSubscriber(BodySubscribers.ofByteArray());
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   150
                case 2: // Path
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   151
                    URI u = request.uri();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   152
                    Path path = Paths.get(WORK_DIR.toString(), u.getPath());
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   153
                    try {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   154
                        Files.createDirectories(path.getParent());
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   155
                    } catch (IOException ee) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   156
                        throw new UncheckedIOException(ee);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   157
                    }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   158
                    return new BodyAndTypeSubscriber(BodySubscribers.ofFile(path));
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   159
                default:
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   160
                    throw new AssertionError("Unexpected " + whichType);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   161
            }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   162
        }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   163
    }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   164
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   165
    static class BodyAndTypeSubscriber<T>
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   166
        implements HttpResponse.BodySubscriber<BodyAndType<T>>
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   167
    {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   168
        private static class BodyAndTypeImpl<T> implements BodyAndType<T> {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   169
            private final Class<T> type;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   170
            private final T body;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   171
            public BodyAndTypeImpl(Class<T> type, T body) { this.type = type; this.body = body; }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   172
            @Override public Class<T> type() { return type; }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   173
            @Override public T getBody() { return body; }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   174
        }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   175
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   176
        private final BodySubscriber<?> bodySubscriber;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   177
        private final CompletableFuture<BodyAndType<T>> cf;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   178
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   179
        BodyAndTypeSubscriber(BodySubscriber bodySubscriber) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   180
            this.bodySubscriber = bodySubscriber;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   181
            cf = new CompletableFuture<>();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   182
            bodySubscriber.getBody().whenComplete(
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   183
                    (r,t) -> cf.complete(new BodyAndTypeImpl(r.getClass(), r)));
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   184
        }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   185
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   186
        @Override
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   187
        public void onSubscribe(Flow.Subscription subscription) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   188
            bodySubscriber.onSubscribe(subscription);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   189
        }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   190
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   191
        @Override
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   192
        public void onNext(List<ByteBuffer> item) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   193
            bodySubscriber.onNext(item);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   194
        }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   195
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   196
        @Override
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   197
        public void onError(Throwable throwable) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   198
            bodySubscriber.onError(throwable);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   199
            cf.completeExceptionally(throwable);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   200
        }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   201
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   202
        @Override
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   203
        public void onComplete() {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   204
            bodySubscriber.onComplete();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   205
        }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   206
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   207
        @Override
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   208
        public CompletionStage<BodyAndType<T>> getBody() {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   209
            return cf;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   210
        }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   211
    }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   212
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   213
    // --- server push handler ---
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   214
    static class ServerPushHandler implements Http2Handler {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   215
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   216
        private final String mainResponseBody;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   217
        private final Map<String,String> promises;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   218
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   219
        public ServerPushHandler(String mainResponseBody,
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   220
                                 Map<String,String> promises)
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   221
            throws Exception
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   222
        {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   223
            Objects.requireNonNull(promises);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   224
            this.mainResponseBody = mainResponseBody;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   225
            this.promises = promises;
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   226
        }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   227
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   228
        public void handle(Http2TestExchange exchange) throws IOException {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   229
            System.err.println("Server: handle " + exchange);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   230
            try (InputStream is = exchange.getRequestBody()) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   231
                is.readAllBytes();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   232
            }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   233
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   234
            if (exchange.serverPushAllowed()) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   235
                pushPromises(exchange);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   236
            }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   237
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   238
            // response data for the main response
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   239
            try (OutputStream os = exchange.getResponseBody()) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   240
                byte[] bytes = mainResponseBody.getBytes(UTF_8);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   241
                exchange.sendResponseHeaders(200, bytes.length);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   242
                os.write(bytes);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   243
            }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   244
        }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   245
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents: 49765
diff changeset
   246
        static final BiPredicate<String,String> ACCEPT_ALL = (x, y) -> true;
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents: 49765
diff changeset
   247
49765
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   248
        private void pushPromises(Http2TestExchange exchange) throws IOException {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   249
            URI requestURI = exchange.getRequestURI();
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   250
            for (Map.Entry<String,String> promise : promises.entrySet()) {
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   251
                URI uri = requestURI.resolve(promise.getKey());
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   252
                InputStream is = new ByteArrayInputStream(promise.getValue().getBytes(UTF_8));
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents: 49765
diff changeset
   253
                Map<String,List<String>> map = Map.of("X-Promise", List.of(promise.getKey()));
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents: 49765
diff changeset
   254
                HttpHeaders headers = HttpHeaders.of(map, ACCEPT_ALL);
49765
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   255
                // TODO: add some check on headers, maybe
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   256
                exchange.serverPush(uri, headers, is);
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   257
            }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   258
            System.err.println("Server: All pushes sent");
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   259
        }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   260
    }
ee6f7a61f3a5 8197564: HTTP Client implementation
chegar
parents:
diff changeset
   261
}