src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClientImpl.java
author dfuchs
Thu, 16 Nov 2017 19:56:44 +0000
branchhttp-client-branch
changeset 55821 fa0fc03c0853
parent 55816 70738768515a
child 55838 12a64276cc96
permissions -rw-r--r--
http-client-branch: HttpClient uses ProxySelector.getDefault() by default
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
/*
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
     2
 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     4
 *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    10
 *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    15
 * accompanied this code).
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    16
 *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    20
 *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    23
 * questions.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    24
 */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    25
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    26
package jdk.incubator.http;
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;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
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;
55812
0a3a307f3502 http-client-branch: CookieManager -> CookieHandler
chegar
parents: 55792
diff changeset
    34
import java.net.CookieHandler;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    35
import java.net.NetPermission;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    36
import java.net.ProxySelector;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    37
import java.net.URI;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    38
import java.nio.channels.CancelledKeyException;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    39
import java.nio.channels.ClosedChannelException;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    40
import java.nio.channels.SelectableChannel;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    41
import java.nio.channels.SelectionKey;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    42
import java.nio.channels.Selector;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    43
import java.nio.channels.SocketChannel;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    44
import java.security.AccessControlContext;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    45
import java.security.AccessController;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    46
import java.security.NoSuchAlgorithmException;
55821
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
    47
import java.security.PrivilegedAction;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    48
import java.time.Instant;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    49
import java.time.temporal.ChronoUnit;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    50
import java.util.ArrayList;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    51
import java.util.HashSet;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    52
import java.util.Iterator;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    53
import java.util.List;
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;
55816
70738768515a http-client-branch: spec clarifications and minor fix to sendXXX methods
chegar
parents: 55815
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;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    62
import java.util.concurrent.atomic.AtomicInteger;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
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;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    65
import jdk.incubator.http.HttpResponse.BodyHandler;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    66
import jdk.incubator.http.HttpResponse.MultiSubscriber;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    67
import jdk.incubator.http.internal.common.Log;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    68
import jdk.incubator.http.internal.common.Pair;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    69
import jdk.incubator.http.internal.common.Utils;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    70
import jdk.incubator.http.internal.websocket.BuilderImpl;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    71
import jdk.internal.misc.InnocuousThread;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    72
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    73
/**
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    74
 * 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
    75
 * 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
    76
 * 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
    77
 */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    78
class HttpClientImpl extends HttpClient {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    79
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    80
    static final boolean DEBUG = Utils.DEBUG;  // Revisit: temporary dev flag.
55781
16e7156053f5 http-client-branch: fixed activation of debug traces
dfuchs
parents: 55764
diff changeset
    81
    static final boolean DEBUGELAPSED = Utils.TESTING || DEBUG;  // Revisit: temporary dev flag.
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    82
    static final boolean DEBUGTIMEOUT = false; // Revisit: temporary dev flag.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    83
    final System.Logger  debug = Utils.getDebugLogger(this::dbgString, DEBUG);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    84
    final System.Logger  debugelapsed = Utils.getDebugLogger(this::dbgString, DEBUGELAPSED);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    85
    final System.Logger  debugtimeout = Utils.getDebugLogger(this::dbgString, DEBUGTIMEOUT);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    86
    static final AtomicLong CLIENT_IDS = new AtomicLong();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    87
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    88
    // 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
    89
    // 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
    90
    // 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
    91
    // 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
    92
    // heapdump analysis).
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
    93
    private static final class DefaultThreadFactory implements ThreadFactory {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    94
        private final String namePrefix;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    95
        private final AtomicInteger nextId = new AtomicInteger();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    96
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    97
        DefaultThreadFactory(long clientID) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    98
            namePrefix = "HttpClient-" + clientID + "-Worker-";
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
    99
        }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   100
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   101
        @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   102
        public Thread newThread(Runnable r) {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   103
            String name = namePrefix + nextId.getAndIncrement();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   104
            Thread t;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   105
            if (System.getSecurityManager() == null) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   106
                t = new Thread(null, r, name, 0, false);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   107
            } else {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   108
                t = InnocuousThread.newThread(name, r);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   109
            }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   110
            t.setDaemon(true);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   111
            return t;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   112
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   113
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   114
55812
0a3a307f3502 http-client-branch: CookieManager -> CookieHandler
chegar
parents: 55792
diff changeset
   115
    private final CookieHandler cookieHandler;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   116
    private final Redirect followRedirects;
55821
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   117
    private final Optional<ProxySelector> userProxySelector;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   118
    private final ProxySelector proxySelector;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   119
    private final Authenticator authenticator;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   120
    private final Version version;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   121
    private final ConnectionPool connections;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   122
    private final Executor executor;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   123
    private final boolean isDefaultExecutor;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   124
    // Security parameters
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   125
    private final SSLContext sslContext;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   126
    private final SSLParameters sslParams;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   127
    private final SelectorManager selmgr;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   128
    private final FilterFactory filters;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   129
    private final Http2ClientImpl client2;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   130
    private final long id;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   131
    private final String dbgTag;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   132
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   133
    // This reference is used to keep track of the facade HttpClient
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   134
    // that was returned to the application code.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   135
    // It makes it possible to know when the application no longer
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   136
    // holds any reference to the HttpClient.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   137
    // Unfortunately, this information is not enough to know when
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   138
    // to exit the SelectorManager thread. Because of the asynchronous
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   139
    // nature of the API, we also need to wait until all pending operations
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   140
    // have completed.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   141
    private final WeakReference<HttpClientFacade> facadeRef;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   142
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   143
    // This counter keeps track of the number of operations pending
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   144
    // on the HttpClient. The SelectorManager thread will wait
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   145
    // until there are no longer any pending operations and the
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   146
    // facadeRef is cleared before exiting.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   147
    //
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   148
    // The pendingOperationCount is incremented every time a send/sendAsync
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   149
    // operation is invoked on the HttpClient, and is decremented when
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   150
    // the HttpResponse<T> object is returned to the user.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   151
    // However, at this point, the body may not have been fully read yet.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   152
    // This is the case when the response T is implemented as a streaming
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   153
    // subscriber (such as an InputStream).
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   154
    //
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   155
    // To take care of this issue the pendingOperationCount will additionally
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   156
    // be incremented/decremented in the following cases:
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   157
    //
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   158
    // 1. For HTTP/2  it is incremented when a stream is added to the
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   159
    //    Http2Connection streams map, and decreased when the stream is removed
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   160
    //    from the map. This should also take care of push promises.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   161
    // 2. For WebSocket the count is increased when creating a
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   162
    //    DetachedConnectionChannel for the socket, and decreased
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   163
    //    when the the channel is closed.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   164
    //    In addition, the HttpClient facade is passed to the WebSocket builder,
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   165
    //    (instead of the client implementation delegate).
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   166
    // 3. For HTTP/1.1 the count is incremented before starting to parse the body
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   167
    //    response, and decremented when the parser has reached the end of the
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   168
    //    response body flow.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   169
    //
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   170
    // This should ensure that the selector manager thread remains alive until
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   171
    // the response has been fully received or the web socket is closed.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   172
    private final AtomicLong pendingOperationCount = new AtomicLong();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   173
    private final AtomicLong pendingWebSocketCount = new AtomicLong();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   174
    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
   175
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   176
    /** 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
   177
    private final TreeSet<TimeoutEvent> timeouts;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   178
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   179
    /**
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   180
     * This is a bit tricky:
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   181
     * 1. an HttpClientFacade has a final HttpClientImpl field.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   182
     * 2. an HttpClientImpl has a final WeakReference<HttpClientFacade> field,
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   183
     *    where the referent is the facade created for that instance.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   184
     * 3. We cannot just create the HttpClientFacade in the HttpClientImpl
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   185
     *    constructor, because it would be only weakly referenced and could
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   186
     *    be GC'ed before we can return it.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   187
     * The solution is to use an instance of SingleFacadeFactory which will
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   188
     * allow the caller of new HttpClientImpl(...) to retrieve the facade
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   189
     * after the HttpClientImpl has been created.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   190
     */
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   191
    private static final class SingleFacadeFactory {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   192
        HttpClientFacade facade;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   193
        HttpClientFacade createFacade(HttpClientImpl impl) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   194
            assert facade == null;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   195
            return (facade = new HttpClientFacade(impl));
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   196
        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   197
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   198
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   199
    static HttpClientFacade create(HttpClientBuilderImpl builder) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   200
        SingleFacadeFactory facadeFactory = new SingleFacadeFactory();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   201
        HttpClientImpl impl = new HttpClientImpl(builder, facadeFactory);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   202
        impl.start();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   203
        assert facadeFactory.facade != null;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   204
        assert impl.facadeRef.get() == facadeFactory.facade;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   205
        return facadeFactory.facade;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   206
    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   207
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   208
    private HttpClientImpl(HttpClientBuilderImpl builder,
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   209
                           SingleFacadeFactory facadeFactory) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   210
        id = CLIENT_IDS.incrementAndGet();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   211
        dbgTag = "HttpClientImpl(" + id +")";
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   212
        if (builder.sslContext == null) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   213
            try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   214
                sslContext = SSLContext.getDefault();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   215
            } catch (NoSuchAlgorithmException ex) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   216
                throw new InternalError(ex);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   217
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   218
        } else {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   219
            sslContext = builder.sslContext;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   220
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   221
        Executor ex = builder.executor;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   222
        if (ex == null) {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   223
            ex = Executors.newCachedThreadPool(new DefaultThreadFactory(id));
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   224
            isDefaultExecutor = true;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   225
        } else {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   226
            ex = builder.executor;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   227
            isDefaultExecutor = false;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   228
        }
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   229
        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
   230
        client2 = new Http2ClientImpl(this);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   231
        executor = ex;
55812
0a3a307f3502 http-client-branch: CookieManager -> CookieHandler
chegar
parents: 55792
diff changeset
   232
        cookieHandler = builder.cookieHandler;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   233
        followRedirects = builder.followRedirects == null ?
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   234
                Redirect.NEVER : builder.followRedirects;
55821
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   235
        this.userProxySelector = Optional.ofNullable(builder.proxy);
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   236
        this.proxySelector = userProxySelector
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   237
                .orElseGet(HttpClientImpl::getDefaultProxySelector);
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   238
        debug.log(Level.DEBUG, "proxySelector is %s (user-supplied=%s)",
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   239
                this.proxySelector, userProxySelector.isPresent());
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   240
        authenticator = builder.authenticator;
44854
5a486e0acd29 8175814: Update default HttpClient protocol version and optional request version
michaelm
parents: 44639
diff changeset
   241
        if (builder.version == null) {
5a486e0acd29 8175814: Update default HttpClient protocol version and optional request version
michaelm
parents: 44639
diff changeset
   242
            version = HttpClient.Version.HTTP_2;
5a486e0acd29 8175814: Update default HttpClient protocol version and optional request version
michaelm
parents: 44639
diff changeset
   243
        } else {
5a486e0acd29 8175814: Update default HttpClient protocol version and optional request version
michaelm
parents: 44639
diff changeset
   244
            version = builder.version;
5a486e0acd29 8175814: Update default HttpClient protocol version and optional request version
michaelm
parents: 44639
diff changeset
   245
        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   246
        if (builder.sslParams == null) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   247
            sslParams = getDefaultParams(sslContext);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   248
        } else {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   249
            sslParams = builder.sslParams;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   250
        }
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   251
        connections = new ConnectionPool(id);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   252
        connections.start();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   253
        timeouts = new TreeSet<>();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   254
        try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   255
            selmgr = new SelectorManager(this);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   256
        } catch (IOException e) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   257
            // unlikely
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   258
            throw new InternalError(e);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   259
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   260
        selmgr.setDaemon(true);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   261
        filters = new FilterFactory();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   262
        initFilters();
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   263
        assert facadeRef.get() != null;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   264
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   265
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   266
    private void start() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   267
        selmgr.start();
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
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   270
    // Called from the SelectorManager thread, just before exiting.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   271
    // Clears the HTTP/1.1 and HTTP/2 cache, ensuring that the connections
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   272
    // that may be still lingering there are properly closed (and their
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   273
    // possibly still opened SocketChannel released).
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   274
    private void stop() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   275
        // Clears HTTP/1.1 cache and close its connections
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   276
        connections.stop();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   277
        // Clears HTTP/2 cache and close its connections.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   278
        client2.stop();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   279
    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   280
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   281
    private static SSLParameters getDefaultParams(SSLContext ctx) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   282
        SSLParameters params = ctx.getSupportedSSLParameters();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   283
        params.setProtocols(new String[]{"TLSv1.2"});
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   284
        return params;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   285
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   286
55821
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   287
    private static ProxySelector getDefaultProxySelector() {
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   288
        PrivilegedAction<ProxySelector> action = ProxySelector::getDefault;
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   289
        return AccessController.doPrivileged(action);
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   290
    }
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   291
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   292
    // Returns the facade that was returned to the application code.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   293
    // May be null if that facade is no longer referenced.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   294
    final HttpClientFacade facade() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   295
        return facadeRef.get();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   296
    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   297
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   298
    // Increments the pendingOperationCount.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   299
    final long reference() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   300
        pendingHttpRequestCount.incrementAndGet();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   301
        return pendingOperationCount.incrementAndGet();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   302
    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   303
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   304
    // Decrements the pendingOperationCount.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   305
    final long unreference() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   306
        final long count = pendingOperationCount.decrementAndGet();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   307
        final long httpCount = pendingHttpRequestCount.decrementAndGet();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   308
        final long webSocketCount = pendingWebSocketCount.get();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   309
        if (count == 0 && facade() == null) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   310
            selmgr.wakeupSelector();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   311
        }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   312
        assert httpCount >= 0 : "count of HTTP operations < 0";
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   313
        assert webSocketCount >= 0 : "count of WS operations < 0";
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   314
        assert count >= 0 : "count of pending operations < 0";
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   315
        return count;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   316
    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   317
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   318
    // Increments the pendingOperationCount.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   319
    final long webSocketOpen() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   320
        pendingWebSocketCount.incrementAndGet();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   321
        return pendingOperationCount.incrementAndGet();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   322
    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   323
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   324
    // Decrements the pendingOperationCount.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   325
    final long webSocketClose() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   326
        final long count = pendingOperationCount.decrementAndGet();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   327
        final long webSocketCount = pendingWebSocketCount.decrementAndGet();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   328
        final long httpCount = pendingHttpRequestCount.get();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   329
        if (count == 0 && facade() == null) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   330
            selmgr.wakeupSelector();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   331
        }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   332
        assert httpCount >= 0 : "count of HTTP operations < 0";
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   333
        assert webSocketCount >= 0 : "count of WS operations < 0";
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   334
        assert count >= 0 : "count of pending operations < 0";
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   335
        return count;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   336
    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   337
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   338
    // Returns the pendingOperationCount.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   339
    final long referenceCount() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   340
        return pendingOperationCount.get();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   341
    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   342
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   343
    // Called by the SelectorManager thread to figure out whether it's time
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   344
    // to terminate.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   345
    final boolean isReferenced() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   346
        HttpClient facade = facade();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   347
        return facade != null || referenceCount() > 0;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   348
    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   349
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   350
    /**
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   351
     * Wait for activity on given exchange.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   352
     * 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
   353
     *
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   354
     *  1) add to selector
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   355
     *  2) If selector fires for this exchange then
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   356
     *     call AsyncEvent.handle()
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   357
     *
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   358
     * 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
   359
     */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   360
    void registerEvent(AsyncEvent exchange) throws IOException {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   361
        selmgr.register(exchange);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   362
    }
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
    /**
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   365
     * 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
   366
     * the selector
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
    void cancelRegistration(SocketChannel s) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   369
        selmgr.cancel(s);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   370
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   371
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   372
    /**
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   373
     * Allows an AsyncEvent to modify its interestOps.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   374
     * @param event The modified event.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   375
     */
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   376
    void eventUpdated(AsyncEvent event) throws ClosedChannelException {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   377
        assert !(event instanceof AsyncTriggerEvent);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   378
        selmgr.eventUpdated(event);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   379
    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   380
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   381
    boolean isSelectorThread() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   382
        return Thread.currentThread() == selmgr;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   383
    }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   384
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   385
    Http2ClientImpl client2() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   386
        return client2;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   387
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   388
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   389
    private void debugCompleted(String tag, long startNanos, HttpRequest req) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   390
        if (debugelapsed.isLoggable(Level.DEBUG)) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   391
            debugelapsed.log(Level.DEBUG, () -> tag + " elapsed "
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   392
                    + (System.nanoTime() - startNanos)/1000_000L
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   393
                    + " millis for " + req.method()
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   394
                    + " to " + req.uri());
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   395
        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   396
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   397
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   398
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   399
    public <T> HttpResponse<T>
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   400
    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
   401
        throws IOException, InterruptedException
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   402
    {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   403
        try {
55816
70738768515a http-client-branch: spec clarifications and minor fix to sendXXX methods
chegar
parents: 55815
diff changeset
   404
            return sendAsync(req, responseHandler).get();
70738768515a http-client-branch: spec clarifications and minor fix to sendXXX methods
chegar
parents: 55815
diff changeset
   405
        } catch (ExecutionException e) {
70738768515a http-client-branch: spec clarifications and minor fix to sendXXX methods
chegar
parents: 55815
diff changeset
   406
            Throwable t = e.getCause();
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   407
            if (t instanceof Error)
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   408
                throw (Error)t;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   409
            if (t instanceof RuntimeException)
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   410
                throw (RuntimeException)t;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   411
            else if (t instanceof IOException)
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   412
                throw Utils.getIOException(t);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   413
            else
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   414
                throw new InternalError("Unexpected exception", t);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   415
        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   416
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   417
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   418
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   419
    public <T> CompletableFuture<HttpResponse<T>>
55764
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   420
    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
   421
    {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   422
        AccessControlContext acc = null;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   423
        if (System.getSecurityManager() != null)
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   424
            acc = AccessController.getContext();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   425
55764
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   426
        // Clone the, possibly untrusted, HttpRequest
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   427
        HttpRequestImpl requestImpl = new HttpRequestImpl(userRequest, proxySelector, acc);
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   428
        if (requestImpl.method().equals("CONNECT"))
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   429
            throw new IllegalArgumentException("Unsupported method CONNECT");
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   430
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   431
        long start = DEBUGELAPSED ? System.nanoTime() : 0;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   432
        reference();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   433
        try {
55815
4f699653026b http-client-branch: Cleanup unneeded buffer instance variable from Http1Exchange
dfuchs
parents: 55812
diff changeset
   434
            debugelapsed.log(Level.DEBUG, "ClientImpl (async) send %s", userRequest);
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   435
55764
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   436
            MultiExchange<Void,T> mex = new MultiExchange<>(userRequest,
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   437
                                                            requestImpl,
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   438
                                                            this,
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   439
                                                            responseHandler,
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   440
                                                            acc);
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   441
            CompletableFuture<HttpResponse<T>> res =
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   442
                    mex.responseAsync().whenComplete((b,t) -> unreference());
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   443
            if (DEBUGELAPSED) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   444
                res = res.whenComplete(
55764
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   445
                        (b,t) -> debugCompleted("ClientImpl (async)", start, userRequest));
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   446
            }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   447
            // makes sure that any dependent actions happen in the executor
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   448
            if (acc != null) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   449
                res.whenCompleteAsync((r, t) -> { /* do nothing */},
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   450
                                      new PrivilegedExecutor(executor, acc));
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   451
            }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   452
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   453
            return res;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   454
        } catch(Throwable t) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   455
            unreference();
55764
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   456
            debugCompleted("ClientImpl (async)", start, userRequest);
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   457
            throw t;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   458
        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   459
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   461
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   462
    public <U, T> CompletableFuture<U>
55764
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   463
    sendAsync(HttpRequest userRequest, MultiSubscriber<U, T> responseHandler) {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   464
        AccessControlContext acc = null;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   465
        if (System.getSecurityManager() != null)
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   466
            acc = AccessController.getContext();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   467
55764
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   468
        // Clone the, possibly untrusted, HttpRequest
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   469
        HttpRequestImpl requestImpl = new HttpRequestImpl(userRequest, proxySelector, acc);
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   470
        if (requestImpl.method().equals("CONNECT"))
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   471
            throw new IllegalArgumentException("Unsupported method CONNECT");
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   472
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   473
        long start = DEBUGELAPSED ? System.nanoTime() : 0;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   474
        reference();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   475
        try {
55815
4f699653026b http-client-branch: Cleanup unneeded buffer instance variable from Http1Exchange
dfuchs
parents: 55812
diff changeset
   476
            debugelapsed.log(Level.DEBUG, "ClientImpl (async) send multi %s", userRequest);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   477
55764
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   478
            MultiExchange<U,T> mex = new MultiExchange<>(userRequest,
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   479
                                                         requestImpl,
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   480
                                                         this,
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   481
                                                         responseHandler,
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   482
                                                         acc);
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   483
            CompletableFuture<U> res = mex.multiResponseAsync()
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   484
                      .whenComplete((b,t) -> unreference());
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   485
            if (DEBUGELAPSED) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   486
                res = res.whenComplete(
55764
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   487
                        (b,t) -> debugCompleted("ClientImpl (async)", start, userRequest));
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   488
            }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   489
            // makes sure that any dependent actions happen in the executor
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   490
            if (acc != null) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   491
                res.whenCompleteAsync((r, t) -> { /* do nothing */},
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   492
                                      new PrivilegedExecutor(executor, acc));
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   493
            }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   494
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   495
            return res;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   496
        } catch(Throwable t) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   497
            unreference();
55764
34d7cc00f87a http-client-branch: WebSocket permission checks, test updates, and more
chegar
parents: 55763
diff changeset
   498
            debugCompleted("ClientImpl (async)", start, userRequest);
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   499
            throw t;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   500
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   501
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   502
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   503
    // 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
   504
    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
   505
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   506
        // For testing purposes we have an internal System property that
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   507
        // can control the frequency at which the selector manager will wake
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   508
        // up when there are no pending operations.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   509
        // Increasing the frequency (shorter delays) might allow the selector
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   510
        // to observe that the facade is no longer referenced and might allow
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   511
        // the selector thread to terminate more timely - for when nothing is
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   512
        // ongoing it will only check for that condition every NODEADLINE ms.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   513
        // To avoid misuse of the property, the delay that can be specified
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   514
        // is comprised between [MIN_NODEADLINE, MAX_NODEADLINE], and its default
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   515
        // value if unspecified (or <= 0) is DEF_NODEADLINE = 3000ms
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   516
        // The property is -Djdk.httpclient.internal.selector.timeout=<millis>
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   517
        private static final int MIN_NODEADLINE = 1000; // ms
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   518
        private static final int MAX_NODEADLINE = 1000 * 1200; // ms
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   519
        private static final int DEF_NODEADLINE = 3000; // ms
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   520
        private static final long NODEADLINE; // default is DEF_NODEADLINE ms
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   521
        static {
55792
0936888d5a4a http-client-branch: (cleanup) unused imports, unused methods, removed 1 class; typos;
prappo
parents: 55781
diff changeset
   522
            // ensure NODEADLINE is initialized with some valid value.
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   523
            long deadline =  Utils.getIntegerNetProperty(
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   524
                "jdk.httpclient.internal.selector.timeout",
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   525
                DEF_NODEADLINE); // millis
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   526
            if (deadline <= 0) deadline = DEF_NODEADLINE;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   527
            deadline = Math.max(deadline, MIN_NODEADLINE);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   528
            NODEADLINE = Math.min(deadline, MAX_NODEADLINE);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   529
        }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   530
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   531
        private final Selector selector;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   532
        private volatile boolean closed;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   533
        private final List<AsyncEvent> registrations;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   534
        private final System.Logger debug;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   535
        private final System.Logger debugtimeout;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   536
        HttpClientImpl owner;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   537
        ConnectionPool pool;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   538
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   539
        SelectorManager(HttpClientImpl ref) throws IOException {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   540
            super(null, null, "HttpClient-" + ref.id + "-SelectorManager", 0, false);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   541
            owner = ref;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   542
            debug = ref.debug;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   543
            debugtimeout = ref.debugtimeout;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   544
            pool = ref.connectionPool();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   545
            registrations = new ArrayList<>();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   546
            selector = Selector.open();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   547
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   548
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   549
        void eventUpdated(AsyncEvent e) throws ClosedChannelException {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   550
            if (Thread.currentThread() == this) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   551
                SelectionKey key = e.channel().keyFor(selector);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   552
                SelectorAttachment sa = (SelectorAttachment) key.attachment();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   553
                if (sa != null) sa.register(e);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   554
            } else {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   555
                register(e);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   556
            }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   557
        }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   558
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   559
        // 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
   560
        // on connection.
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   561
        synchronized void register(AsyncEvent e) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   562
            registrations.add(e);
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 cancel(SocketChannel e) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   567
            SelectionKey key = e.keyFor(selector);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   568
            if (key != null) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   569
                key.cancel();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   570
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   571
            selector.wakeup();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   572
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   573
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   574
        void wakeupSelector() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   575
            selector.wakeup();
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
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   578
        synchronized void shutdown() {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   579
            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
   580
            closed = true;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   581
            try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   582
                selector.close();
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   583
            } catch (IOException ignored) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   584
            } finally {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   585
                owner.stop();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   586
            }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   587
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   588
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   589
        @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   590
        public void run() {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   591
            List<Pair<AsyncEvent,IOException>> errorList = new ArrayList<>();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   592
            List<AsyncEvent> readyList = new ArrayList<>();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   593
            try {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   594
                while (!Thread.currentThread().isInterrupted()) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   595
                    synchronized (this) {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   596
                        assert errorList.isEmpty();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   597
                        assert readyList.isEmpty();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   598
                        for (AsyncEvent event : registrations) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   599
                            if (event instanceof AsyncTriggerEvent) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   600
                                readyList.add(event);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   601
                                continue;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   602
                            }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   603
                            SelectableChannel chan = event.channel();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   604
                            SelectionKey key = null;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   605
                            try {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   606
                                key = chan.keyFor(selector);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   607
                                SelectorAttachment sa;
45531
fb3dbffad37b 8180044: java/net/httpclient/ManyRequests.java failed due to timeout
dfuchs
parents: 44854
diff changeset
   608
                                if (key == null || !key.isValid()) {
fb3dbffad37b 8180044: java/net/httpclient/ManyRequests.java failed due to timeout
dfuchs
parents: 44854
diff changeset
   609
                                    if (key != null) {
fb3dbffad37b 8180044: java/net/httpclient/ManyRequests.java failed due to timeout
dfuchs
parents: 44854
diff changeset
   610
                                        // key is canceled.
fb3dbffad37b 8180044: java/net/httpclient/ManyRequests.java failed due to timeout
dfuchs
parents: 44854
diff changeset
   611
                                        // invoke selectNow() to purge it
fb3dbffad37b 8180044: java/net/httpclient/ManyRequests.java failed due to timeout
dfuchs
parents: 44854
diff changeset
   612
                                        // before registering the new event.
fb3dbffad37b 8180044: java/net/httpclient/ManyRequests.java failed due to timeout
dfuchs
parents: 44854
diff changeset
   613
                                        selector.selectNow();
fb3dbffad37b 8180044: java/net/httpclient/ManyRequests.java failed due to timeout
dfuchs
parents: 44854
diff changeset
   614
                                    }
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   615
                                    sa = new SelectorAttachment(chan, selector);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   616
                                } else {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   617
                                    sa = (SelectorAttachment) key.attachment();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   618
                                }
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   619
                                // may throw IOE if channel closed: that's OK
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   620
                                sa.register(event);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   621
                                if (!chan.isOpen()) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   622
                                    throw new IOException("Channel closed");
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   623
                                }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   624
                            } catch (IOException e) {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   625
                                Log.logTrace("HttpClientImpl: " + e);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   626
                                debug.log(Level.DEBUG, () ->
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   627
                                        "Got " + e.getClass().getName()
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   628
                                                 + " while handling"
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   629
                                                 + " registration events");
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   630
                                chan.close();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   631
                                // let the event abort deal with it
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   632
                                errorList.add(new Pair<>(event, e));
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   633
                                if (key != null) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   634
                                    key.cancel();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   635
                                    selector.selectNow();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   636
                                }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   637
                            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   638
                        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   639
                        registrations.clear();
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   640
                        selector.selectedKeys().clear();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   641
                    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   642
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   643
                    for (AsyncEvent event : readyList) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   644
                        assert event instanceof AsyncTriggerEvent;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   645
                        event.handle();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   646
                    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   647
                    readyList.clear();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   648
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   649
                    for (Pair<AsyncEvent,IOException> error : errorList) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   650
                        // an IOException was raised and the channel closed.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   651
                        handleEvent(error.first, error.second);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   652
                    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   653
                    errorList.clear();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   654
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   655
                    // 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
   656
                    // gracefully stop this thread
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   657
                    if (!owner.isReferenced()) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   658
                        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
   659
                        return;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   660
                    }
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   661
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   662
                    // Timeouts will have milliseconds granularity. It is important
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   663
                    // to handle them in a timely fashion.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   664
                    long nextTimeout = owner.purgeTimeoutsAndReturnNextDeadline();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   665
                    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
   666
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   667
                    // Keep-alive have seconds granularity. It's not really an
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   668
                    // issue if we keep connections linger a bit more in the keep
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   669
                    // alive cache.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   670
                    long nextExpiry = pool.purgeExpiredConnectionsAndReturnNextDeadline();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   671
                    debugtimeout.log(Level.DEBUG, "next expired: %d", nextExpiry);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   672
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   673
                    assert nextTimeout >= 0;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   674
                    assert nextExpiry >= 0;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   675
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   676
                    // 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
   677
                    // stop gracefully. millis will be 0 if no deadline was found.
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   678
                    if (nextTimeout <= 0) nextTimeout = NODEADLINE;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   679
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   680
                    // Clip nextExpiry at NODEADLINE limit. The default
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   681
                    // keep alive is 1200 seconds (half an hour) - we don't
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   682
                    // want to wait that long.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   683
                    if (nextExpiry <= 0) nextExpiry = NODEADLINE;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   684
                    else nextExpiry = Math.min(NODEADLINE, nextExpiry);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   685
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   686
                    // takes the least of the two.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   687
                    long millis = Math.min(nextExpiry, nextTimeout);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   688
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   689
                    debugtimeout.log(Level.DEBUG, "Next deadline is %d",
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   690
                                     (millis == 0 ? NODEADLINE : millis));
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   691
                    //debugPrint(selector);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   692
                    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
   693
                    if (n == 0) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   694
                        // 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
   695
                        // gracefully stop this thread
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   696
                        if (!owner.isReferenced()) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   697
                            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
   698
                            return;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   699
                        }
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   700
                        owner.purgeTimeoutsAndReturnNextDeadline();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   701
                        continue;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   702
                    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   703
                    Set<SelectionKey> keys = selector.selectedKeys();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   704
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   705
                    assert errorList.isEmpty();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   706
                    for (SelectionKey key : keys) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   707
                        SelectorAttachment sa = (SelectorAttachment) key.attachment();
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   708
                        if (!key.isValid()) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   709
                            IOException ex = sa.chan.isOpen()
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   710
                                    ? new IOException("Invalid key")
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   711
                                    : new ClosedChannelException();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   712
                            sa.pending.forEach(e -> errorList.add(new Pair<>(e,ex)));
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   713
                            sa.pending.clear();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   714
                            continue;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   715
                        }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   716
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   717
                        int eventsOccurred;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   718
                        try {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   719
                            eventsOccurred = key.readyOps();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   720
                        } catch (CancelledKeyException ex) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   721
                            IOException io = Utils.getIOException(ex);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   722
                            sa.pending.forEach(e -> errorList.add(new Pair<>(e,io)));
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   723
                            sa.pending.clear();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   724
                            continue;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   725
                        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   726
                        sa.events(eventsOccurred).forEach(readyList::add);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   727
                        sa.resetInterestOps(eventsOccurred);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   728
                    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   729
                    selector.selectNow(); // complete cancellation
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   730
                    selector.selectedKeys().clear();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   731
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   732
                    for (AsyncEvent event : readyList) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   733
                        handleEvent(event, null); // will be delegated to executor
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   734
                    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   735
                    readyList.clear();
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   736
                    errorList.forEach((p) -> handleEvent(p.first, p.second));
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   737
                    errorList.clear();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   738
                }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   739
            } catch (Throwable e) {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   740
                //e.printStackTrace();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   741
                if (!closed) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   742
                    // 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
   743
                    String err = Utils.stackTrace(e);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   744
                    Log.logError("HttpClientImpl: fatal error: " + err);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   745
                }
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   746
                debug.log(Level.DEBUG, "shutting down", e);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   747
                if (Utils.ASSERTIONSENABLED && !debug.isLoggable(Level.DEBUG)) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   748
                    e.printStackTrace(System.err); // always print the stack
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   749
                }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   750
            } finally {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   751
                shutdown();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   752
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   753
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   754
55792
0936888d5a4a http-client-branch: (cleanup) unused imports, unused methods, removed 1 class; typos;
prappo
parents: 55781
diff changeset
   755
//        void debugPrint(Selector selector) {
0936888d5a4a http-client-branch: (cleanup) unused imports, unused methods, removed 1 class; typos;
prappo
parents: 55781
diff changeset
   756
//            System.err.println("Selector: debugprint start");
0936888d5a4a http-client-branch: (cleanup) unused imports, unused methods, removed 1 class; typos;
prappo
parents: 55781
diff changeset
   757
//            Set<SelectionKey> keys = selector.keys();
0936888d5a4a http-client-branch: (cleanup) unused imports, unused methods, removed 1 class; typos;
prappo
parents: 55781
diff changeset
   758
//            for (SelectionKey key : keys) {
0936888d5a4a http-client-branch: (cleanup) unused imports, unused methods, removed 1 class; typos;
prappo
parents: 55781
diff changeset
   759
//                SelectableChannel c = key.channel();
0936888d5a4a http-client-branch: (cleanup) unused imports, unused methods, removed 1 class; typos;
prappo
parents: 55781
diff changeset
   760
//                int ops = key.interestOps();
0936888d5a4a http-client-branch: (cleanup) unused imports, unused methods, removed 1 class; typos;
prappo
parents: 55781
diff changeset
   761
//                System.err.printf("selector chan:%s ops:%d\n", c, ops);
0936888d5a4a http-client-branch: (cleanup) unused imports, unused methods, removed 1 class; typos;
prappo
parents: 55781
diff changeset
   762
//            }
0936888d5a4a http-client-branch: (cleanup) unused imports, unused methods, removed 1 class; typos;
prappo
parents: 55781
diff changeset
   763
//            System.err.println("Selector: debugprint end");
0936888d5a4a http-client-branch: (cleanup) unused imports, unused methods, removed 1 class; typos;
prappo
parents: 55781
diff changeset
   764
//        }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   765
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   766
        /** Handles the given event. The given ioe may be null. */
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   767
        void handleEvent(AsyncEvent event, IOException ioe) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   768
            if (closed || ioe != null) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   769
                event.abort(ioe);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   770
            } else {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   771
                event.handle();
42460
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
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   774
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   775
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   776
    /**
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   777
     * 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
   778
     * registration (SelectionKey). In this implementation, registrations
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   779
     * 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
   780
     * until explicitly registered again.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   781
     *
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   782
     * <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
   783
     * 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
   784
     * connection.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   785
     */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   786
    private static class SelectorAttachment {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   787
        private final SelectableChannel chan;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   788
        private final Selector selector;
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   789
        private final Set<AsyncEvent> pending;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   790
        private final static System.Logger debug =
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   791
                Utils.getDebugLogger("SelectorAttachment"::toString, DEBUG);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   792
        private int interestOps;
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
        SelectorAttachment(SelectableChannel chan, Selector selector) {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   795
            this.pending = new HashSet<>();
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   796
            this.chan = chan;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   797
            this.selector = selector;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   798
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   799
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   800
        void register(AsyncEvent e) throws ClosedChannelException {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   801
            int newOps = e.interestOps();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   802
            boolean reRegister = (interestOps & newOps) != newOps;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   803
            interestOps |= newOps;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   804
            pending.add(e);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   805
            if (reRegister) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   806
                // first time registration happens here also
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   807
                chan.register(selector, interestOps, this);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   808
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   809
        }
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
         * 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
   813
         * registered with the given {@code interestOps}.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   814
         */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   815
        Stream<AsyncEvent> events(int interestOps) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   816
            return pending.stream()
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   817
                    .filter(ev -> (ev.interestOps() & interestOps) != 0);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   818
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   819
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   820
        /**
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   821
         * 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
   822
         * events remaining, cancels the associated SelectionKey.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   823
         */
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   824
        void resetInterestOps(int interestOps) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   825
            int newOps = 0;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   826
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   827
            Iterator<AsyncEvent> itr = pending.iterator();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   828
            while (itr.hasNext()) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   829
                AsyncEvent event = itr.next();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   830
                int evops = event.interestOps();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   831
                if (event.repeating()) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   832
                    newOps |= evops;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   833
                    continue;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   834
                }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   835
                if ((evops & interestOps) != 0) {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   836
                    itr.remove();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   837
                } else {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   838
                    newOps |= evops;
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
            this.interestOps = newOps;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   843
            SelectionKey key = chan.keyFor(selector);
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   844
            if (newOps == 0 && pending.isEmpty()) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   845
                key.cancel();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   846
            } else {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   847
                try {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   848
                    key.interestOps(newOps);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   849
                } catch (CancelledKeyException x) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   850
                    // channel may have been closed
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   851
                    debug.log(Level.DEBUG, "key cancelled for " + chan);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   852
                    abortPending(x);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   853
                }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   854
            }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   855
        }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   856
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   857
        void abortPending(Throwable x) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   858
            if (!pending.isEmpty()) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   859
                AsyncEvent[] evts = pending.toArray(new AsyncEvent[0]);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   860
                pending.clear();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   861
                IOException io = Utils.getIOException(x);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   862
                for (AsyncEvent event : evts) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   863
                    event.abort(io);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   864
                }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   865
            }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   866
        }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   867
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   868
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   869
    /*package-private*/ SSLContext theSSLContext() {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   870
        return sslContext;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   871
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   872
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   873
    @Override
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   874
    public SSLContext sslContext() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   875
        SecurityManager sm = System.getSecurityManager();
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   876
        if (sm != null) {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   877
            NetPermission np = new NetPermission("getSSLContext");
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   878
            sm.checkPermission(np);
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   879
        }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   880
        return sslContext;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   881
    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   882
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   883
    @Override
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   884
    public SSLParameters sslParameters() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   885
        return Utils.copySSLParameters(sslParams);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   886
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   887
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   888
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   889
    public Optional<Authenticator> authenticator() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   890
        return Optional.ofNullable(authenticator);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   891
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   892
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   893
    /*package-private*/ final Executor theExecutor() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   894
        return executor;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   895
    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   896
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   897
    @Override
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   898
    public final Optional<Executor> executor() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   899
        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
   900
    }
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
    ConnectionPool connectionPool() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   903
        return connections;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   904
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   905
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   906
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   907
    public Redirect followRedirects() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   908
        return followRedirects;
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   909
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   910
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
    @Override
55812
0a3a307f3502 http-client-branch: CookieManager -> CookieHandler
chegar
parents: 55792
diff changeset
   913
    public Optional<CookieHandler> cookieHandler() {
0a3a307f3502 http-client-branch: CookieManager -> CookieHandler
chegar
parents: 55792
diff changeset
   914
        return Optional.ofNullable(cookieHandler);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   915
    }
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
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   918
    public Optional<ProxySelector> proxy() {
55821
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   919
        return this.userProxySelector;
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   920
    }
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   921
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   922
    // Return the effective proxy that this client uses.
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   923
    ProxySelector proxySelector() {
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   924
        return proxySelector;
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
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   928
    public WebSocket.Builder newWebSocketBuilder(URI uri,
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   929
                                                 WebSocket.Listener listener) {
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   930
        // Make sure to pass the HttpClientFacade to the web socket builder.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   931
        // This will ensure that the facade is not released before the
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   932
        // WebSocket has been created, at which point the pendingOperationCount
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   933
        // will have been incremented by the DetachedConnectionChannel
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   934
        // (see PlainHttpConnection.detachChannel())
55821
fa0fc03c0853 http-client-branch: HttpClient uses ProxySelector.getDefault() by default
dfuchs
parents: 55816
diff changeset
   935
        return new BuilderImpl(this.facade(), uri, listener, proxySelector);
42460
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
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   938
    @Override
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   939
    public Version version() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   940
        return version;
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
55763
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   943
    String dbgString() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   944
        return dbgTag;
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   945
    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   946
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   947
    @Override
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   948
    public String toString() {
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   949
        // Used by tests to get the client's id and compute the
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   950
        // name of the SelectorManager thread.
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   951
        return super.toString() + ("(" + id + ")");
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   952
    }
634d8e14c172 http-client-branch: intial load from jdk10/sandbox
chegar
parents: 47216
diff changeset
   953
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   954
    private void initFilters() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   955
        addFilter(AuthenticationFilter.class);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   956
        addFilter(RedirectFilter.class);
55812
0a3a307f3502 http-client-branch: CookieManager -> CookieHandler
chegar
parents: 55792
diff changeset
   957
        if (this.cookieHandler != null) {
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   958
            addFilter(CookieFilter.class);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   959
        }
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
    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
   963
        filters.addFilter(f);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   964
    }
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
    final List<HeaderFilter> filterChain() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   967
        return filters.getFilterChain();
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   968
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   969
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   970
    // Timer controls.
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   971
    // 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
   972
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   973
    synchronized void registerTimer(TimeoutEvent event) {
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
   974
        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
   975
        timeouts.add(event);
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   976
        selmgr.wakeupSelector();
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
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   979
    synchronized void cancelTimer(TimeoutEvent event) {
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
   980
        Log.logTrace("Canceling timer {0}", event);
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
   981
        timeouts.remove(event);
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
   982
    }
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
     * 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
   986
     * 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
   987
     * 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
   988
     */
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
   989
    private long purgeTimeoutsAndReturnNextDeadline() {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
   990
        long diff = 0L;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
   991
        List<TimeoutEvent> toHandle = null;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
   992
        int remaining = 0;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
   993
        // 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
   994
        synchronized(this) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
   995
            if (timeouts.isEmpty()) return 0L;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
   996
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
   997
            Instant now = Instant.now();
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
   998
            Iterator<TimeoutEvent> itr = timeouts.iterator();
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
   999
            while (itr.hasNext()) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1000
                TimeoutEvent event = itr.next();
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1001
                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
  1002
                if (diff <= 0) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1003
                    itr.remove();
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1004
                    toHandle = (toHandle == null) ? new ArrayList<>() : toHandle;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1005
                    toHandle.add(event);
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1006
                } else {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1007
                    break;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1008
                }
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1009
            }
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1010
            remaining = timeouts.size();
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1011
        }
42460
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
        // can be useful for debugging
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1014
        if (toHandle != null && Log.trace()) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1015
            Log.logTrace("purgeTimeoutsAndReturnNextDeadline: handling "
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1016
                    + (toHandle == null ? 0 : toHandle.size()) + " events, "
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1017
                    + "remaining " + remaining
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1018
                    + ", next deadline: " + (diff < 0 ? 0L : diff));
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1019
        }
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
        // 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
  1022
        if (toHandle != null) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1023
            Throwable failed = null;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1024
            for (TimeoutEvent event : toHandle) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1025
                try {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1026
                   Log.logTrace("Firing timer {0}", event);
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1027
                   event.handle();
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1028
                } catch (Error | RuntimeException e) {
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1029
                    // 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
  1030
                    // 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
  1031
                    // 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
  1032
                    // 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
  1033
                    if (failed == null) failed = e;
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1034
                    else failed.addSuppressed(e);
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1035
                    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
  1036
                }
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1037
            }
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1038
            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
  1039
            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
  1040
        }
44639
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1041
5c2838d882a5 8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents: 43984
diff changeset
  1042
        // 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
  1043
        return diff < 0 ? 0L : diff;
42460
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1044
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1045
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1046
    // used for the connection window
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1047
    int getReceiveBufferSize() {
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1048
        return Utils.getIntegerNetProperty(
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1049
                "jdk.httpclient.connectionWindowSize", 256 * 1024
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1050
        );
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1051
    }
7133f144981a 8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff changeset
  1052
}