src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java
author dfuchs
Tue, 13 Mar 2018 10:21:57 +0000
branchhttp-client-branch
changeset 56282 10cebcd18d47
parent 56271 e1eab097c6d7
child 56299 903ff8ec239d
permissions -rw-r--r--
http-client-branch: verify that dependent actions registered by the user in the CF we return are always executed either in the user thread that joins or asynchronously in the executor.
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
/*
56079
d23b02f37fce http-client-branch: more remaining impl types to internal
chegar
parents: 56074
diff changeset
     2
 * Copyright (c) 2015, 2018, 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
56092
fd85b2bf2b0d http-client-branch: move implementation to jdk.internal.net.http
chegar
parents: 56089
diff changeset
    26
package jdk.internal.net.http;
42460
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 javax.net.ssl.SSLContext;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    29
import javax.net.ssl.SSLParameters;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    30
import java.io.IOException;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    31
import java.lang.System.Logger.Level;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    32
import java.lang.ref.WeakReference;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    33
import java.net.Authenticator;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    34
import java.net.CookieHandler;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    35
import java.net.ProxySelector;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    36
import java.nio.channels.CancelledKeyException;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    37
import java.nio.channels.ClosedChannelException;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    38
import java.nio.channels.SelectableChannel;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    39
import java.nio.channels.SelectionKey;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    40
import java.nio.channels.Selector;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    41
import java.nio.channels.SocketChannel;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    42
import java.security.AccessControlContext;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    43
import java.security.AccessController;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    44
import java.security.NoSuchAlgorithmException;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    45
import java.security.PrivilegedAction;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    46
import java.time.Instant;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    47
import java.time.temporal.ChronoUnit;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    48
import java.util.ArrayList;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    49
import java.util.HashSet;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    50
import java.util.Iterator;
56264
c012b93297b0 http-client-branch: filtering ordering
chegar
parents: 56235
diff changeset
    51
import java.util.LinkedList;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    52
import java.util.List;
56267
fe6f17faa23a http-client-branch: null checking in send[Async]
chegar
parents: 56264
diff changeset
    53
import java.util.Objects;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    54
import java.util.Optional;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    55
import java.util.Set;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    56
import java.util.TreeSet;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    57
import java.util.concurrent.CompletableFuture;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    58
import java.util.concurrent.ExecutionException;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    59
import java.util.concurrent.Executor;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    60
import java.util.concurrent.Executors;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    61
import java.util.concurrent.ThreadFactory;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    62
import java.util.concurrent.atomic.AtomicInteger;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    63
import java.util.concurrent.atomic.AtomicLong;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    64
import java.util.stream.Stream;
56089
42208b2f224e http-client-branch: move to standard package and module name
chegar
parents: 56081
diff changeset
    65
import java.net.http.HttpClient;
42208b2f224e http-client-branch: move to standard package and module name
chegar
parents: 56081
diff changeset
    66
import java.net.http.HttpRequest;
42208b2f224e http-client-branch: move to standard package and module name
chegar
parents: 56081
diff changeset
    67
import java.net.http.HttpResponse;
42208b2f224e http-client-branch: move to standard package and module name
chegar
parents: 56081
diff changeset
    68
import java.net.http.HttpResponse.BodyHandler;
42208b2f224e http-client-branch: move to standard package and module name
chegar
parents: 56081
diff changeset
    69
import java.net.http.HttpResponse.PushPromiseHandler;
42208b2f224e http-client-branch: move to standard package and module name
chegar
parents: 56081
diff changeset
    70
import java.net.http.WebSocket;
56092
fd85b2bf2b0d http-client-branch: move implementation to jdk.internal.net.http
chegar
parents: 56089
diff changeset
    71
import jdk.internal.net.http.common.Log;
fd85b2bf2b0d http-client-branch: move implementation to jdk.internal.net.http
chegar
parents: 56089
diff changeset
    72
import jdk.internal.net.http.common.Pair;
fd85b2bf2b0d http-client-branch: move implementation to jdk.internal.net.http
chegar
parents: 56089
diff changeset
    73
import jdk.internal.net.http.common.Utils;
fd85b2bf2b0d http-client-branch: move implementation to jdk.internal.net.http
chegar
parents: 56089
diff changeset
    74
import jdk.internal.net.http.websocket.BuilderImpl;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    75
import jdk.internal.misc.InnocuousThread;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    76
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    77
/**
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    78
 * Client implementation. Contains all configuration information and also
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    79
 * the selector manager thread which allows async events to be registered
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    80
 * and delivered when they occur. See AsyncEvent.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    81
 */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    82
class HttpClientImpl extends HttpClient {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    83
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    84
    static final boolean DEBUG = Utils.DEBUG;  // Revisit: temporary dev flag.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    85
    static final boolean DEBUGELAPSED = Utils.TESTING || DEBUG;  // Revisit: temporary dev flag.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    86
    static final boolean DEBUGTIMEOUT = false; // Revisit: temporary dev flag.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    87
    final System.Logger  debug = Utils.getDebugLogger(this::dbgString, DEBUG);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    88
    final System.Logger  debugelapsed = Utils.getDebugLogger(this::dbgString, DEBUGELAPSED);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    89
    final System.Logger  debugtimeout = Utils.getDebugLogger(this::dbgString, DEBUGTIMEOUT);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    90
    static final AtomicLong CLIENT_IDS = new AtomicLong();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    91
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    92
    // Define the default factory as a static inner class
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    93
    // that embeds all the necessary logic to avoid
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    94
    // the risk of using a lambda that might keep a reference on the
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    95
    // HttpClient instance from which it was created (helps with
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    96
    // heapdump analysis).
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    97
    private static final class DefaultThreadFactory implements ThreadFactory {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    98
        private final String namePrefix;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
    99
        private final AtomicInteger nextId = new AtomicInteger();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   100
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   101
        DefaultThreadFactory(long clientID) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   102
            namePrefix = "HttpClient-" + clientID + "-Worker-";
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   103
        }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   104
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   105
        @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   106
        public Thread newThread(Runnable r) {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   107
            String name = namePrefix + nextId.getAndIncrement();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   108
            Thread t;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   109
            if (System.getSecurityManager() == null) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   110
                t = new Thread(null, r, name, 0, false);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   111
            } else {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   112
                t = InnocuousThread.newThread(name, r);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   113
            }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   114
            t.setDaemon(true);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   115
            return t;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   116
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   117
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   118
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   119
    private final CookieHandler cookieHandler;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   120
    private final Redirect followRedirects;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   121
    private final Optional<ProxySelector> userProxySelector;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   122
    private final ProxySelector proxySelector;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   123
    private final Authenticator authenticator;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   124
    private final Version version;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   125
    private final ConnectionPool connections;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   126
    private final Executor executor;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   127
    private final boolean isDefaultExecutor;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   128
    // Security parameters
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   129
    private final SSLContext sslContext;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   130
    private final SSLParameters sslParams;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   131
    private final SelectorManager selmgr;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   132
    private final FilterFactory filters;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   133
    private final Http2ClientImpl client2;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   134
    private final long id;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   135
    private final String dbgTag;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   136
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   137
    // This reference is used to keep track of the facade HttpClient
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   138
    // that was returned to the application code.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   139
    // It makes it possible to know when the application no longer
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   140
    // holds any reference to the HttpClient.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   141
    // Unfortunately, this information is not enough to know when
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   142
    // to exit the SelectorManager thread. Because of the asynchronous
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   143
    // nature of the API, we also need to wait until all pending operations
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   144
    // have completed.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   145
    private final WeakReference<HttpClientFacade> facadeRef;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   146
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   147
    // This counter keeps track of the number of operations pending
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   148
    // on the HttpClient. The SelectorManager thread will wait
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   149
    // until there are no longer any pending operations and the
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   150
    // facadeRef is cleared before exiting.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   151
    //
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   152
    // The pendingOperationCount is incremented every time a send/sendAsync
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   153
    // operation is invoked on the HttpClient, and is decremented when
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   154
    // the HttpResponse<T> object is returned to the user.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   155
    // However, at this point, the body may not have been fully read yet.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   156
    // This is the case when the response T is implemented as a streaming
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   157
    // subscriber (such as an InputStream).
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   158
    //
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   159
    // To take care of this issue the pendingOperationCount will additionally
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   160
    // be incremented/decremented in the following cases:
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   161
    //
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   162
    // 1. For HTTP/2  it is incremented when a stream is added to the
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   163
    //    Http2Connection streams map, and decreased when the stream is removed
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   164
    //    from the map. This should also take care of push promises.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   165
    // 2. For WebSocket the count is increased when creating a
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   166
    //    DetachedConnectionChannel for the socket, and decreased
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   167
    //    when the the channel is closed.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   168
    //    In addition, the HttpClient facade is passed to the WebSocket builder,
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   169
    //    (instead of the client implementation delegate).
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   170
    // 3. For HTTP/1.1 the count is incremented before starting to parse the body
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   171
    //    response, and decremented when the parser has reached the end of the
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   172
    //    response body flow.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   173
    //
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   174
    // This should ensure that the selector manager thread remains alive until
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   175
    // the response has been fully received or the web socket is closed.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   176
    private final AtomicLong pendingOperationCount = new AtomicLong();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   177
    private final AtomicLong pendingWebSocketCount = new AtomicLong();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   178
    private final AtomicLong pendingHttpRequestCount = new AtomicLong();
42460
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
    /** A Set of, deadline first, ordered timeout events. */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   181
    private final TreeSet<TimeoutEvent> timeouts;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   182
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   183
    /**
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   184
     * This is a bit tricky:
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   185
     * 1. an HttpClientFacade has a final HttpClientImpl field.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   186
     * 2. an HttpClientImpl has a final WeakReference<HttpClientFacade> field,
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   187
     *    where the referent is the facade created for that instance.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   188
     * 3. We cannot just create the HttpClientFacade in the HttpClientImpl
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   189
     *    constructor, because it would be only weakly referenced and could
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   190
     *    be GC'ed before we can return it.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   191
     * The solution is to use an instance of SingleFacadeFactory which will
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   192
     * allow the caller of new HttpClientImpl(...) to retrieve the facade
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   193
     * after the HttpClientImpl has been created.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   194
     */
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   195
    private static final class SingleFacadeFactory {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   196
        HttpClientFacade facade;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   197
        HttpClientFacade createFacade(HttpClientImpl impl) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   198
            assert facade == null;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   199
            return (facade = new HttpClientFacade(impl));
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   200
        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   201
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   202
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   203
    static HttpClientFacade create(HttpClientBuilderImpl builder) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   204
        SingleFacadeFactory facadeFactory = new SingleFacadeFactory();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   205
        HttpClientImpl impl = new HttpClientImpl(builder, facadeFactory);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   206
        impl.start();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   207
        assert facadeFactory.facade != null;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   208
        assert impl.facadeRef.get() == facadeFactory.facade;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   209
        return facadeFactory.facade;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   210
    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   211
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   212
    private HttpClientImpl(HttpClientBuilderImpl builder,
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   213
                           SingleFacadeFactory facadeFactory) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   214
        id = CLIENT_IDS.incrementAndGet();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   215
        dbgTag = "HttpClientImpl(" + id +")";
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   216
        if (builder.sslContext == null) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   217
            try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   218
                sslContext = SSLContext.getDefault();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   219
            } catch (NoSuchAlgorithmException ex) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   220
                throw new InternalError(ex);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   221
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   222
        } else {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   223
            sslContext = builder.sslContext;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   224
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   225
        Executor ex = builder.executor;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   226
        if (ex == null) {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   227
            ex = Executors.newCachedThreadPool(new DefaultThreadFactory(id));
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   228
            isDefaultExecutor = true;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   229
        } else {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   230
            ex = builder.executor;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   231
            isDefaultExecutor = false;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   232
        }
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   233
        facadeRef = new WeakReference<>(facadeFactory.createFacade(this));
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   234
        client2 = new Http2ClientImpl(this);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   235
        executor = ex;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   236
        cookieHandler = builder.cookieHandler;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   237
        followRedirects = builder.followRedirects == null ?
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   238
                Redirect.NEVER : builder.followRedirects;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   239
        this.userProxySelector = Optional.ofNullable(builder.proxy);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   240
        this.proxySelector = userProxySelector
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   241
                .orElseGet(HttpClientImpl::getDefaultProxySelector);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   242
        debug.log(Level.DEBUG, "proxySelector is %s (user-supplied=%s)",
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   243
                this.proxySelector, userProxySelector.isPresent());
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   244
        authenticator = builder.authenticator;
44854
5a486e0acd29 8175814: Update default HttpClient protocol version and optional request version
michaelm
parents: 44639
diff changeset
   245
        if (builder.version == null) {
5a486e0acd29 8175814: Update default HttpClient protocol version and optional request version
michaelm
parents: 44639
diff changeset
   246
            version = HttpClient.Version.HTTP_2;
5a486e0acd29 8175814: Update default HttpClient protocol version and optional request version
michaelm
parents: 44639
diff changeset
   247
        } else {
5a486e0acd29 8175814: Update default HttpClient protocol version and optional request version
michaelm
parents: 44639
diff changeset
   248
            version = builder.version;
5a486e0acd29 8175814: Update default HttpClient protocol version and optional request version
michaelm
parents: 44639
diff changeset
   249
        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   250
        if (builder.sslParams == null) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   251
            sslParams = getDefaultParams(sslContext);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   252
        } else {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   253
            sslParams = builder.sslParams;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   254
        }
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   255
        connections = new ConnectionPool(id);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   256
        connections.start();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   257
        timeouts = new TreeSet<>();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   258
        try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   259
            selmgr = new SelectorManager(this);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   260
        } catch (IOException e) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   261
            // unlikely
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   262
            throw new InternalError(e);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   263
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   264
        selmgr.setDaemon(true);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   265
        filters = new FilterFactory();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   266
        initFilters();
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   267
        assert facadeRef.get() != null;
42460
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
    private void start() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   271
        selmgr.start();
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
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   274
    // Called from the SelectorManager thread, just before exiting.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   275
    // Clears the HTTP/1.1 and HTTP/2 cache, ensuring that the connections
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   276
    // that may be still lingering there are properly closed (and their
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   277
    // possibly still opened SocketChannel released).
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   278
    private void stop() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   279
        // Clears HTTP/1.1 cache and close its connections
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   280
        connections.stop();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   281
        // Clears HTTP/2 cache and close its connections.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   282
        client2.stop();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   283
    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   284
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   285
    private static SSLParameters getDefaultParams(SSLContext ctx) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   286
        SSLParameters params = ctx.getSupportedSSLParameters();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   287
        params.setProtocols(new String[]{"TLSv1.2"});
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   288
        return params;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   289
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   290
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   291
    private static ProxySelector getDefaultProxySelector() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   292
        PrivilegedAction<ProxySelector> action = ProxySelector::getDefault;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   293
        return AccessController.doPrivileged(action);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   294
    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   295
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   296
    // Returns the facade that was returned to the application code.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   297
    // May be null if that facade is no longer referenced.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   298
    final HttpClientFacade facade() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   299
        return facadeRef.get();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   300
    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   301
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   302
    // Increments the pendingOperationCount.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   303
    final long reference() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   304
        pendingHttpRequestCount.incrementAndGet();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   305
        return pendingOperationCount.incrementAndGet();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   306
    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   307
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   308
    // Decrements the pendingOperationCount.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   309
    final long unreference() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   310
        final long count = pendingOperationCount.decrementAndGet();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   311
        final long httpCount = pendingHttpRequestCount.decrementAndGet();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   312
        final long webSocketCount = pendingWebSocketCount.get();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   313
        if (count == 0 && facade() == null) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   314
            selmgr.wakeupSelector();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   315
        }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   316
        assert httpCount >= 0 : "count of HTTP operations < 0";
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   317
        assert webSocketCount >= 0 : "count of WS operations < 0";
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   318
        assert count >= 0 : "count of pending operations < 0";
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   319
        return count;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   320
    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   321
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   322
    // Increments the pendingOperationCount.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   323
    final long webSocketOpen() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   324
        pendingWebSocketCount.incrementAndGet();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   325
        return pendingOperationCount.incrementAndGet();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   326
    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   327
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   328
    // Decrements the pendingOperationCount.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   329
    final long webSocketClose() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   330
        final long count = pendingOperationCount.decrementAndGet();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   331
        final long webSocketCount = pendingWebSocketCount.decrementAndGet();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   332
        final long httpCount = pendingHttpRequestCount.get();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   333
        if (count == 0 && facade() == null) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   334
            selmgr.wakeupSelector();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   335
        }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   336
        assert httpCount >= 0 : "count of HTTP operations < 0";
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   337
        assert webSocketCount >= 0 : "count of WS operations < 0";
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   338
        assert count >= 0 : "count of pending operations < 0";
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   339
        return count;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   340
    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   341
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   342
    // Returns the pendingOperationCount.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   343
    final long referenceCount() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   344
        return pendingOperationCount.get();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   345
    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   346
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   347
    // Called by the SelectorManager thread to figure out whether it's time
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   348
    // to terminate.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   349
    final boolean isReferenced() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   350
        HttpClient facade = facade();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   351
        return facade != null || referenceCount() > 0;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   352
    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   353
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   354
    /**
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   355
     * Wait for activity on given exchange.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   356
     * The following occurs in the SelectorManager thread.
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   357
     *
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   358
     *  1) add to selector
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   359
     *  2) If selector fires for this exchange then
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   360
     *     call AsyncEvent.handle()
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   361
     *
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   362
     * If exchange needs to change interest ops, then call registerEvent() again.
42460
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
    void registerEvent(AsyncEvent exchange) throws IOException {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   365
        selmgr.register(exchange);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   366
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   367
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   368
    /**
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   369
     * Only used from RawChannel to disconnect the channel from
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   370
     * the selector
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   371
     */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   372
    void cancelRegistration(SocketChannel s) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   373
        selmgr.cancel(s);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   374
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   375
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   376
    /**
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   377
     * Allows an AsyncEvent to modify its interestOps.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   378
     * @param event The modified event.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   379
     */
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   380
    void eventUpdated(AsyncEvent event) throws ClosedChannelException {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   381
        assert !(event instanceof AsyncTriggerEvent);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   382
        selmgr.eventUpdated(event);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   383
    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   384
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   385
    boolean isSelectorThread() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   386
        return Thread.currentThread() == selmgr;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   387
    }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   388
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   389
    Http2ClientImpl client2() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   390
        return client2;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   391
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   392
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   393
    private void debugCompleted(String tag, long startNanos, HttpRequest req) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   394
        if (debugelapsed.isLoggable(Level.DEBUG)) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   395
            debugelapsed.log(Level.DEBUG, () -> tag + " elapsed "
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   396
                    + (System.nanoTime() - startNanos)/1000_000L
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   397
                    + " millis for " + req.method()
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   398
                    + " to " + req.uri());
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   399
        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   400
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   401
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   402
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   403
    public <T> HttpResponse<T>
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   404
    send(HttpRequest req, BodyHandler<T> responseHandler)
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   405
        throws IOException, InterruptedException
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   406
    {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   407
        try {
56267
fe6f17faa23a http-client-branch: null checking in send[Async]
chegar
parents: 56264
diff changeset
   408
            return sendAsync(req, responseHandler, null).get();
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   409
        } catch (ExecutionException e) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   410
            Throwable t = e.getCause();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   411
            if (t instanceof Error)
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   412
                throw (Error)t;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   413
            if (t instanceof RuntimeException)
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   414
                throw (RuntimeException)t;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   415
            else if (t instanceof IOException)
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   416
                throw Utils.getIOException(t);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   417
            else
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   418
                throw new InternalError("Unexpected exception", t);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   419
        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   420
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   421
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   422
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   423
    public <T> CompletableFuture<HttpResponse<T>>
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   424
    sendAsync(HttpRequest userRequest, BodyHandler<T> responseHandler)
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   425
    {
56010
782b2f2d1e76 http-client-branch: updated server push API
michaelm
parents: 55982
diff changeset
   426
        return sendAsync(userRequest, responseHandler, null);
782b2f2d1e76 http-client-branch: updated server push API
michaelm
parents: 55982
diff changeset
   427
    }
782b2f2d1e76 http-client-branch: updated server push API
michaelm
parents: 55982
diff changeset
   428
782b2f2d1e76 http-client-branch: updated server push API
michaelm
parents: 55982
diff changeset
   429
782b2f2d1e76 http-client-branch: updated server push API
michaelm
parents: 55982
diff changeset
   430
    @Override
782b2f2d1e76 http-client-branch: updated server push API
michaelm
parents: 55982
diff changeset
   431
    public <T> CompletableFuture<HttpResponse<T>>
782b2f2d1e76 http-client-branch: updated server push API
michaelm
parents: 55982
diff changeset
   432
    sendAsync(HttpRequest userRequest,
782b2f2d1e76 http-client-branch: updated server push API
michaelm
parents: 55982
diff changeset
   433
              BodyHandler<T> responseHandler,
782b2f2d1e76 http-client-branch: updated server push API
michaelm
parents: 55982
diff changeset
   434
              PushPromiseHandler<T> pushPromiseHandler)
782b2f2d1e76 http-client-branch: updated server push API
michaelm
parents: 55982
diff changeset
   435
    {
56267
fe6f17faa23a http-client-branch: null checking in send[Async]
chegar
parents: 56264
diff changeset
   436
        Objects.requireNonNull(userRequest);
fe6f17faa23a http-client-branch: null checking in send[Async]
chegar
parents: 56264
diff changeset
   437
        Objects.requireNonNull(responseHandler);
fe6f17faa23a http-client-branch: null checking in send[Async]
chegar
parents: 56264
diff changeset
   438
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   439
        AccessControlContext acc = null;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   440
        if (System.getSecurityManager() != null)
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   441
            acc = AccessController.getContext();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   442
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   443
        // Clone the, possibly untrusted, HttpRequest
56235
6218673d7fa0 http-client-branch: 100-Continue 100-Continue
chegar
parents: 56165
diff changeset
   444
        HttpRequestImpl requestImpl = new HttpRequestImpl(userRequest, proxySelector);
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   445
        if (requestImpl.method().equals("CONNECT"))
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   446
            throw new IllegalArgumentException("Unsupported method CONNECT");
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   447
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   448
        long start = DEBUGELAPSED ? System.nanoTime() : 0;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   449
        reference();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   450
        try {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   451
            debugelapsed.log(Level.DEBUG, "ClientImpl (async) send %s", userRequest);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   452
56282
10cebcd18d47 http-client-branch: verify that dependent actions registered by the user in the CF we return are always executed either in the user thread that joins or asynchronously in the executor.
dfuchs
parents: 56271
diff changeset
   453
            Executor executor = acc == null
10cebcd18d47 http-client-branch: verify that dependent actions registered by the user in the CF we return are always executed either in the user thread that joins or asynchronously in the executor.
dfuchs
parents: 56271
diff changeset
   454
                    ? this.executor
10cebcd18d47 http-client-branch: verify that dependent actions registered by the user in the CF we return are always executed either in the user thread that joins or asynchronously in the executor.
dfuchs
parents: 56271
diff changeset
   455
                    : new PrivilegedExecutor(this.executor, acc);
10cebcd18d47 http-client-branch: verify that dependent actions registered by the user in the CF we return are always executed either in the user thread that joins or asynchronously in the executor.
dfuchs
parents: 56271
diff changeset
   456
56010
782b2f2d1e76 http-client-branch: updated server push API
michaelm
parents: 55982
diff changeset
   457
            MultiExchange<T> mex = new MultiExchange<>(userRequest,
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   458
                                                            requestImpl,
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   459
                                                            this,
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   460
                                                            responseHandler,
56010
782b2f2d1e76 http-client-branch: updated server push API
michaelm
parents: 55982
diff changeset
   461
                                                            pushPromiseHandler,
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   462
                                                            acc);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   463
            CompletableFuture<HttpResponse<T>> res =
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   464
                    mex.responseAsync().whenComplete((b,t) -> unreference());
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   465
            if (DEBUGELAPSED) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   466
                res = res.whenComplete(
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   467
                        (b,t) -> debugCompleted("ClientImpl (async)", start, userRequest));
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   468
            }
56282
10cebcd18d47 http-client-branch: verify that dependent actions registered by the user in the CF we return are always executed either in the user thread that joins or asynchronously in the executor.
dfuchs
parents: 56271
diff changeset
   469
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   470
            // makes sure that any dependent actions happen in the executor
56282
10cebcd18d47 http-client-branch: verify that dependent actions registered by the user in the CF we return are always executed either in the user thread that joins or asynchronously in the executor.
dfuchs
parents: 56271
diff changeset
   471
            res = res.whenCompleteAsync((r, t) -> { /* do nothing */}, executor);
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   472
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   473
            return res;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   474
        } catch(Throwable t) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   475
            unreference();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   476
            debugCompleted("ClientImpl (async)", start, userRequest);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   477
            throw t;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   478
        }
42460
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
    // Main loop for this client's selector
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   482
    private final static class SelectorManager extends Thread {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   483
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   484
        // For testing purposes we have an internal System property that
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   485
        // can control the frequency at which the selector manager will wake
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   486
        // up when there are no pending operations.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   487
        // Increasing the frequency (shorter delays) might allow the selector
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   488
        // to observe that the facade is no longer referenced and might allow
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   489
        // the selector thread to terminate more timely - for when nothing is
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   490
        // ongoing it will only check for that condition every NODEADLINE ms.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   491
        // To avoid misuse of the property, the delay that can be specified
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   492
        // is comprised between [MIN_NODEADLINE, MAX_NODEADLINE], and its default
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   493
        // value if unspecified (or <= 0) is DEF_NODEADLINE = 3000ms
56271
e1eab097c6d7 http-client-branch: rename jdk.httpclient.internal.selector.timeout property
chegar
parents: 56267
diff changeset
   494
        // The property is -Djdk.internal.httpclient.selectorTimeout=<millis>
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   495
        private static final int MIN_NODEADLINE = 1000; // ms
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   496
        private static final int MAX_NODEADLINE = 1000 * 1200; // ms
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   497
        private static final int DEF_NODEADLINE = 3000; // ms
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   498
        private static final long NODEADLINE; // default is DEF_NODEADLINE ms
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   499
        static {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   500
            // ensure NODEADLINE is initialized with some valid value.
56271
e1eab097c6d7 http-client-branch: rename jdk.httpclient.internal.selector.timeout property
chegar
parents: 56267
diff changeset
   501
            long deadline =  Utils.getIntegerProperty(
e1eab097c6d7 http-client-branch: rename jdk.httpclient.internal.selector.timeout property
chegar
parents: 56267
diff changeset
   502
                "jdk.internal.httpclient.selectorTimeout",
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   503
                DEF_NODEADLINE); // millis
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   504
            if (deadline <= 0) deadline = DEF_NODEADLINE;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   505
            deadline = Math.max(deadline, MIN_NODEADLINE);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   506
            NODEADLINE = Math.min(deadline, MAX_NODEADLINE);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   507
        }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   508
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   509
        private final Selector selector;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   510
        private volatile boolean closed;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   511
        private final List<AsyncEvent> registrations;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   512
        private final System.Logger debug;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   513
        private final System.Logger debugtimeout;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   514
        HttpClientImpl owner;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   515
        ConnectionPool pool;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   516
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   517
        SelectorManager(HttpClientImpl ref) throws IOException {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   518
            super(null, null, "HttpClient-" + ref.id + "-SelectorManager", 0, false);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   519
            owner = ref;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   520
            debug = ref.debug;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   521
            debugtimeout = ref.debugtimeout;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   522
            pool = ref.connectionPool();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   523
            registrations = new ArrayList<>();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   524
            selector = Selector.open();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   525
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   526
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   527
        void eventUpdated(AsyncEvent e) throws ClosedChannelException {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   528
            if (Thread.currentThread() == this) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   529
                SelectionKey key = e.channel().keyFor(selector);
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   530
                if (key != null && key.isValid()) {
56081
20c6742e5545 http-client-branch: 8196848: SplitResponseSSL test failing intermitently (but rarely) with HttpClientImpl shutting down.
dfuchs
parents: 56079
diff changeset
   531
                    SelectorAttachment sa = (SelectorAttachment) key.attachment();
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   532
                    sa.register(e);
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   533
                } else if (e.interestOps() != 0){
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   534
                    // We don't care about paused events.
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   535
                    // These are actually handled by
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   536
                    // SelectorAttachment::resetInterestOps later on.
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   537
                    // But if we reach here when trying to resume an
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   538
                    // event then it's better to fail fast.
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   539
                    debug.log(Level.DEBUG, "No key for channel");
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   540
                    e.abort(new IOException("No key for channel"));
56081
20c6742e5545 http-client-branch: 8196848: SplitResponseSSL test failing intermitently (but rarely) with HttpClientImpl shutting down.
dfuchs
parents: 56079
diff changeset
   541
                }
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   542
            } else {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   543
                register(e);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   544
            }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   545
        }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   546
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   547
        // This returns immediately. So caller not allowed to send/receive
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   548
        // on connection.
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   549
        synchronized void register(AsyncEvent e) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   550
            registrations.add(e);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   551
            selector.wakeup();
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
        synchronized void cancel(SocketChannel e) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   555
            SelectionKey key = e.keyFor(selector);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   556
            if (key != null) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   557
                key.cancel();
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
            selector.wakeup();
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
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   562
        void wakeupSelector() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   563
            selector.wakeup();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   564
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   565
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   566
        synchronized void shutdown() {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   567
            debug.log(Level.DEBUG, "SelectorManager shutting down");
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   568
            closed = true;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   569
            try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   570
                selector.close();
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   571
            } catch (IOException ignored) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   572
            } finally {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   573
                owner.stop();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   574
            }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   575
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   576
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   577
        @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   578
        public void run() {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   579
            List<Pair<AsyncEvent,IOException>> errorList = new ArrayList<>();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   580
            List<AsyncEvent> readyList = new ArrayList<>();
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   581
            List<Runnable> resetList = new ArrayList<>();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   582
            try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   583
                while (!Thread.currentThread().isInterrupted()) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   584
                    synchronized (this) {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   585
                        assert errorList.isEmpty();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   586
                        assert readyList.isEmpty();
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   587
                        assert resetList.isEmpty();
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   588
                        for (AsyncEvent event : registrations) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   589
                            if (event instanceof AsyncTriggerEvent) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   590
                                readyList.add(event);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   591
                                continue;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   592
                            }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   593
                            SelectableChannel chan = event.channel();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   594
                            SelectionKey key = null;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   595
                            try {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   596
                                key = chan.keyFor(selector);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   597
                                SelectorAttachment sa;
45531
fb3dbffad37b 8180044: java/net/httpclient/ManyRequests.java failed due to timeout
dfuchs
parents: 44854
diff changeset
   598
                                if (key == null || !key.isValid()) {
fb3dbffad37b 8180044: java/net/httpclient/ManyRequests.java failed due to timeout
dfuchs
parents: 44854
diff changeset
   599
                                    if (key != null) {
fb3dbffad37b 8180044: java/net/httpclient/ManyRequests.java failed due to timeout
dfuchs
parents: 44854
diff changeset
   600
                                        // key is canceled.
fb3dbffad37b 8180044: java/net/httpclient/ManyRequests.java failed due to timeout
dfuchs
parents: 44854
diff changeset
   601
                                        // invoke selectNow() to purge it
fb3dbffad37b 8180044: java/net/httpclient/ManyRequests.java failed due to timeout
dfuchs
parents: 44854
diff changeset
   602
                                        // before registering the new event.
fb3dbffad37b 8180044: java/net/httpclient/ManyRequests.java failed due to timeout
dfuchs
parents: 44854
diff changeset
   603
                                        selector.selectNow();
fb3dbffad37b 8180044: java/net/httpclient/ManyRequests.java failed due to timeout
dfuchs
parents: 44854
diff changeset
   604
                                    }
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   605
                                    sa = new SelectorAttachment(chan, selector);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   606
                                } else {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   607
                                    sa = (SelectorAttachment) key.attachment();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   608
                                }
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   609
                                // may throw IOE if channel closed: that's OK
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   610
                                sa.register(event);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   611
                                if (!chan.isOpen()) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   612
                                    throw new IOException("Channel closed");
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   613
                                }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   614
                            } catch (IOException e) {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   615
                                Log.logTrace("HttpClientImpl: " + e);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   616
                                debug.log(Level.DEBUG, () ->
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   617
                                        "Got " + e.getClass().getName()
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   618
                                                 + " while handling"
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   619
                                                 + " registration events");
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   620
                                chan.close();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   621
                                // let the event abort deal with it
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   622
                                errorList.add(new Pair<>(event, e));
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   623
                                if (key != null) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   624
                                    key.cancel();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   625
                                    selector.selectNow();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   626
                                }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   627
                            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   628
                        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   629
                        registrations.clear();
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   630
                        selector.selectedKeys().clear();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   631
                    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   632
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   633
                    for (AsyncEvent event : readyList) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   634
                        assert event instanceof AsyncTriggerEvent;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   635
                        event.handle();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   636
                    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   637
                    readyList.clear();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   638
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   639
                    for (Pair<AsyncEvent,IOException> error : errorList) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   640
                        // an IOException was raised and the channel closed.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   641
                        handleEvent(error.first, error.second);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   642
                    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   643
                    errorList.clear();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   644
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   645
                    // Check whether client is still alive, and if not,
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   646
                    // gracefully stop this thread
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   647
                    if (!owner.isReferenced()) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   648
                        Log.logTrace("HttpClient no longer referenced. Exiting...");
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   649
                        return;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   650
                    }
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   651
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   652
                    // Timeouts will have milliseconds granularity. It is important
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   653
                    // to handle them in a timely fashion.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   654
                    long nextTimeout = owner.purgeTimeoutsAndReturnNextDeadline();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   655
                    debugtimeout.log(Level.DEBUG, "next timeout: %d", nextTimeout);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   656
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   657
                    // Keep-alive have seconds granularity. It's not really an
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   658
                    // issue if we keep connections linger a bit more in the keep
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   659
                    // alive cache.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   660
                    long nextExpiry = pool.purgeExpiredConnectionsAndReturnNextDeadline();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   661
                    debugtimeout.log(Level.DEBUG, "next expired: %d", nextExpiry);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   662
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   663
                    assert nextTimeout >= 0;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   664
                    assert nextExpiry >= 0;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   665
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   666
                    // Don't wait for ever as it might prevent the thread to
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   667
                    // stop gracefully. millis will be 0 if no deadline was found.
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   668
                    if (nextTimeout <= 0) nextTimeout = NODEADLINE;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   669
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   670
                    // Clip nextExpiry at NODEADLINE limit. The default
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   671
                    // keep alive is 1200 seconds (half an hour) - we don't
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   672
                    // want to wait that long.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   673
                    if (nextExpiry <= 0) nextExpiry = NODEADLINE;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   674
                    else nextExpiry = Math.min(NODEADLINE, nextExpiry);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   675
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   676
                    // takes the least of the two.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   677
                    long millis = Math.min(nextExpiry, nextTimeout);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   678
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   679
                    debugtimeout.log(Level.DEBUG, "Next deadline is %d",
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   680
                                     (millis == 0 ? NODEADLINE : millis));
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   681
                    //debugPrint(selector);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   682
                    int n = selector.select(millis == 0 ? NODEADLINE : millis);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   683
                    if (n == 0) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   684
                        // Check whether client is still alive, and if not,
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   685
                        // gracefully stop this thread
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   686
                        if (!owner.isReferenced()) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   687
                            Log.logTrace("HttpClient no longer referenced. Exiting...");
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   688
                            return;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   689
                        }
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   690
                        owner.purgeTimeoutsAndReturnNextDeadline();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   691
                        continue;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   692
                    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   693
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   694
                    Set<SelectionKey> keys = selector.selectedKeys();
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   695
                    assert errorList.isEmpty();
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   696
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   697
                    for (SelectionKey key : keys) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   698
                        SelectorAttachment sa = (SelectorAttachment) key.attachment();
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   699
                        if (!key.isValid()) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   700
                            IOException ex = sa.chan.isOpen()
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   701
                                    ? new IOException("Invalid key")
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   702
                                    : new ClosedChannelException();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   703
                            sa.pending.forEach(e -> errorList.add(new Pair<>(e,ex)));
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   704
                            sa.pending.clear();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   705
                            continue;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   706
                        }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   707
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   708
                        int eventsOccurred;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   709
                        try {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   710
                            eventsOccurred = key.readyOps();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   711
                        } catch (CancelledKeyException ex) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   712
                            IOException io = Utils.getIOException(ex);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   713
                            sa.pending.forEach(e -> errorList.add(new Pair<>(e,io)));
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   714
                            sa.pending.clear();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   715
                            continue;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   716
                        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   717
                        sa.events(eventsOccurred).forEach(readyList::add);
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   718
                        resetList.add(() -> sa.resetInterestOps(eventsOccurred));
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   719
                    }
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   720
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   721
                    selector.selectNow(); // complete cancellation
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   722
                    selector.selectedKeys().clear();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   723
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   724
                    // handle selected events
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   725
                    readyList.forEach((e) -> handleEvent(e, null));
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   726
                    readyList.clear();
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   727
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   728
                    // handle errors (closed channels etc...)
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   729
                    errorList.forEach((p) -> handleEvent(p.first, p.second));
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   730
                    errorList.clear();
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   731
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   732
                    // reset interest ops for selected channels
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   733
                    resetList.forEach(r -> r.run());
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   734
                    resetList.clear();
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   735
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   736
                }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   737
            } catch (Throwable e) {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   738
                //e.printStackTrace();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   739
                if (!closed) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   740
                    // This terminates thread. So, better just print stack trace
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   741
                    String err = Utils.stackTrace(e);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   742
                    Log.logError("HttpClientImpl: fatal error: " + err);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   743
                }
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   744
                debug.log(Level.DEBUG, "shutting down", e);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   745
                if (Utils.ASSERTIONSENABLED && !debug.isLoggable(Level.DEBUG)) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   746
                    e.printStackTrace(System.err); // always print the stack
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   747
                }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   748
            } finally {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   749
                shutdown();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   750
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   751
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   752
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   753
//        void debugPrint(Selector selector) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   754
//            System.err.println("Selector: debugprint start");
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   755
//            Set<SelectionKey> keys = selector.keys();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   756
//            for (SelectionKey key : keys) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   757
//                SelectableChannel c = key.channel();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   758
//                int ops = key.interestOps();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   759
//                System.err.printf("selector chan:%s ops:%d\n", c, ops);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   760
//            }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   761
//            System.err.println("Selector: debugprint end");
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   762
//        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   763
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   764
        /** Handles the given event. The given ioe may be null. */
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   765
        void handleEvent(AsyncEvent event, IOException ioe) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   766
            if (closed || ioe != null) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   767
                event.abort(ioe);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   768
            } else {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   769
                event.handle();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   770
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   771
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   772
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   773
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   774
    final String debugInterestOps(SelectableChannel channel) {
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   775
        try {
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   776
            SelectionKey key = channel.keyFor(selmgr.selector);
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   777
            if (key == null) return "channel not registered with selector";
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   778
            String keyInterestOps = key.isValid()
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   779
                    ? "key.interestOps=" + key.interestOps() : "invalid key";
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   780
            return String.format("channel registered with selector, %s, sa.interestOps=%s",
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   781
                                 keyInterestOps,
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   782
                                 ((SelectorAttachment)key.attachment()).interestOps);
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   783
        } catch (Throwable t) {
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   784
            return String.valueOf(t);
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   785
        }
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   786
    }
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   787
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   788
    /**
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   789
     * Tracks multiple user level registrations associated with one NIO
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   790
     * registration (SelectionKey). In this implementation, registrations
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   791
     * are one-off and when an event is posted the registration is cancelled
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   792
     * until explicitly registered again.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   793
     *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   794
     * <p> No external synchronization required as this class is only used
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   795
     * by the SelectorManager thread. One of these objects required per
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   796
     * connection.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   797
     */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   798
    private static class SelectorAttachment {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   799
        private final SelectableChannel chan;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   800
        private final Selector selector;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   801
        private final Set<AsyncEvent> pending;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   802
        private final static System.Logger debug =
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   803
                Utils.getDebugLogger("SelectorAttachment"::toString, DEBUG);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   804
        private int interestOps;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   805
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   806
        SelectorAttachment(SelectableChannel chan, Selector selector) {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   807
            this.pending = new HashSet<>();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   808
            this.chan = chan;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   809
            this.selector = selector;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   810
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   811
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   812
        void register(AsyncEvent e) throws ClosedChannelException {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   813
            int newOps = e.interestOps();
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   814
            // re register interest if we are not already interested
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   815
            // in the event. If the event is paused, then the pause will
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   816
            // be taken into account later when resetInterestOps is called.
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   817
            boolean reRegister = (interestOps & newOps) != newOps;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   818
            interestOps |= newOps;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   819
            pending.add(e);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   820
            if (reRegister) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   821
                // first time registration happens here also
56081
20c6742e5545 http-client-branch: 8196848: SplitResponseSSL test failing intermitently (but rarely) with HttpClientImpl shutting down.
dfuchs
parents: 56079
diff changeset
   822
                try {
20c6742e5545 http-client-branch: 8196848: SplitResponseSSL test failing intermitently (but rarely) with HttpClientImpl shutting down.
dfuchs
parents: 56079
diff changeset
   823
                    chan.register(selector, interestOps, this);
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   824
                } catch (Throwable x) {
56081
20c6742e5545 http-client-branch: 8196848: SplitResponseSSL test failing intermitently (but rarely) with HttpClientImpl shutting down.
dfuchs
parents: 56079
diff changeset
   825
                    abortPending(x);
20c6742e5545 http-client-branch: 8196848: SplitResponseSSL test failing intermitently (but rarely) with HttpClientImpl shutting down.
dfuchs
parents: 56079
diff changeset
   826
                }
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   827
            } else if (!chan.isOpen()) {
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   828
                abortPending(new ClosedChannelException());
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   829
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   830
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   831
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   832
        /**
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   833
         * Returns a Stream<AsyncEvents> containing only events that are
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   834
         * registered with the given {@code interestOps}.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   835
         */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   836
        Stream<AsyncEvent> events(int interestOps) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   837
            return pending.stream()
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   838
                    .filter(ev -> (ev.interestOps() & interestOps) != 0);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   839
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   840
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   841
        /**
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   842
         * Removes any events with the given {@code interestOps}, and if no
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   843
         * events remaining, cancels the associated SelectionKey.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   844
         */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   845
        void resetInterestOps(int interestOps) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   846
            int newOps = 0;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   847
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   848
            Iterator<AsyncEvent> itr = pending.iterator();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   849
            while (itr.hasNext()) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   850
                AsyncEvent event = itr.next();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   851
                int evops = event.interestOps();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   852
                if (event.repeating()) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   853
                    newOps |= evops;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   854
                    continue;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   855
                }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   856
                if ((evops & interestOps) != 0) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   857
                    itr.remove();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   858
                } else {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   859
                    newOps |= evops;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   860
                }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   861
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   862
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   863
            this.interestOps = newOps;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   864
            SelectionKey key = chan.keyFor(selector);
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   865
            if (newOps == 0 && key != null && pending.isEmpty()) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   866
                key.cancel();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   867
            } else {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   868
                try {
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   869
                    if (key == null || !key.isValid()) {
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   870
                        throw new CancelledKeyException();
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   871
                    }
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   872
                    key.interestOps(newOps);
56165
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   873
                    // double check after
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   874
                    if (!chan.isOpen()) {
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   875
                        abortPending(new ClosedChannelException());
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   876
                        return;
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   877
                    }
8a6065d830b9 http-client-branch: Add a test for BodySubscribers throwing in getBody() or returning exceptionally completed CFs
dfuchs
parents: 56092
diff changeset
   878
                    assert key.interestOps() == newOps;
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   879
                } catch (CancelledKeyException x) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   880
                    // channel may have been closed
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   881
                    debug.log(Level.DEBUG, "key cancelled for " + chan);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   882
                    abortPending(x);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   883
                }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   884
            }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   885
        }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   886
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   887
        void abortPending(Throwable x) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   888
            if (!pending.isEmpty()) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   889
                AsyncEvent[] evts = pending.toArray(new AsyncEvent[0]);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   890
                pending.clear();
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   891
                IOException io = Utils.getIOException(x);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   892
                for (AsyncEvent event : evts) {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   893
                    event.abort(io);
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   894
                }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   895
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   896
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   897
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   898
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   899
    /*package-private*/ SSLContext theSSLContext() {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   900
        return sslContext;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   901
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   902
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   903
    @Override
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   904
    public SSLContext sslContext() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   905
        return sslContext;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   906
    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   907
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   908
    @Override
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   909
    public SSLParameters sslParameters() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   910
        return Utils.copySSLParameters(sslParams);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   911
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   912
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   913
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   914
    public Optional<Authenticator> authenticator() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   915
        return Optional.ofNullable(authenticator);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   916
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   917
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   918
    /*package-private*/ final Executor theExecutor() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   919
        return executor;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   920
    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   921
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   922
    @Override
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   923
    public final Optional<Executor> executor() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   924
        return isDefaultExecutor ? Optional.empty() : Optional.of(executor);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   925
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   926
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   927
    ConnectionPool connectionPool() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   928
        return connections;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   929
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   930
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   931
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   932
    public Redirect followRedirects() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   933
        return followRedirects;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   934
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   935
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   936
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   937
    @Override
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   938
    public Optional<CookieHandler> cookieHandler() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   939
        return Optional.ofNullable(cookieHandler);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   940
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   941
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   942
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   943
    public Optional<ProxySelector> proxy() {
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   944
        return this.userProxySelector;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   945
    }
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   946
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   947
    // Return the effective proxy that this client uses.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   948
    ProxySelector proxySelector() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   949
        return proxySelector;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   950
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   951
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   952
    @Override
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   953
    public WebSocket.Builder newWebSocketBuilder() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   954
        // Make sure to pass the HttpClientFacade to the WebSocket builder.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   955
        // This will ensure that the facade is not released before the
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   956
        // WebSocket has been created, at which point the pendingOperationCount
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   957
        // will have been incremented by the DetachedConnectionChannel
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   958
        // (see PlainHttpConnection.detachChannel())
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   959
        return new BuilderImpl(this.facade(), proxySelector);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   960
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   961
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   962
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   963
    public Version version() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   964
        return version;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   965
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   966
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   967
    String dbgString() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   968
        return dbgTag;
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   969
    }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   970
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   971
    @Override
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   972
    public String toString() {
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   973
        // Used by tests to get the client's id and compute the
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   974
        // name of the SelectorManager thread.
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   975
        return super.toString() + ("(" + id + ")");
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   976
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   977
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   978
    private void initFilters() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   979
        addFilter(AuthenticationFilter.class);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   980
        addFilter(RedirectFilter.class);
48083
b1c1b4ef4be2 8191494: Refresh incubating HTTP Client
chegar
parents: 47216
diff changeset
   981
        if (this.cookieHandler != null) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   982
            addFilter(CookieFilter.class);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   983
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   984
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   985
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   986
    private void addFilter(Class<? extends HeaderFilter> f) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   987
        filters.addFilter(f);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   988
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   989
56264
c012b93297b0 http-client-branch: filtering ordering
chegar
parents: 56235
diff changeset
   990
    final LinkedList<HeaderFilter> filterChain() {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   991
        return filters.getFilterChain();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   992
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   993
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   994
    // Timer controls.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   995
    // Timers are implemented through timed Selector.select() calls.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   996
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   997
    synchronized void registerTimer(TimeoutEvent event) {
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
   998
        Log.logTrace("Registering timer {0}", event);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   999
        timeouts.add(event);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1000
        selmgr.wakeupSelector();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1001
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1002
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1003
    synchronized void cancelTimer(TimeoutEvent event) {
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1004
        Log.logTrace("Canceling timer {0}", event);
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1005
        timeouts.remove(event);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1006
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1007
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1008
    /**
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1009
     * Purges ( handles ) timer events that have passed their deadline, and
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1010
     * returns the amount of time, in milliseconds, until the next earliest
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1011
     * event. A return value of 0 means that there are no events.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1012
     */
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1013
    private long purgeTimeoutsAndReturnNextDeadline() {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1014
        long diff = 0L;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1015
        List<TimeoutEvent> toHandle = null;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1016
        int remaining = 0;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1017
        // enter critical section to retrieve the timeout event to handle
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1018
        synchronized(this) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1019
            if (timeouts.isEmpty()) return 0L;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1020
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1021
            Instant now = Instant.now();
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1022
            Iterator<TimeoutEvent> itr = timeouts.iterator();
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1023
            while (itr.hasNext()) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1024
                TimeoutEvent event = itr.next();
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1025
                diff = now.until(event.deadline(), ChronoUnit.MILLIS);
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1026
                if (diff <= 0) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1027
                    itr.remove();
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1028
                    toHandle = (toHandle == null) ? new ArrayList<>() : toHandle;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1029
                    toHandle.add(event);
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1030
                } else {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1031
                    break;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1032
                }
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1033
            }
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1034
            remaining = timeouts.size();
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1035
        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1036
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1037
        // can be useful for debugging
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1038
        if (toHandle != null && Log.trace()) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1039
            Log.logTrace("purgeTimeoutsAndReturnNextDeadline: handling "
56074
06459c34105f http-client-branch: remove redundant null check
chegar
parents: 56010
diff changeset
  1040
                    +  toHandle.size() + " events, "
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1041
                    + "remaining " + remaining
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1042
                    + ", next deadline: " + (diff < 0 ? 0L : diff));
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1043
        }
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1044
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1045
        // handle timeout events out of critical section
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1046
        if (toHandle != null) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1047
            Throwable failed = null;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1048
            for (TimeoutEvent event : toHandle) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1049
                try {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1050
                   Log.logTrace("Firing timer {0}", event);
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1051
                   event.handle();
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1052
                } catch (Error | RuntimeException e) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1053
                    // Not expected. Handle remaining events then throw...
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1054
                    // If e is an OOME or SOE it might simply trigger a new
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1055
                    // error from here - but in this case there's not much we
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1056
                    // could do anyway. Just let it flow...
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1057
                    if (failed == null) failed = e;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1058
                    else failed.addSuppressed(e);
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1059
                    Log.logTrace("Failed to handle event {0}: {1}", event, e);
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1060
                }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1061
            }
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1062
            if (failed instanceof Error) throw (Error) failed;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1063
            if (failed instanceof RuntimeException) throw (RuntimeException) failed;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1064
        }
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1065
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1066
        // return time to wait until next event. 0L if there's no more events.
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1067
        return diff < 0 ? 0L : diff;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1068
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1069
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1070
    // used for the connection window
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1071
    int getReceiveBufferSize() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1072
        return Utils.getIntegerNetProperty(
48263
a559b7cd1dea 8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents: 48083
diff changeset
  1073
                "jdk.httpclient.receiveBufferSize", 2 * 1024 * 1024
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1074
        );
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1075
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1076
}