1 /*
   2  * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.incubator.http;
  27 
  28 import java.io.FileNotFoundException;
  29 import java.io.InputStream;
  30 import java.net.URI;
  31 import java.net.URLPermission;
  32 import java.nio.ByteBuffer;
  33 import java.nio.charset.Charset;
  34 import java.nio.charset.StandardCharsets;
  35 import java.nio.file.Files;
  36 import java.nio.file.Path;
  37 import java.security.AccessController;
  38 import java.security.PrivilegedAction;
  39 import java.time.Duration;
  40 import java.util.Iterator;
  41 import java.util.Objects;
  42 import java.util.Optional;
  43 import java.util.concurrent.CompletableFuture;
  44 import java.util.concurrent.Executor;
  45 import java.util.concurrent.Flow;
  46 import java.util.function.Supplier;
  47 import static java.nio.charset.StandardCharsets.UTF_8;
  48 
  49 /**
  50  * Represents one HTTP request which can be sent to a server.
  51  * {@Incubating }
  52  *
  53  * <p> {@code HttpRequest} instances are built from {@code HttpRequest}
  54  * {@linkplain HttpRequest.Builder builders}. {@code HttpRequest} builders
  55  * are obtained by calling {@link HttpRequest#newBuilder(URI) HttpRequest.newBuilder}.
  56  * A request's {@linkplain URI}, headers and body can be set. Request bodies are
  57  * provided through a {@link BodyPublisher} object supplied to the
  58  * {@link Builder#DELETE(BodyPublisher) DELETE},
  59  * {@link Builder#POST(BodyPublisher) POST} or
  60  * {@link Builder#PUT(BodyPublisher) PUT} methods.
  61  * {@link Builder#GET() GET} does not take a body. Once all required
  62  * parameters have been set in the builder, {@link Builder#build() } is called
  63  * to return the {@code HttpRequest}. Builders can also be copied and modified
  64  * multiple times in order to build multiple related requests that differ in
  65  * some parameters.
  66  *
  67  * <p> Two simple, example HTTP interactions are shown below:
  68  * <pre>
  69  * {@code
  70  *      HttpClient client = HttpClient.newHttpClient();
  71  *
  72  *      // GET
  73  *      HttpResponse<String> response = client.send(
  74  *          HttpRequest
  75  *              .newBuilder(new URI("http://www.foo.com/"))
  76  *              .headers("Foo", "foovalue", "Bar", "barvalue")
  77  *              .GET()
  78  *              .build(),
  79  *          BodyHandler.asString()
  80  *      );
  81  *      int statusCode = response.statusCode();
  82  *      String body = response.body();
  83  *
  84  *      // POST
  85  *      HttpResponse<Path> response = client.send(
  86  *          HttpRequest
  87  *              .newBuilder(new URI("http://www.foo.com/"))
  88  *              .headers("Foo", "foovalue", "Bar", "barvalue")
  89  *              .POST(BodyPublisher.fromString("Hello world"))
  90  *              .build(),
  91  *          BodyHandler.asFile(Paths.get("/path"))
  92  *      );
  93  *      int statusCode = response.statusCode();
  94  *      Path body = response.body(); // should be "/path"
  95  * }
  96  * </pre>
  97  *
  98  * <p> The request is sent and the response obtained by calling one of the
  99  * following methods in {@link HttpClient}.
 100  * <ul><li>{@link HttpClient#send(HttpRequest, HttpResponse.BodyHandler)} blocks
 101  * until the entire request has been sent and the response has been received.</li>
 102  * <li>{@link HttpClient#sendAsync(HttpRequest,HttpResponse.BodyHandler)} sends the
 103  * request and receives the response asynchronously. Returns immediately with a
 104  * {@link java.util.concurrent.CompletableFuture CompletableFuture}&lt;{@link
 105  * HttpResponse}&gt;.</li>
 106  * <li>{@link HttpClient#sendAsync(HttpRequest, HttpResponse.MultiSubscriber) }
 107  * sends the request asynchronously, expecting multiple responses. This
 108  * capability is of most relevance to HTTP/2 server push, but can be used for
 109  * single responses (HTTP/1.1 or HTTP/2) also.</li>
 110  * </ul>
 111  *
 112  * <p> Once a {@link HttpResponse} is received, the headers, response code
 113  * and body (typically) are available. Whether the body has been read or not
 114  * depends on the type {@code <T>} of the response body. See below.
 115  *
 116  * <p> See below for discussion of synchronous versus asynchronous usage.
 117  *
 118  * <p> <b>Request bodies</b>
 119  *
 120  * <p> Request bodies can be sent using one of the convenience request publisher
 121  * implementations below, provided in {@link BodyPublisher}. Alternatively, a
 122  * custom Publisher implementation can be used.
 123  * <ul>
 124  * <li>{@link BodyPublisher#fromByteArray(byte[]) fromByteArray(byte[])} from byte array</li>
 125  * <li>{@link BodyPublisher#fromByteArrays(Iterable) fromByteArrays(Iterable)}
 126  *      from an Iterable of byte arrays</li>
 127  * <li>{@link BodyPublisher#fromFile(java.nio.file.Path) fromFile(Path)} from the file located
 128  *     at the given Path</li>
 129  * <li>{@link BodyPublisher#fromString(java.lang.String) fromString(String)} from a String </li>
 130  * <li>{@link BodyPublisher#fromInputStream(Supplier) fromInputStream}({@link Supplier}&lt;
 131  *      {@link InputStream}&gt;) from an InputStream obtained from a Supplier</li>
 132  * <li>{@link BodyPublisher#noBody() } no request body is sent</li>
 133  * </ul>
 134  *
 135  * <p> <b>Response bodies</b>
 136  *
 137  * <p> Responses bodies are handled at two levels. When sending the request,
 138  * a response body handler is specified. This is a function ({@linkplain
 139  * HttpResponse.BodyHandler}) which will be called with the response status code
 140  * and headers, once they are received. This function is then expected to return
 141  * a {@link HttpResponse.BodySubscriber}{@code <T>} which is then used to read
 142  * the response body, converting it into an instance of T. After this occurs,
 143  * the response becomes available in a {@link HttpResponse}, and {@link
 144  * HttpResponse#body()} can then be called to obtain the actual body. Some
 145  * implementations and examples of usage of both {@link
 146  * HttpResponse.BodySubscriber} and {@link HttpResponse.BodyHandler} are
 147  * provided in {@link HttpResponse}:
 148  *
 149  * <p> <b>Some of the pre-defined body handlers</b><br>
 150  * <ul>
 151  * <li>{@link HttpResponse.BodyHandler#asByteArray() BodyHandler.asByteArray()}
 152  * stores the body in a byte array</li>
 153  * <li>{@link HttpResponse.BodyHandler#asString() BodyHandler.asString()}
 154  * stores the body as a String </li>
 155  * <li>{@link HttpResponse.BodyHandler#asFile(java.nio.file.Path)
 156  * BodyHandler.asFile(Path)} stores the body in a named file</li>
 157  * <li>{@link HttpResponse.BodyHandler#discard(Object) BodyHandler.discard()}
 158  * discards the response body and returns the given value instead.</li>
 159  * </ul>
 160  *
 161  * <p> <b>Multi responses</b>
 162  *
 163  * <p> With HTTP/2 it is possible for a server to return a main response and zero
 164  * or more additional responses (known as server pushes) to a client-initiated
 165  * request. These are handled using a special response subscriber called {@link
 166  * HttpResponse.MultiSubscriber}.
 167  *
 168  * <p> <b>Blocking/asynchronous behavior and thread usage</b>
 169  *
 170  * <p> There are two styles of request sending: <i>synchronous</i> and
 171  * <i>asynchronous</i>. {@link HttpClient#send(HttpRequest, HttpResponse.BodyHandler) }
 172  * blocks the calling thread until the request has been sent and the response received.
 173  *
 174  * <p> {@link HttpClient#sendAsync(HttpRequest, HttpResponse.BodyHandler)} is
 175  * asynchronous and returns immediately with a {@link CompletableFuture}&lt;{@link
 176  * HttpResponse}&gt; and when this object completes (possibly in a different
 177  * thread) the response has been received.
 178  *
 179  * <p> {@link HttpClient#sendAsync(HttpRequest, HttpResponse.MultiSubscriber)}
 180  * is the variant for multi responses and is also asynchronous.
 181  *
 182  * <p> Instances of {@code CompletableFuture} can be combined in different ways
 183  * to declare the dependencies among several asynchronous tasks, while allowing
 184  * for the maximum level of parallelism to be utilized.
 185  *
 186  * <p> <a id="securitychecks"></a><b>Security checks</b></a>
 187  *
 188  * <p> If a security manager is present then security checks are performed by
 189  * the HTTP Client's sending methods. An appropriate {@link URLPermission} is
 190  * required to access the destination server, and proxy server if one has
 191  * been configured. The {@code URLPermission} form used to access proxies uses a
 192  * method parameter of {@code "CONNECT"} (for all kinds of proxying) and a URL
 193  * string  of the form {@code "socket://host:port"} where host and port specify
 194  * the proxy's address.
 195  *
 196  * <p> In this implementation, if an explicit {@linkplain
 197  * HttpClient.Builder#executor(Executor) executor} has not been set for an
 198  * {@code HttpClient}, and a security manager has been installed, then the
 199  * default executor will execute asynchronous and dependent tasks in a context
 200  * that is granted no permissions. Custom {@linkplain HttpRequest.BodyPublisher
 201  * request body publishers}, {@linkplain HttpResponse.BodyHandler response body
 202  * handlers}, {@linkplain HttpResponse.BodySubscriber response body subscribers},
 203  * and {@linkplain WebSocket.Listener WebSocket Listeners}, if executing
 204  * operations that require privileges, should do so  within an appropriate
 205  * {@linkplain AccessController#doPrivileged(PrivilegedAction) privileged context}.
 206  *
 207  * <p> <b>Examples</b>
 208  * <pre>{@code
 209  *      HttpClient client = HttpClient
 210  *              .newBuilder()
 211  *              .build();
 212  *
 213  *      HttpRequest request = HttpRequest
 214  *              .newBuilder(new URI("http://www.foo.com/"))
 215  *              .POST(BodyPublisher.fromString("Hello world"))
 216  *              .build();
 217  *
 218  *      HttpResponse<Path> response =
 219  *          client.send(request, BodyHandler.asFile(Paths.get("/path")));
 220  *
 221  *      Path body = response.body();
 222  * }</pre>
 223  *
 224  * <p><b>Asynchronous Example</b>
 225  *
 226  * <p> The above example will work asynchronously, if {@link HttpClient#sendAsync
 227  * (HttpRequest, HttpResponse.BodyHandler) sendAsync} is used instead of
 228  * {@link HttpClient#send(HttpRequest,HttpResponse.BodyHandler) send}
 229  * in which case the returned object is a {@link CompletableFuture}{@code <HttpResponse>}
 230  * instead of {@link HttpResponse}. The following example shows how multiple requests
 231  * can be sent asynchronously. It also shows how dependent asynchronous operations
 232  * (receiving response, and receiving response body) can be chained easily using
 233  * one of the many methods in {@code CompletableFuture}.
 234  * <pre>
 235  * {@code
 236  *  // fetch a list of target URIs asynchronously and store them in Files.
 237  *
 238  *      List<URI> targets = ...
 239  *
 240  *      List<CompletableFuture<File>> futures = targets
 241  *          .stream()
 242  *          .map(target -> client
 243  *                  .sendAsync(
 244  *                      HttpRequest.newBuilder(target)
 245  *                                 .GET()
 246  *                                 .build(),
 247  *                      BodyHandler.asFile(Paths.get("base", target.getPath())))
 248  *                  .thenApply(response -> response.body())
 249  *                  .thenApply(path -> path.toFile()))
 250  *          .collect(Collectors.toList());
 251  *
 252  *      // all async operations waited for here
 253  *
 254  *      CompletableFuture.allOf(futures.toArray(new CompletableFuture<?>[0]))
 255  *          .join();
 256  *
 257  *      // all elements of futures have completed and can be examined.
 258  *      // Use File.exists() to check whether file was successfully downloaded
 259  * }
 260  * </pre>
 261  *
 262  * <p> Unless otherwise stated, {@code null} parameter values will cause methods
 263  * of this class to throw {@code NullPointerException}.
 264  *
 265  * @since 9
 266  */
 267 public abstract class HttpRequest {
 268 
 269     /**
 270      * Creates an HttpRequest.
 271      */
 272     protected HttpRequest() {}
 273 
 274     /**
 275      * A builder of {@linkplain HttpRequest HTTP Requests}.
 276      * {@Incubating}
 277      *
 278      * <p> Instances of {@code HttpRequest.Builder} are created by calling {@link
 279      * HttpRequest#newBuilder(URI)} or {@link HttpRequest#newBuilder()}.
 280      *
 281      * <p> Each of the setter methods in this class modifies the state of the
 282      * builder and returns <i>this</i> (ie. the same instance). The methods are
 283      * not synchronized and should not be called from multiple threads without
 284      * external synchronization.
 285      *
 286      * <p> Note, that not all request headers may be set by user code. Some are
 287      * restricted for security reasons and others such as the headers relating
 288      * to authentication, redirection and cookie management are managed by
 289      * specific APIs rather than through directly user set headers.
 290      *
 291      * <p> The {@linkplain #build() build} method returns a new {@code
 292      * HttpRequest} each time it is invoked.
 293      *
 294      * @since 9
 295      */
 296     public abstract static class Builder {
 297 
 298         /**
 299          * Creates a Builder.
 300          */
 301         protected Builder() {}
 302 
 303         /**
 304          * Sets this {@code HttpRequest}'s request {@code URI}.
 305          *
 306          * @param uri the request URI
 307          * @return this request builder
 308          * @throws IllegalArgumentException if the {@code URI} scheme is not
 309          *         supported
 310          */
 311         public abstract Builder uri(URI uri);
 312 
 313         /**
 314          * Requests the server to acknowledge the request before sending the
 315          * body. This is disabled by default. If enabled, the server is
 316          * requested to send an error response or a {@code 100 Continue}
 317          * response before the client sends the request body. This means the
 318          * request publisher for the request will not be invoked until this
 319          * interim response is received.
 320          *
 321          * @param enable {@code true} if Expect continue to be sent
 322          * @return this request builder
 323          */
 324         public abstract Builder expectContinue(boolean enable);
 325 
 326         /**
 327          * Sets the preferred {@link HttpClient.Version} for this request.
 328          *
 329          * <p> The corresponding {@link HttpResponse} should be checked for the
 330          * version that was actually used. If the version is not set in a
 331          * request, then the version requested will be that of the sending
 332          * {@link HttpClient}.
 333          *
 334          * @param version the HTTP protocol version requested
 335          * @return this request builder
 336          */
 337         public abstract Builder version(HttpClient.Version version);
 338 
 339         /**
 340          * Adds the given name value pair to the set of headers for this request.
 341          * The given value is added to the list of values for that name.
 342          *
 343          * @param name the header name
 344          * @param value the header value
 345          * @return this request builder
 346          * @throws IllegalArgumentException if the header name or value is not
 347          *         valid, see <a href="https://tools.ietf.org/html/rfc7230#section-3.2">
 348          *         RFC 7230 section-3.2</a>
 349          */
 350         public abstract Builder header(String name, String value);
 351 
 352         /**
 353          * Adds the given name value pairs to the set of headers for this
 354          * request. The supplied {@code String} instances must alternate as
 355          * header names and header values.
 356          * To add several values to the same name then the same name must
 357          * be supplied with each new value.
 358          *
 359          * @param headers the list of name value pairs
 360          * @return this request builder
 361          * @throws IllegalArgumentException if there are an odd number of
 362          *         parameters, or if a header name or value is not valid, see
 363          *         <a href="https://tools.ietf.org/html/rfc7230#section-3.2">
 364          *         RFC 7230 section-3.2</a>
 365          */
 366         public abstract Builder headers(String... headers);
 367 
 368         /**
 369          * Sets a timeout for this request. If the response is not received
 370          * within the specified timeout then a {@link HttpTimeoutException} is
 371          * thrown from {@link HttpClient#send(jdk.incubator.http.HttpRequest,
 372          * jdk.incubator.http.HttpResponse.BodyHandler) HttpClient::send} or
 373          * {@link HttpClient#sendAsync(jdk.incubator.http.HttpRequest,
 374          * jdk.incubator.http.HttpResponse.BodyHandler) HttpClient::sendAsync}
 375          * completes exceptionally with a {@code HttpTimeoutException}. The effect
 376          * of not setting a timeout is the same as setting an infinite Duration, ie.
 377          * block forever.
 378          *
 379          * @param duration the timeout duration
 380          * @return this request builder
 381          * @throws IllegalArgumentException if the duration is non-positive
 382          */
 383         public abstract Builder timeout(Duration duration);
 384 
 385         /**
 386          * Sets the given name value pair to the set of headers for this
 387          * request. This overwrites any previously set values for name.
 388          *
 389          * @param name the header name
 390          * @param value the header value
 391          * @return this request builder
 392          * @throws IllegalArgumentException if the header name or value is not valid,
 393          *         see <a href="https://tools.ietf.org/html/rfc7230#section-3.2">
 394          *         RFC 7230 section-3.2</a>
 395          */
 396         public abstract Builder setHeader(String name, String value);
 397 
 398         /**
 399          * Sets the request method of this builder to GET.
 400          * This is the default.
 401          *
 402          * @return a {@code HttpRequest}
 403          */
 404         public abstract Builder GET();
 405 
 406         /**
 407          * Sets the request method of this builder to POST and sets its
 408          * request body publisher to the given value.
 409          *
 410          * @param bodyPublisher the body publisher
 411          *
 412          * @return a {@code HttpRequest}
 413          */
 414         public abstract Builder POST(BodyPublisher bodyPublisher);
 415 
 416         /**
 417          * Sets the request method of this builder to PUT and sets its
 418          * request body publisher to the given value.
 419          *
 420          * @param bodyPublisher the body publisher
 421          *
 422          * @return a {@code HttpRequest}
 423          */
 424         public abstract Builder PUT(BodyPublisher bodyPublisher);
 425 
 426         /**
 427          * Sets the request method of this builder to DELETE and sets its
 428          * request body publisher to the given value.
 429          *
 430          * @param bodyPublisher the body publisher
 431          *
 432          * @return a {@code HttpRequest}
 433          */
 434 
 435         public abstract Builder DELETE(BodyPublisher bodyPublisher);
 436 
 437         /**
 438          * Sets the request method and request body of this builder to the
 439          * given values.
 440          *
 441          * @apiNote The {@linkplain BodyPublisher#noBody() noBody} request
 442          * body publisher can be used where no request body is required or
 443          * appropriate.
 444          *
 445          * @param method the method to use
 446          * @param bodyPublisher the body publisher
 447          * @return a {@code HttpRequest}
 448          * @throws IllegalArgumentException if the method is unrecognised
 449          */
 450         public abstract Builder method(String method, BodyPublisher bodyPublisher);
 451 
 452         /**
 453          * Builds and returns a {@link HttpRequest}.
 454          *
 455          * @return the request
 456          * @throws IllegalStateException if a URI has not been set
 457          */
 458         public abstract HttpRequest build();
 459 
 460         /**
 461          * Returns an exact duplicate copy of this {@code Builder} based on
 462          * current state. The new builder can then be modified independently of
 463          * this builder.
 464          *
 465          * @return an exact copy of this Builder
 466          */
 467         public abstract Builder copy();
 468     }
 469 
 470     /**
 471      * Creates a {@code HttpRequest} builder.
 472      *
 473      * @param uri the request URI
 474      * @return a new request builder
 475      * @throws IllegalArgumentException if the URI scheme is not supported.
 476      */
 477     public static HttpRequest.Builder newBuilder(URI uri) {
 478         return new HttpRequestBuilderImpl(uri);
 479     }
 480 
 481     /**
 482      * Creates a {@code HttpRequest} builder.
 483      *
 484      * @return a new request builder
 485      */
 486     public static HttpRequest.Builder newBuilder() {
 487         return new HttpRequestBuilderImpl();
 488     }
 489 
 490     /**
 491      * Returns an {@code Optional} containing the {@link BodyPublisher} set on
 492      * this request. If no {@code BodyPublisher} was set in the requests's
 493      * builder, then the {@code Optional} is empty.
 494      *
 495      * @return an {@code Optional} containing this request's {@code BodyPublisher}
 496      */
 497     public abstract Optional<BodyPublisher> bodyPublisher();
 498 
 499     /**
 500      * Returns the request method for this request. If not set explicitly,
 501      * the default method for any request is "GET".
 502      *
 503      * @return this request's method
 504      */
 505     public abstract String method();
 506 
 507     /**
 508      * Returns an {@code Optional} containing this request's timeout duration.
 509      * If the timeout duration was not set in the request's builder, then the
 510      * {@code Optional} is empty.
 511      *
 512      * @return an {@code Optional} containing this request's timeout duration
 513      */
 514     public abstract Optional<Duration> timeout();
 515 
 516     /**
 517      * Returns this request's {@link HttpRequest.Builder#expectContinue(boolean)
 518      * expect continue } setting.
 519      *
 520      * @return this request's expect continue setting
 521      */
 522     public abstract boolean expectContinue();
 523 
 524     /**
 525      * Returns this request's request {@code URI}.
 526      *
 527      * @return this request's URI
 528      */
 529     public abstract URI uri();
 530 
 531     /**
 532      * Returns an {@code Optional} containing the HTTP protocol version that
 533      * will be requested for this {@code HttpRequest}. If the version was not
 534      * set in the request's builder, then the {@code Optional} is empty.
 535      * In that case, the version requested will be that of the sending
 536      * {@link HttpClient}. The corresponding {@link HttpResponse} should be
 537      * queried to determine the version that was actually used.
 538      *
 539      * @return HTTP protocol version
 540      */
 541     public abstract Optional<HttpClient.Version> version();
 542 
 543     /**
 544      * The (user-accessible) request headers that this request was (or will be)
 545      * sent with.
 546      *
 547      * @return this request's HttpHeaders
 548      */
 549     public abstract HttpHeaders headers();
 550 
 551     /**
 552      * Tests this HTTP request instance for equality with the given object.
 553      *
 554      * <p> If the given object is not an {@code HttpRequest} then this
 555      * method returns {@code false}. Two HTTP requests are equal if their URI,
 556      * method, and headers fields are all equal.
 557      *
 558      * <p> This method satisfies the general contract of the {@link
 559      * Object#equals(Object) Object.equals} method.
 560      *
 561      * @param obj the object to which this object is to be compared
 562      * @return {@code true} if, and only if, the given object is an {@code
 563      *         HttpRequest} that is equal to this HTTP request
 564      */
 565     @Override
 566     public final boolean equals(Object obj) {
 567        if (! (obj instanceof HttpRequest))
 568            return false;
 569        HttpRequest that = (HttpRequest)obj;
 570        if (!that.method().equals(this.method()))
 571            return false;
 572        if (!that.uri().equals(this.uri()))
 573            return false;
 574        if (!that.headers().equals(this.headers()))
 575            return false;
 576        return true;
 577     }
 578 
 579     /**
 580      * Computes a hash code for this HTTP request instance.
 581      *
 582      * <p> The hash code is based upon the HTTP request's URI, method, and
 583      * header components, and satisfies the general contract of the
 584      * {@link Object#hashCode Object.hashCode} method.
 585      *
 586      * @return the hash-code value for this HTTP request
 587      */
 588     public final int hashCode() {
 589         return method().hashCode()
 590                 + uri().hashCode()
 591                 + headers().hashCode();
 592     }
 593 
 594     /**
 595      * A Publisher which converts high level Java objects into flows of
 596      * byte buffers suitable for sending as request bodies.
 597      * {@Incubating}
 598      *
 599      * <p> The {@code BodyPublisher} class implements {@link Flow.Publisher
 600      * Flow.Publisher&lt;ByteBuffer&gt;} which means that a {@code BodyPublisher}
 601      * acts as a publisher of {@linkplain ByteBuffer byte buffers}.
 602      *
 603      * <p> The HTTP client implementation subscribes to the publisher in order
 604      * to receive the flow of outgoing data buffers. The normal semantics of
 605      * {@link Flow.Subscriber} and {@link Flow.Publisher} are implemented by the
 606      * library and are expected from publisher implementations. Each outgoing
 607      * request results in one {@code Subscriber} subscribing to the {@code
 608      * BodyPublisher} in order to provide the sequence of byte buffers
 609      * containing the request body.
 610      * Instances of {@code ByteBuffer} published  by the publisher must be
 611      * allocated by the publisher, and must not be accessed after being handed
 612      * over to the library.
 613      * These subscriptions complete normally when the request is fully sent,
 614      * and can be canceled or terminated early through error. If a request
 615      * needs to be resent for any reason, then a new subscription is created
 616      * which is expected to generate the same data as before.
 617      *
 618      * <p> A publisher that reports a {@linkplain #contentLength() content
 619      * length} of {@code 0} may not be subscribed to by the HTTP client
 620      * implementation, as it has effectively no data to publish.
 621      */
 622     public interface BodyPublisher extends Flow.Publisher<ByteBuffer> {
 623 
 624         /**
 625          * Returns a request body publisher whose body is the given {@code
 626          * String}, converted using the {@link StandardCharsets#UTF_8 UTF_8}
 627          * character set.
 628          *
 629          * @param body the String containing the body
 630          * @return a BodyPublisher
 631          */
 632         static BodyPublisher fromString(String body) {
 633             return fromString(body, UTF_8);
 634         }
 635 
 636         /**
 637          * Returns a request body publisher whose body is the given {@code
 638          * String}, converted using the given character set.
 639          *
 640          * @param s the String containing the body
 641          * @param charset the character set to convert the string to bytes
 642          * @return a BodyPublisher
 643          */
 644         static BodyPublisher fromString(String s, Charset charset) {
 645             return new RequestPublishers.StringPublisher(s, charset);
 646         }
 647 
 648         /**
 649          * A request body publisher that reads its data from an {@link
 650          * InputStream}. A {@link Supplier} of {@code InputStream} is used in
 651          * case the request needs to be repeated, as the content is not buffered.
 652          * The {@code Supplier} may return {@code null} on subsequent attempts,
 653          * in which case the request fails.
 654          *
 655          * @param streamSupplier a Supplier of open InputStreams
 656          * @return a BodyPublisher
 657          */
 658         // TODO (spec): specify that the stream will be closed
 659         static BodyPublisher fromInputStream(Supplier<? extends InputStream> streamSupplier) {
 660             return new RequestPublishers.InputStreamPublisher(streamSupplier);
 661         }
 662 
 663         /**
 664          * Returns a request body publisher whose body is the given byte array.
 665          *
 666          * @param buf the byte array containing the body
 667          * @return a BodyPublisher
 668          */
 669         static BodyPublisher fromByteArray(byte[] buf) {
 670             return new RequestPublishers.ByteArrayPublisher(buf);
 671         }
 672 
 673         /**
 674          * Returns a request body publisher whose body is the content of the
 675          * given byte array of {@code length} bytes starting from the specified
 676          * {@code offset}.
 677          *
 678          * @param buf the byte array containing the body
 679          * @param offset the offset of the first byte
 680          * @param length the number of bytes to use
 681          * @return a BodyPublisher
 682          * @throws IndexOutOfBoundsException if the sub-range is defined to be
 683          *                                   out-of-bounds
 684          */
 685         static BodyPublisher fromByteArray(byte[] buf, int offset, int length) {
 686             Objects.checkFromIndexSize(offset, length, buf.length);
 687             return new RequestPublishers.ByteArrayPublisher(buf, offset, length);
 688         }
 689 
 690         private static String pathForSecurityCheck(Path path) {
 691             return path.toFile().getPath();
 692         }
 693 
 694         /**
 695          * A request body publisher that takes data from the contents of a File.
 696          *
 697          * @param path the path to the file containing the body
 698          * @return a BodyPublisher
 699          * @throws java.io.FileNotFoundException if the path is not found
 700          * @throws SecurityException if a security manager has been installed
 701          *          and it denies {@link SecurityManager#checkRead(String)
 702          *          read access} to the given file
 703          */
 704         static BodyPublisher fromFile(Path path) throws FileNotFoundException {
 705             Objects.requireNonNull(path);
 706             SecurityManager sm = System.getSecurityManager();
 707             if (sm != null)
 708                 sm.checkRead(pathForSecurityCheck(path));
 709             if (Files.notExists(path))
 710                 throw new FileNotFoundException(path + " not found");
 711             return new RequestPublishers.FilePublisher(path);
 712         }
 713 
 714         /**
 715          * A request body publisher that takes data from an {@code Iterable}
 716          * of byte arrays. An {@link Iterable} is provided which supplies
 717          * {@link Iterator} instances. Each attempt to send the request results
 718          * in one invocation of the {@code Iterable}.
 719          *
 720          * @param iter an Iterable of byte arrays
 721          * @return a BodyPublisher
 722          */
 723         static BodyPublisher fromByteArrays(Iterable<byte[]> iter) {
 724             return new RequestPublishers.IterablePublisher(iter);
 725         }
 726 
 727         /**
 728          * A request body publisher which sends no request body.
 729          *
 730          * @return a BodyPublisher which completes immediately and sends
 731          *         no request body.
 732          */
 733         static BodyPublisher noBody() {
 734             return new RequestPublishers.EmptyPublisher();
 735         }
 736 
 737         /**
 738          * Returns the content length for this request body. May be zero
 739          * if no request body being sent, greater than zero for a fixed
 740          * length content, or less than zero for an unknown content length.
 741          *
 742          * This method may be invoked before the publisher is subscribed to.
 743          * This method may be invoked more than once by the HTTP client
 744          * implementation, and MUST return the same constant value each time.
 745          *
 746          * @return the content length for this request body, if known
 747          */
 748         long contentLength();
 749     }
 750 }