src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/WebSocketImpl.java
author prappo
Thu, 23 Nov 2017 18:52:22 +0300
branchhttp-client-branch
changeset 55863 04c2bb7a1693
parent 55862 faa39b5ec8e1
child 55867 1b8734a5c696
permissions -rw-r--r--
http-client-branch: (WebSocket) cleanup
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     1
/*
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
     2
 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     4
 *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    10
 *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    15
 * accompanied this code).
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    16
 *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    20
 *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    23
 * questions.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    24
 */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    25
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    26
package jdk.incubator.http.internal.websocket;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    27
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    28
import java.io.IOException;
55789
b3562d42f3b1 http-client-impl: use Reference.reachabilityFence to make clear the websokect BuilderImpl must stay strongly referenced until after the WebSocketImpl is created.
dfuchs
parents: 55768
diff changeset
    29
import java.lang.ref.Reference;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    30
import java.net.ProtocolException;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    31
import java.net.URI;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    32
import java.nio.ByteBuffer;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    33
import java.util.Queue;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    34
import java.util.concurrent.CompletableFuture;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    35
import java.util.concurrent.CompletionStage;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    36
import java.util.concurrent.ConcurrentLinkedQueue;
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
    37
import java.util.concurrent.TimeUnit;
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
    38
import java.util.concurrent.TimeoutException;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    39
import java.util.concurrent.atomic.AtomicBoolean;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    40
import java.util.function.Consumer;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    41
import java.util.function.Function;
55764
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
    42
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    43
import jdk.incubator.http.WebSocket;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    44
import jdk.incubator.http.internal.common.Log;
55768
8674257c75ce http-client-branch: SSLTube should call onSubscribe in the flow
dfuchs
parents: 55764
diff changeset
    45
import jdk.incubator.http.internal.common.MinimalFuture;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    46
import jdk.incubator.http.internal.common.Pair;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    47
import jdk.incubator.http.internal.common.SequentialScheduler;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    48
import jdk.incubator.http.internal.common.SequentialScheduler.DeferredCompleter;
55764
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
    49
import jdk.incubator.http.internal.common.Utils;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    50
import jdk.incubator.http.internal.websocket.OpeningHandshake.Result;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    51
import jdk.incubator.http.internal.websocket.OutgoingMessage.Binary;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    52
import jdk.incubator.http.internal.websocket.OutgoingMessage.Close;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    53
import jdk.incubator.http.internal.websocket.OutgoingMessage.Context;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    54
import jdk.incubator.http.internal.websocket.OutgoingMessage.Ping;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    55
import jdk.incubator.http.internal.websocket.OutgoingMessage.Pong;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    56
import jdk.incubator.http.internal.websocket.OutgoingMessage.Text;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    57
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    58
import static java.util.Objects.requireNonNull;
55850
1e2fa7c503c1 http-client-branch: (WebSocket) CompletableFuture -> MinimalFuture
prappo
parents: 55842
diff changeset
    59
import static jdk.incubator.http.internal.common.MinimalFuture.failedFuture;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    60
import static jdk.incubator.http.internal.common.Pair.pair;
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
    61
import static jdk.incubator.http.internal.websocket.StatusCodes.CLOSED_ABNORMALLY;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    62
import static jdk.incubator.http.internal.websocket.StatusCodes.NO_STATUS_CODE;
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
    63
import static jdk.incubator.http.internal.websocket.StatusCodes.isLegalToSendFromClient;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    64
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    65
/*
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    66
 * A WebSocket client.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    67
 */
55862
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
    68
public final class WebSocketImpl implements WebSocket {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    69
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    70
    private final URI uri;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    71
    private final String subprotocol;
55853
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
    72
    private final RawChannel channel; /* Stored to call close() on */
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    73
    private final Listener listener;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    74
55862
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
    75
    private volatile boolean inputClosed;
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
    76
    private volatile boolean outputClosed;
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
    77
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    78
    /*
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    79
     * Whether or not Listener.onClose or Listener.onError has been already
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    80
     * invoked. We keep track of this since only one of these methods is invoked
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    81
     * and it is invoked at most once.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    82
     */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    83
    private boolean lastMethodInvoked;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    84
    private final AtomicBoolean outstandingSend = new AtomicBoolean();
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    85
    private final SequentialScheduler sendScheduler;
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
    86
    private final Queue<Pair<OutgoingMessage, CompletableFuture<WebSocket>>>
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
    87
            queue = new ConcurrentLinkedQueue<>();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    88
    private final Context context = new OutgoingMessage.Context();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    89
    private final Transmitter transmitter;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    90
    private final Receiver receiver;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    91
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    92
    /*
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    93
     * Whether or not the WebSocket has been closed. When a WebSocket has been
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    94
     * closed it means that no further messages can be sent or received.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    95
     * A closure can be triggered by:
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    96
     *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    97
     *   1. abort()
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    98
     *   2. "Failing the WebSocket Connection" (i.e. a fatal error)
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    99
     *   3. Completion of the Closing handshake
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   100
     */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   101
    private final AtomicBoolean closed = new AtomicBoolean();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   102
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   103
    /*
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   104
     * This lock is enforcing sequential ordering of invocations to listener's
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   105
     * methods. It is supposed to be uncontended. The only contention that can
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   106
     * happen is when onOpen, an asynchronous onError (not related to reading
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   107
     * from the channel, e.g. an error from automatic Pong reply) or onClose
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   108
     * (related to abort) happens. Since all of the above are one-shot actions,
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   109
     * the said contention is insignificant.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   110
     */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   111
    private final Object lock = new Object();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   112
55853
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
   113
    private final CompletableFuture<?> channelInputClosed = new MinimalFuture<>();
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
   114
    private final CompletableFuture<?> channelOutputClosed = new MinimalFuture<>();
55838
12a64276cc96 http-client-branch: (WebSocket) builder change
prappo
parents: 55826
diff changeset
   115
55862
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   116
    public static CompletableFuture<WebSocket> newInstanceAsync(BuilderImpl b) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   117
        Function<Result, WebSocket> newWebSocket = r -> {
55826
66b5d6013d85 http-client-branch: (WebSocket) the builder is immutable now
prappo
parents: 55824
diff changeset
   118
            WebSocketImpl ws = new WebSocketImpl(b.getUri(),
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   119
                                                 r.subprotocol,
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   120
                                                 r.channel,
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   121
                                                 b.getListener());
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   122
            // The order of calls might cause a subtle effects, like CF will be
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   123
            // returned from the buildAsync _after_ onOpen has been signalled.
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   124
            // This means if onOpen is lengthy, it might cause some problems.
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   125
            ws.signalOpen();
55789
b3562d42f3b1 http-client-impl: use Reference.reachabilityFence to make clear the websokect BuilderImpl must stay strongly referenced until after the WebSocketImpl is created.
dfuchs
parents: 55768
diff changeset
   126
            // make sure we don't release the builder until this lambda
b3562d42f3b1 http-client-impl: use Reference.reachabilityFence to make clear the websokect BuilderImpl must stay strongly referenced until after the WebSocketImpl is created.
dfuchs
parents: 55768
diff changeset
   127
            // has been executed. The builder has a strong reference to
b3562d42f3b1 http-client-impl: use Reference.reachabilityFence to make clear the websokect BuilderImpl must stay strongly referenced until after the WebSocketImpl is created.
dfuchs
parents: 55768
diff changeset
   128
            // the HttpClientFacade, and we want to keep that live until
b3562d42f3b1 http-client-impl: use Reference.reachabilityFence to make clear the websokect BuilderImpl must stay strongly referenced until after the WebSocketImpl is created.
dfuchs
parents: 55768
diff changeset
   129
            // after the raw channel is created and passed to WebSocketImpl.
b3562d42f3b1 http-client-impl: use Reference.reachabilityFence to make clear the websokect BuilderImpl must stay strongly referenced until after the WebSocketImpl is created.
dfuchs
parents: 55768
diff changeset
   130
            Reference.reachabilityFence(b);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   131
            return ws;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   132
        };
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   133
        OpeningHandshake h;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   134
        try {
55853
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
   135
            h = new OpeningHandshake(b);
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
   136
        } catch (Exception e) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   137
            return failedFuture(e);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   138
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   139
        return h.send().thenApply(newWebSocket);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   140
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   141
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   142
    WebSocketImpl(URI uri,
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   143
                  String subprotocol,
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   144
                  RawChannel channel,
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   145
                  Listener listener)
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   146
    {
55862
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   147
        this(uri,
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   148
             subprotocol,
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   149
             channel,
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   150
             listener,
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   151
             new Transmitter(channel));
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   152
    }
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   153
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   154
    /* Exposed for testing purposes */
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   155
    WebSocketImpl(URI uri,
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   156
                  String subprotocol,
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   157
                  RawChannel channel,
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   158
                  Listener listener,
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   159
                  Transmitter transmitter)
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   160
    {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   161
        this.uri = requireNonNull(uri);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   162
        this.subprotocol = requireNonNull(subprotocol);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   163
        this.channel = requireNonNull(channel);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   164
        this.listener = requireNonNull(listener);
55862
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   165
        this.transmitter = transmitter;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   166
        this.receiver = new Receiver(messageConsumerOf(listener), channel);
55853
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
   167
        this.sendScheduler = new SequentialScheduler(new SendTask());
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   168
55853
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
   169
        // Set up automatic channel closing action
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
   170
        CompletableFuture.allOf(channelInputClosed, channelOutputClosed)
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   171
                .whenComplete((result, error) -> {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   172
                    try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   173
                        channel.close();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   174
                    } catch (IOException e) {
43730
b6847c320451 8174745: Httpclient source update for JDK 8
michaelm
parents: 42460
diff changeset
   175
                        Log.logError(e);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   176
                    } finally {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   177
                        closed.set(true);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   178
                    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   179
                });
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   180
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   181
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   182
    /*
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   183
     * This initialisation is outside of the constructor for the sake of
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   184
     * safe publication.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   185
     */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   186
    private void signalOpen() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   187
        synchronized (lock) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   188
            // TODO: might hold lock longer than needed causing prolonged
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   189
            // contention? substitute lock for ConcurrentLinkedQueue<Runnable>?
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   190
            try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   191
                listener.onOpen(this);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   192
            } catch (Exception e) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   193
                signalError(e);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   194
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   195
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   196
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   197
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   198
    private void signalError(Throwable error) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   199
        synchronized (lock) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   200
            if (lastMethodInvoked) {
43730
b6847c320451 8174745: Httpclient source update for JDK 8
michaelm
parents: 42460
diff changeset
   201
                Log.logError(error);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   202
            } else {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   203
                lastMethodInvoked = true;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   204
                receiver.close();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   205
                try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   206
                    listener.onError(this, error);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   207
                } catch (Exception e) {
43730
b6847c320451 8174745: Httpclient source update for JDK 8
michaelm
parents: 42460
diff changeset
   208
                    Log.logError(e);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   209
                }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   210
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   211
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   212
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   213
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   214
    /*
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   215
     * Processes a Close event that came from the channel. Invoked at most once.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   216
     */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   217
    private void processClose(int statusCode, String reason) {
55862
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   218
        inputClosed = true;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   219
        receiver.close();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   220
        try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   221
            channel.shutdownInput();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   222
        } catch (IOException e) {
43730
b6847c320451 8174745: Httpclient source update for JDK 8
michaelm
parents: 42460
diff changeset
   223
            Log.logError(e);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   224
        }
55853
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
   225
        boolean alreadyCompleted = !channelInputClosed.complete(null);
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   226
        if (alreadyCompleted) {
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   227
            // This CF is supposed to be completed only once, the first time a
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   228
            // Close message is received. No further messages are pulled from
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   229
            // the socket.
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   230
            throw new InternalError();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   231
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   232
        int code;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   233
        if (statusCode == NO_STATUS_CODE || statusCode == CLOSED_ABNORMALLY) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   234
            code = NORMAL_CLOSURE;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   235
        } else {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   236
            code = statusCode;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   237
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   238
        CompletionStage<?> readyToClose = signalClose(statusCode, reason);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   239
        if (readyToClose == null) {
55850
1e2fa7c503c1 http-client-branch: (WebSocket) CompletableFuture -> MinimalFuture
prappo
parents: 55842
diff changeset
   240
            readyToClose = MinimalFuture.completedFuture(null);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   241
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   242
        readyToClose.whenComplete((r, error) -> {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   243
            enqueueClose(new Close(code, ""))
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   244
                    .whenComplete((r1, error1) -> {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   245
                        if (error1 != null) {
43730
b6847c320451 8174745: Httpclient source update for JDK 8
michaelm
parents: 42460
diff changeset
   246
                            Log.logError(error1);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   247
                        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   248
                    });
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   249
        });
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   250
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   251
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   252
    /*
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   253
     * Signals a Close event (might not correspond to anything happened on the
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   254
     * channel, e.g. `abort()`).
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   255
     */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   256
    private CompletionStage<?> signalClose(int statusCode, String reason) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   257
        synchronized (lock) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   258
            if (lastMethodInvoked) {
43730
b6847c320451 8174745: Httpclient source update for JDK 8
michaelm
parents: 42460
diff changeset
   259
                Log.logTrace("Close: {0}, ''{1}''", statusCode, reason);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   260
            } else {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   261
                lastMethodInvoked = true;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   262
                receiver.close();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   263
                try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   264
                    return listener.onClose(this, statusCode, reason);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   265
                } catch (Exception e) {
43730
b6847c320451 8174745: Httpclient source update for JDK 8
michaelm
parents: 42460
diff changeset
   266
                    Log.logError(e);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   267
                }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   268
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   269
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   270
        return null;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   271
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   272
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   273
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   274
    public CompletableFuture<WebSocket> sendText(CharSequence message,
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   275
                                                 boolean isLast)
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   276
    {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   277
        return enqueueExclusively(new Text(message, isLast));
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   278
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   279
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   280
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   281
    public CompletableFuture<WebSocket> sendBinary(ByteBuffer message,
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   282
                                                   boolean isLast)
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   283
    {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   284
        return enqueueExclusively(new Binary(message, isLast));
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   285
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   286
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   287
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   288
    public CompletableFuture<WebSocket> sendPing(ByteBuffer message) {
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   289
        return enqueue(new Ping(message));
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   290
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   291
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   292
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   293
    public CompletableFuture<WebSocket> sendPong(ByteBuffer message) {
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   294
        return enqueue(new Pong(message));
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   295
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   296
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   297
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   298
    public CompletableFuture<WebSocket> sendClose(int statusCode,
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   299
                                                  String reason) {
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   300
        if (!isLegalToSendFromClient(statusCode)) {
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   301
            return failedFuture(
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   302
                    new IllegalArgumentException("statusCode: " + statusCode));
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   303
        }
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   304
        Close msg;
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   305
        try {
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   306
            msg = new Close(statusCode, reason);
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   307
        } catch (IllegalArgumentException e) {
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   308
            return failedFuture(e);
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   309
        }
55853
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
   310
        outputClosed = true;
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   311
        return enqueueClose(msg);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   312
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   313
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   314
    /*
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   315
     * Sends a Close message and then shuts down the channel for writing since
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   316
     * no more messages are expected to be sent after this.
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   317
     */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   318
    private CompletableFuture<WebSocket> enqueueClose(Close m) {
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   319
        return enqueue(m)
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   320
                .orTimeout(60, TimeUnit.SECONDS)
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   321
                .whenComplete((r, error) -> {
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   322
                    if (error instanceof TimeoutException) {
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   323
                        try {
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   324
                            channel.close();
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   325
                        } catch (IOException e) {
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   326
                            Log.logError(e);
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   327
                        }
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   328
                    } else {
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   329
                        try {
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   330
                            channel.shutdownOutput();
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   331
                        } catch (IOException e) {
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   332
                            Log.logError(e);
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   333
                        }
55853
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
   334
                        channelOutputClosed.complete(null);
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   335
                    }
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   336
                });
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   337
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   338
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   339
    /*
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   340
     * Accepts the given message into the outgoing queue in a mutually-exclusive
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   341
     * fashion in respect to other messages accepted through this method. No
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   342
     * further messages will be accepted until the returned CompletableFuture
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   343
     * completes. This method is used to enforce "one outstanding send
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   344
     * operation" policy.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   345
     */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   346
    private CompletableFuture<WebSocket> enqueueExclusively(OutgoingMessage m)
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   347
    {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   348
        if (!outstandingSend.compareAndSet(false, true)) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   349
            return failedFuture(new IllegalStateException("Outstanding send"));
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   350
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   351
        return enqueue(m).whenComplete((r, e) -> outstandingSend.set(false));
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   352
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   353
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   354
    private CompletableFuture<WebSocket> enqueue(OutgoingMessage m) {
55768
8674257c75ce http-client-branch: SSLTube should call onSubscribe in the flow
dfuchs
parents: 55764
diff changeset
   355
        CompletableFuture<WebSocket> cf = new MinimalFuture<>();
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   356
        boolean added = queue.add(pair(m, cf));
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   357
        if (!added) {
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   358
            // The queue is supposed to be unbounded
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   359
            throw new InternalError();
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   360
        }
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   361
        sendScheduler.runOrSchedule();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   362
        return cf;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   363
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   364
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   365
    /*
55853
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
   366
     * This is a message sending task. It pulls messages from the queue one by
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
   367
     * one and sends them. It may be run in different threads, but never
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
   368
     * concurrently.
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   369
     */
55853
937985fc3c45 http-client-branch: (WebSocket) moving http proxy-related code to OpeningHandshake
prappo
parents: 55850
diff changeset
   370
    private class SendTask implements SequentialScheduler.RestartableTask {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   371
        @Override
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   372
        public void run(DeferredCompleter taskCompleter) {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   373
            Pair<OutgoingMessage, CompletableFuture<WebSocket>> p = queue.poll();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   374
            if (p == null) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   375
                taskCompleter.complete();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   376
                return;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   377
            }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   378
            OutgoingMessage message = p.first;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   379
            CompletableFuture<WebSocket> cf = p.second;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   380
            try {
55862
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   381
                if (!message.contextualize(context)) { // Do not send the message
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   382
                    cf.complete(null);
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   383
                    repeat(taskCompleter);
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   384
                    return;
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   385
                }
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   386
                Consumer<Exception> h = e -> {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   387
                    if (e == null) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   388
                        cf.complete(WebSocketImpl.this);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   389
                    } else {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   390
                        cf.completeExceptionally(e);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   391
                    }
55862
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   392
                    repeat(taskCompleter);
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   393
                };
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   394
                transmitter.send(message, h);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   395
            } catch (Exception t) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   396
                cf.completeExceptionally(t);
55862
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   397
                repeat(taskCompleter);
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   398
            }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   399
        }
55862
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   400
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   401
        private void repeat(DeferredCompleter taskCompleter) {
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   402
            taskCompleter.complete();
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   403
            // More than a single message may have been enqueued while
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   404
            // the task has been busy with the current message, but
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   405
            // there is only a single signal recorded
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   406
            sendScheduler.runOrSchedule();
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   407
        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   408
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   409
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   410
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   411
    public void request(long n) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   412
        receiver.request(n);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   413
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   414
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   415
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   416
    public String getSubprotocol() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   417
        return subprotocol;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   418
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   419
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   420
    @Override
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   421
    public boolean isOutputClosed() {
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   422
        return outputClosed;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   423
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   424
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   425
    @Override
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   426
    public boolean isInputClosed() {
55862
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   427
        return inputClosed;
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   428
    }
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   429
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   430
    @Override
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   431
    public void abort() {
55862
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   432
        inputClosed = true;
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   433
        outputClosed = true;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   434
        try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   435
            channel.close();
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   436
        } catch (IOException ignored) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   437
        } finally {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   438
            closed.set(true);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   439
            signalClose(CLOSED_ABNORMALLY, "");
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   440
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   441
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   442
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   443
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   444
    public String toString() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   445
        return super.toString()
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   446
                + "[" + (closed.get() ? "CLOSED" : "OPEN") + "]: " + uri
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   447
                + (!subprotocol.isEmpty() ? ", subprotocol=" + subprotocol : "");
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   448
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   449
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   450
    private MessageStreamConsumer messageConsumerOf(Listener listener) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   451
        // Synchronization performed here in every method is not for the sake of
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   452
        // ordering invocations to this consumer, after all they are naturally
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   453
        // ordered in the channel. The reason is to avoid an interference with
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   454
        // any unrelated to the channel calls to onOpen, onClose and onError.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   455
        return new MessageStreamConsumer() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   456
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   457
            @Override
55863
04c2bb7a1693 http-client-branch: (WebSocket) cleanup
prappo
parents: 55862
diff changeset
   458
            public void onText(CharSequence data, MessagePart part) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   459
                receiver.acknowledge();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   460
                synchronized (WebSocketImpl.this.lock) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   461
                    try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   462
                        listener.onText(WebSocketImpl.this, data, part);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   463
                    } catch (Exception e) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   464
                        signalError(e);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   465
                    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   466
                }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   467
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   468
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   469
            @Override
55863
04c2bb7a1693 http-client-branch: (WebSocket) cleanup
prappo
parents: 55862
diff changeset
   470
            public void onBinary(ByteBuffer data, MessagePart part) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   471
                receiver.acknowledge();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   472
                synchronized (WebSocketImpl.this.lock) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   473
                    try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   474
                        listener.onBinary(WebSocketImpl.this, data.slice(), part);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   475
                    } catch (Exception e) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   476
                        signalError(e);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   477
                    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   478
                }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   479
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   480
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   481
            @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   482
            public void onPing(ByteBuffer data) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   483
                receiver.acknowledge();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   484
                // Let's make a full copy of this tiny data. What we want here
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   485
                // is to rule out a possibility the shared data we send might be
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   486
                // corrupted the by processing in the listener.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   487
                ByteBuffer slice = data.slice();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   488
                ByteBuffer copy = ByteBuffer.allocate(data.remaining())
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   489
                        .put(data)
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   490
                        .flip();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   491
                // Non-exclusive send;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   492
                CompletableFuture<WebSocket> pongSent = enqueue(new Pong(copy));
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   493
                pongSent.whenComplete(
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   494
                        (r, error) -> {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   495
                            if (error != null) {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   496
                                WebSocketImpl.this.signalError(
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   497
                                        Utils.getCompletionCause(error));
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   498
                            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   499
                        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   500
                );
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   501
                synchronized (WebSocketImpl.this.lock) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   502
                    try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   503
                        listener.onPing(WebSocketImpl.this, slice);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   504
                    } catch (Exception e) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   505
                        signalError(e);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   506
                    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   507
                }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   508
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   509
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   510
            @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   511
            public void onPong(ByteBuffer data) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   512
                receiver.acknowledge();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   513
                synchronized (WebSocketImpl.this.lock) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   514
                    try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   515
                        listener.onPong(WebSocketImpl.this, data.slice());
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   516
                    } catch (Exception e) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   517
                        signalError(e);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   518
                    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   519
                }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   520
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   521
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   522
            @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   523
            public void onClose(int statusCode, CharSequence reason) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   524
                receiver.acknowledge();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   525
                processClose(statusCode, reason.toString());
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   526
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   527
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   528
            @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   529
            public void onError(Exception error) {
55862
faa39b5ec8e1 http-client-branch: (WebSocket) testing sending messages
prappo
parents: 55853
diff changeset
   530
                inputClosed = true;
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   531
                outputClosed = true;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   532
                if (!(error instanceof FailWebSocketException)) {
55842
cb8fcde5b5c8 http-client-branch: (WebSocket) API update
prappo
parents: 55838
diff changeset
   533
                    abort();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   534
                    signalError(error);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   535
                } else {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   536
                    Exception ex = (Exception) new ProtocolException().initCause(error);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   537
                    int code = ((FailWebSocketException) error).getStatusCode();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   538
                    enqueueClose(new Close(code, ""))
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   539
                            .whenComplete((r, e) -> {
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   540
                                if (e != null) {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   541
                                    ex.addSuppressed(Utils.getCompletionCause(e));
45119
decbbff9fdb4 8179021: Latest bugfixes to WebSocket/HPACK from the sandbox repo
prappo
parents: 43730
diff changeset
   542
                                }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   543
                                try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   544
                                    channel.close();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   545
                                } catch (IOException e1) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   546
                                    ex.addSuppressed(e1);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   547
                                } finally {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   548
                                    closed.set(true);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   549
                                }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   550
                                signalError(ex);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   551
                            });
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   552
                }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   553
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   554
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   555
            @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   556
            public void onComplete() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   557
                processClose(CLOSED_ABNORMALLY, "");
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   558
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   559
        };
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   560
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   561
}