jdk/src/java.httpclient/share/classes/java/net/http/ExchangeImpl.java
author ysuenaga
Fri, 04 Mar 2016 18:13:04 +0900
changeset 37314 341fa2e9011f
parent 36131 379db4b2f95d
child 39730 196f4e25d9f5
permissions -rw-r--r--
8151181: Add JSnap to jhsdb Reviewed-by: dsamersoff
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36131
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
     1
/*
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
     2
 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
     4
 *
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    10
 *
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    15
 * accompanied this code).
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    16
 *
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    20
 *
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    23
 */
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    24
package java.net.http;
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    25
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    26
import java.io.IOException;
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    27
import java.util.concurrent.CompletableFuture;
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    28
import static java.net.http.HttpClient.Version.HTTP_1_1;
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    29
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    30
/**
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    31
 * Splits request so that headers and body can be sent separately with optional
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    32
 * (multiple) responses in between (e.g. 100 Continue). Also request and
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    33
 * response always sent/received in different calls.
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    34
 *
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    35
 * Synchronous and asynchronous versions of each method are provided.
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    36
 *
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    37
 * Separate implementations of this class exist for HTTP/1.1 and HTTP/2
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    38
 *      Http1Exchange   (HTTP/1.1)
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    39
 *      Stream          (HTTP/2)
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    40
 *
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    41
 * These implementation classes are where work is allocated to threads.
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    42
 */
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    43
abstract class ExchangeImpl {
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    44
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    45
    final Exchange exchange;
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    46
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    47
    ExchangeImpl(Exchange e) {
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    48
        this.exchange = e;
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    49
    }
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    50
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    51
    /**
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    52
     * Initiates a new exchange and assigns it to a connection if one exists
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    53
     * already. connection usually null.
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    54
     */
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    55
    static ExchangeImpl get(Exchange exchange, HttpConnection connection)
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    56
        throws IOException, InterruptedException
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    57
    {
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    58
        HttpRequestImpl req = exchange.request();
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    59
        if (req.version() == HTTP_1_1) {
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    60
            return new Http1Exchange(exchange, connection);
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    61
        } else {
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    62
            Http2ClientImpl c2 = exchange.request().client().client2(); // TODO: improve
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    63
            HttpRequestImpl request = exchange.request();
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    64
            Http2Connection c = c2.getConnectionFor(request);
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    65
            if (c == null) {
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    66
                // no existing connection. Send request with HTTP 1 and then
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    67
                // upgrade if successful
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    68
                ExchangeImpl ex = new Http1Exchange(exchange, connection);
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    69
                exchange.h2Upgrade();
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    70
                return ex;
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    71
            }
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    72
            return c.createStream(exchange);
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    73
        }
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    74
    }
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    75
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    76
    /* The following methods have separate HTTP/1.1 and HTTP/2 implementations */
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    77
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    78
    /**
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    79
     * Sends the request headers only. May block until all sent.
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    80
     */
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    81
    abstract void sendHeadersOnly() throws IOException, InterruptedException;
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    82
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    83
    /**
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    84
     * Gets response headers by blocking if necessary. This may be an
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    85
     * intermediate response (like 101) or a final response 200 etc.
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    86
     */
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    87
    abstract HttpResponseImpl getResponse() throws IOException;
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    88
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    89
    /**
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    90
     * Sends a request body after request headers.
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    91
     */
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    92
    abstract void sendBody() throws IOException, InterruptedException;
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    93
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    94
    /**
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    95
     * Sends the entire request (headers and body) blocking.
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    96
     */
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    97
    abstract void sendRequest() throws IOException, InterruptedException;
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    98
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
    99
    /**
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   100
     * Asynchronous version of sendHeaders().
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   101
     */
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   102
    abstract CompletableFuture<Void> sendHeadersAsync();
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   103
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   104
    /**
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   105
     * Asynchronous version of getResponse().  Requires void parameter for
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   106
     * CompletableFuture chaining.
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   107
     */
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   108
    abstract CompletableFuture<HttpResponseImpl> getResponseAsync(Void v);
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   109
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   110
    /**
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   111
     * Asynchronous version of sendBody().
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   112
     */
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   113
    abstract CompletableFuture<Void> sendBodyAsync();
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   114
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   115
    /**
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   116
     * Cancels a request.  Not currently exposed through API.
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   117
     */
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   118
    abstract void cancel();
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   119
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   120
    /**
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   121
     * Asynchronous version of sendRequest().
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   122
     */
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   123
    abstract CompletableFuture<Void> sendRequestAsync();
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   124
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   125
    abstract <T> T responseBody(HttpResponse.BodyProcessor<T> processor)
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   126
        throws IOException;
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   127
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   128
    /**
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   129
     * Asynchronous version of responseBody().
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   130
     */
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   131
    abstract <T> CompletableFuture<T>
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   132
    responseBodyAsync(HttpResponse.BodyProcessor<T> processor);
379db4b2f95d 8087112: HTTP API and HTTP/1.1 implementation
michaelm
parents:
diff changeset
   133
}