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.IOException;
  29 import java.io.InputStream;
  30 import java.net.URI;
  31 import jdk.incubator.http.ResponseSubscribers.MultiSubscriberImpl;
  32 import static jdk.incubator.http.internal.common.Utils.unchecked;
  33 import static jdk.incubator.http.internal.common.Utils.charsetFrom;
  34 import java.nio.ByteBuffer;
  35 import java.nio.charset.Charset;
  36 import java.nio.channels.FileChannel;
  37 import java.nio.file.OpenOption;
  38 import java.nio.file.Path;
  39 import java.nio.file.Paths;
  40 import java.nio.file.StandardOpenOption;
  41 import java.security.AccessControlContext;
  42 import java.util.Arrays;
  43 import java.util.List;
  44 import java.util.Objects;
  45 import java.util.Optional;
  46 import java.util.concurrent.CompletableFuture;
  47 import java.util.concurrent.CompletionStage;
  48 import java.util.concurrent.Flow;
  49 import java.util.function.Consumer;
  50 import java.util.function.Function;
  51 import javax.net.ssl.SSLParameters;
  52 
  53 /**
  54  * Represents a response to a {@link HttpRequest}.
  55  * {@Incubating}
  56  *
  57  * <p> A {@code HttpResponse} is available when the response status code and
  58  * headers have been received, and typically after the response body has also
  59  * been received. This depends on the response body handler provided when
  60  * sending the request. In all cases, the response body handler is invoked
  61  * before the body is read. This gives applications an opportunity to decide
  62  * how to handle the body.
  63  *
  64  * <p> Methods are provided in this class for accessing the response headers,
  65  * and response body.
  66  *
  67  * <p><b>Response handlers and subscribers</b>
  68  *
  69  * <p> Response bodies are handled at two levels. Application code supplies a
  70  * response handler ({@link BodyHandler}) which may examine the response status
  71  * code and headers, and which then returns a {@link BodySubscriber} to actually
  72  * read (or discard) the body and convert it into some useful Java object type.
  73  * The handler can return one of the pre-defined subscriber types, or a custom
  74  * subscriber, or if the body is to be discarded it can call {@link
  75  * BodySubscriber#discard(Object) discard} and return a subscriber which
  76  * discards the response body. Static implementations of both handlers and
  77  * subscribers are provided in {@linkplain BodyHandler BodyHandler} and
  78  * {@linkplain BodySubscriber BodySubscriber} respectively. In all cases, the
  79  * handler functions provided are convenience implementations which ignore the
  80  * supplied status code and headers and return the relevant pre-defined {@code
  81  * BodySubscriber}.
  82  *
  83  * <p> See {@link BodyHandler} for example usage.
  84  *
  85  * @param <T> the response body type
  86  * @since 9
  87  */
  88 public abstract class HttpResponse<T> {
  89 
  90     /**
  91      * Creates an HttpResponse.
  92      */
  93     protected HttpResponse() { }
  94 
  95     /**
  96      * Returns the status code for this response.
  97      *
  98      * @return the response code
  99      */
 100     public abstract int statusCode();
 101 
 102     /**
 103      * Returns the {@link HttpRequest} corresponding to this response.
 104      *
 105      * <p> This may not be the original request provided by the caller,
 106      * for example, if that request was redirected.
 107      *
 108      * @see #previousResponse()
 109      *
 110      * @return the request
 111      */
 112     public abstract HttpRequest request();
 113 
 114     /**
 115      * Returns an {@code Optional} containing the previous intermediate response
 116      * if one was received. An intermediate response is one that is received
 117      * as a result of redirection or authentication. If no previous response
 118      * was received then an empty {@code Optional} is returned.
 119      *
 120      * @return an Optional containing the HttpResponse, if any.
 121      */
 122     public abstract Optional<HttpResponse<T>> previousResponse();
 123 
 124     /**
 125      * Returns the received response headers.
 126      *
 127      * @return the response headers
 128      */
 129     public abstract HttpHeaders headers();
 130 
 131     /**
 132      * Returns the body. Depending on the type of {@code T}, the returned body
 133      * may represent the body after it was read (such as {@code byte[]}, or
 134      * {@code String}, or {@code Path}) or it may represent an object with
 135      * which the body is read, such as an {@link java.io.InputStream}.
 136      *
 137      * <p> If this {@code HttpResponse} was returned from an invocation of
 138      * {@link #previousResponse()} then this method returns {@code null}
 139      *
 140      * @return the body
 141      */
 142     public abstract T body();
 143 
 144     /**
 145      * Returns the {@link javax.net.ssl.SSLParameters} in effect for this
 146      * response. Returns {@code null} if this is not a HTTPS response.
 147      *
 148      * @return the SSLParameters associated with the response
 149      */
 150     public abstract SSLParameters sslParameters();
 151 
 152     /**
 153      * Returns the {@code URI} that the response was received from. This may be
 154      * different from the request {@code URI} if redirection occurred.
 155      *
 156      * @return the URI of the response
 157      */
 158     public abstract URI uri();
 159 
 160     /**
 161      * Returns the HTTP protocol version that was used for this response.
 162      *
 163      * @return HTTP protocol version
 164      */
 165     public abstract HttpClient.Version version();
 166 
 167 
 168     private static String pathForSecurityCheck(Path path) {
 169         return path.toFile().getPath();
 170     }
 171 
 172     /** A body handler that is further restricted by a given ACC. */
 173     interface UntrustedBodyHandler<T> extends BodyHandler<T> {
 174         void setAccessControlContext(AccessControlContext acc);
 175     }
 176 
 177     /**
 178      * A Path body handler.
 179      *
 180      * Note: Exists mainly too allow setting of the senders ACC post creation of
 181      * the handler.
 182      */
 183     static class PathBodyHandler implements UntrustedBodyHandler<Path> {
 184         private final Path file;
 185         private final OpenOption[]openOptions;
 186         private volatile AccessControlContext acc;
 187 
 188         PathBodyHandler(Path file, OpenOption... openOptions) {
 189             this.file = file;
 190             this.openOptions = openOptions;
 191         }
 192 
 193         @Override
 194         public void setAccessControlContext(AccessControlContext acc) {
 195             this.acc = acc;
 196         }
 197 
 198         @Override
 199         public BodySubscriber<Path> apply(int statusCode, HttpHeaders headers) {
 200             ResponseSubscribers.PathSubscriber bs = (ResponseSubscribers.PathSubscriber)
 201                     BodySubscriber.asFileImpl(file, openOptions);
 202             bs.setAccessControlContext(acc);
 203             return bs;
 204         }
 205     }
 206 
 207     // Similar to Path body handler, but for file download. Supports setting ACC.
 208     static class FileDownloadBodyHandler implements UntrustedBodyHandler<Path> {
 209         private final Path directory;
 210         private final OpenOption[]openOptions;
 211         private volatile AccessControlContext acc;
 212 
 213         FileDownloadBodyHandler(Path directory, OpenOption... openOptions) {
 214             this.directory = directory;
 215             this.openOptions = openOptions;
 216         }
 217 
 218         @Override
 219         public void setAccessControlContext(AccessControlContext acc) {
 220             this.acc = acc;
 221         }
 222 
 223         @Override
 224         public BodySubscriber<Path> apply(int statusCode, HttpHeaders headers) {
 225             String dispoHeader = headers.firstValue("Content-Disposition")
 226                     .orElseThrow(() -> unchecked(new IOException("No Content-Disposition")));
 227             if (!dispoHeader.startsWith("attachment;")) {
 228                 throw unchecked(new IOException("Unknown Content-Disposition type"));
 229             }
 230             int n = dispoHeader.indexOf("filename=");
 231             if (n == -1) {
 232                 throw unchecked(new IOException("Bad Content-Disposition type"));
 233             }
 234             int lastsemi = dispoHeader.lastIndexOf(';');
 235             String disposition;
 236             if (lastsemi < n) {
 237                 disposition = dispoHeader.substring(n + 9);
 238             } else {
 239                 disposition = dispoHeader.substring(n + 9, lastsemi);
 240             }
 241             Path file = Paths.get(directory.toString(), disposition);
 242 
 243             ResponseSubscribers.PathSubscriber bs = (ResponseSubscribers.PathSubscriber)
 244                     BodySubscriber.asFileImpl(file, openOptions);
 245             bs.setAccessControlContext(acc);
 246             return bs;
 247         }
 248     }
 249 
 250     /**
 251      * A handler for response bodies.
 252      * {@Incubating}
 253      *
 254      * <p> This is a function that takes two parameters: the response status code,
 255      * and the response headers, and which returns a {@linkplain BodySubscriber}.
 256      * The function is always called just before the response body is read. Its
 257      * implementation may examine the status code or headers and must decide,
 258      * whether to accept the response body or discard it, and if accepting it,
 259      * exactly how to handle it.
 260      *
 261      * <p> Some pre-defined implementations which do not utilize the status code
 262      * or headers (meaning the body is always accepted) are defined:
 263      * <ul><li>{@link #asByteArray() }</li>
 264      * <li>{@link #asByteArrayConsumer(java.util.function.Consumer)
 265      * asByteArrayConsumer(Consumer)}</li>
 266      * <li>{@link #asString(java.nio.charset.Charset) asString(Charset)}</li>
 267      * <li>{@link #asFile(Path, OpenOption...)
 268      * asFile(Path,OpenOption...)}</li>
 269      * <li>{@link #asFileDownload(java.nio.file.Path,OpenOption...)
 270      * asFileDownload(Path,OpenOption...)}</li>
 271      * <li>{@link #asInputStream() asInputStream()}</li>
 272      * <li>{@link #discard(Object) }</li>
 273      * <li>{@link #buffering(BodyHandler, int)
 274      * buffering(BodyHandler,int)}</li>
 275      * </ul>
 276      *
 277      * <p> These implementations return the equivalent {@link BodySubscriber}.
 278      * Alternatively, the handler can be used to examine the status code
 279      * or headers and return different body subscribers as appropriate.
 280      *
 281      * <p><b>Examples of handler usage</b>
 282      *
 283      * <p> The first example uses one of the predefined handler functions which
 284      * ignores the response headers and status, and always process the response
 285      * body in the same way.
 286      * <pre>
 287      * {@code
 288      *      HttpResponse<Path> resp = HttpRequest
 289      *              .create(URI.create("http://www.foo.com"))
 290      *              .GET()
 291      *              .response(BodyHandler.asFile(Paths.get("/tmp/f")));
 292      * }
 293      * </pre>
 294      * Note, that even though these pre-defined handlers ignore the status code
 295      * and headers, this information is still accessible from the
 296      * {@code HttpResponse} when it is returned.
 297      *
 298      * <p> In the second example, the function returns a different subscriber
 299      * depending on the status code.
 300      * <pre>
 301      * {@code
 302      *      HttpResponse<Path> resp1 = HttpRequest
 303      *              .create(URI.create("http://www.foo.com"))
 304      *              .GET()
 305      *              .response(
 306      *                  (status, headers) -> status == 200
 307      *                      ? BodySubscriber.asFile(Paths.get("/tmp/f"))
 308      *                      : BodySubscriber.discard(Paths.get("/NULL")));
 309      * }
 310      * </pre>
 311      *
 312      * @param <T> the response body type
 313      */
 314     @FunctionalInterface
 315     public interface BodyHandler<T> {
 316 
 317         /**
 318          * Returns a {@link BodySubscriber BodySubscriber} considering the given
 319          * response status code and headers. This method is always called before
 320          * the body is read and its implementation can decide to keep the body
 321          * and store it somewhere, or else discard it by returning the {@code
 322          * BodySubscriber} returned from {@link BodySubscriber#discard(Object)
 323          * discard}.
 324          *
 325          * @param statusCode the HTTP status code received
 326          * @param responseHeaders the response headers received
 327          * @return a body subscriber
 328          */
 329         public BodySubscriber<T> apply(int statusCode, HttpHeaders responseHeaders);
 330 
 331         /**
 332          * Returns a response body handler which discards the response body and
 333          * uses the given value as a replacement for it.
 334          *
 335          * @param <U> the response body type
 336          * @param value the value of U to return as the body, may be {@code null}
 337          * @return a response body handler
 338          */
 339         public static <U> BodyHandler<U> discard(U value) {
 340             return (status, headers) -> BodySubscriber.discard(value);
 341         }
 342 
 343         /**
 344          * Returns a {@code BodyHandler<String>} that returns a
 345          * {@link BodySubscriber BodySubscriber}{@code <String>} obtained from
 346          * {@link BodySubscriber#asString(Charset) BodySubscriber.asString(Charset)}.
 347          * If a charset is provided, the body is decoded using it. If charset is
 348          * {@code null} then the handler tries to determine the character set
 349          * from the {@code Content-encoding} header. If that charset is not
 350          * supported then {@link java.nio.charset.StandardCharsets#UTF_8 UTF_8}
 351          * is used.
 352          *
 353          * @param charset The name of the charset to interpret the body as. If
 354          *                {@code null} then the charset is determined from the
 355          *                <i>Content-encoding</i> header.
 356          * @return a response body handler
 357          */
 358         public static BodyHandler<String> asString(Charset charset) {
 359             return (status, headers) -> {
 360                 if (charset != null) {
 361                     return BodySubscriber.asString(charset);
 362                 }
 363                 return BodySubscriber.asString(charsetFrom(headers));
 364             };
 365         }
 366 
 367         /**
 368          * Returns a {@code BodyHandler<Path>} that returns a
 369          * {@link BodySubscriber BodySubscriber}{@code <Path>} obtained from
 370          * {@link BodySubscriber#asFile(Path, OpenOption...)
 371          * BodySubscriber.asFile(Path,OpenOption...)}.
 372          *
 373          * <p> When the {@code HttpResponse} object is returned, the body has
 374          * been completely written to the file, and {@link #body()} returns a
 375          * reference to its {@link Path}.
 376          *
 377          * @param file the filename to store the body in
 378          * @param openOptions any options to use when opening/creating the file
 379          * @return a response body handler
 380          * @throws SecurityException If a security manager has been installed
 381          *          and it denies {@link SecurityManager#checkWrite(String)
 382          *          write access} to the file. The {@link
 383          *          SecurityManager#checkDelete(String) checkDelete} method is
 384          *          invoked to check delete access if the file is opened with
 385          *          the {@code DELETE_ON_CLOSE} option.
 386          */
 387         public static BodyHandler<Path> asFile(Path file, OpenOption... openOptions) {
 388             Objects.requireNonNull(file);
 389             SecurityManager sm = System.getSecurityManager();
 390             if (sm != null) {
 391                 String fn = pathForSecurityCheck(file);
 392                 sm.checkWrite(fn);
 393                 List<OpenOption> opts = Arrays.asList(openOptions);
 394                 if (opts.contains(StandardOpenOption.DELETE_ON_CLOSE))
 395                     sm.checkDelete(fn);
 396                 if (opts.contains(StandardOpenOption.READ))
 397                     sm.checkRead(fn);
 398             }
 399             return new PathBodyHandler(file, openOptions);
 400         }
 401 
 402         /**
 403          * Returns a {@code BodyHandler<Path>} that returns a
 404          * {@link BodySubscriber BodySubscriber}{@code <Path>} obtained from
 405          * {@link BodySubscriber#asFile(Path) BodySubscriber.asFile(Path)}.
 406          *
 407          * <p> When the {@code HttpResponse} object is returned, the body has
 408          * been completely written to the file, and {@link #body()} returns a
 409          * reference to its {@link Path}.
 410          *
 411          * @param file the file to store the body in
 412          * @return a response body handler
 413          * @throws SecurityException if a security manager has been installed
 414          *          and it denies {@link SecurityManager#checkWrite(String)
 415          *          write access} to the file
 416          */
 417         public static BodyHandler<Path> asFile(Path file) {
 418             return BodyHandler.asFile(file, StandardOpenOption.CREATE,
 419                                             StandardOpenOption.WRITE);
 420         }
 421 
 422         /**
 423          * Returns a {@code BodyHandler<Path>} that returns a
 424          * {@link BodySubscriber BodySubscriber}&lt;{@link Path}&gt;
 425          * where the download directory is specified, but the filename is
 426          * obtained from the {@code Content-Disposition} response header. The
 427          * {@code Content-Disposition} header must specify the <i>attachment</i>
 428          * type and must also contain a <i>filename</i> parameter. If the
 429          * filename specifies multiple path components only the final component
 430          * is used as the filename (with the given directory name).
 431          *
 432          * <p> When the {@code HttpResponse} object is returned, the body has
 433          * been completely written to the file and {@link #body()} returns a
 434          * {@code Path} object for the file. The returned {@code Path} is the
 435          * combination of the supplied directory name and the file name supplied
 436          * by the server. If the destination directory does not exist or cannot
 437          * be written to, then the response will fail with an {@link IOException}.
 438          *
 439          * @param directory the directory to store the file in
 440          * @param openOptions open options
 441          * @return a response body handler
 442          * @throws SecurityException If a security manager has been installed
 443          *          and it denies {@link SecurityManager#checkWrite(String)
 444          *          write access} to the file. The {@link
 445          *          SecurityManager#checkDelete(String) checkDelete} method is
 446          *          invoked to check delete access if the file is opened with
 447          *          the {@code DELETE_ON_CLOSE} option.
 448          */
 449          //####: check if the dir exists and is writable??
 450         public static BodyHandler<Path> asFileDownload(Path directory,
 451                                                        OpenOption... openOptions) {
 452             Objects.requireNonNull(directory);
 453             SecurityManager sm = System.getSecurityManager();
 454             if (sm != null) {
 455                 String fn = pathForSecurityCheck(directory);
 456                 sm.checkWrite(fn);
 457                 List<OpenOption> opts = Arrays.asList(openOptions);
 458                 if (opts.contains(StandardOpenOption.DELETE_ON_CLOSE))
 459                     sm.checkDelete(fn);
 460                 if (opts.contains(StandardOpenOption.READ))
 461                     sm.checkRead(fn);
 462             }
 463             return new FileDownloadBodyHandler(directory, openOptions);
 464         }
 465 
 466         /**
 467          * Returns a {@code BodyHandler<InputStream>} that returns a
 468          * {@link BodySubscriber BodySubscriber}{@code <InputStream>} obtained
 469          * from {@link BodySubscriber#asInputStream() BodySubscriber.asInputStream}.
 470          *
 471          * <p> When the {@code HttpResponse} object is returned, the response
 472          * headers will have been completely read, but the body may not have
 473          * been fully received yet. The {@link #body()} method returns an
 474          * {@link InputStream} from which the body can be read as it is received.
 475          *
 476          * @apiNote See {@link BodySubscriber#asInputStream()} for more information.
 477          *
 478          * @return a response body handler
 479          */
 480         public static BodyHandler<InputStream> asInputStream() {
 481             return (status, headers) -> BodySubscriber.asInputStream();
 482         }
 483 
 484         /**
 485          * Returns a {@code BodyHandler<Void>} that returns a
 486          * {@link BodySubscriber BodySubscriber}{@code <Void>} obtained from
 487          * {@link BodySubscriber#asByteArrayConsumer(Consumer)
 488          * BodySubscriber.asByteArrayConsumer(Consumer)}.
 489          *
 490          * <p> When the {@code HttpResponse} object is returned, the body has
 491          * been completely written to the consumer.
 492          *
 493          * @param consumer a Consumer to accept the response body
 494          * @return a response body handler
 495          */
 496         public static BodyHandler<Void> asByteArrayConsumer(Consumer<Optional<byte[]>> consumer) {
 497             return (status, headers) -> BodySubscriber.asByteArrayConsumer(consumer);
 498         }
 499 
 500         /**
 501          * Returns a {@code BodyHandler<byte[]>} that returns a
 502          * {@link BodySubscriber BodySubscriber}&lt;{@code byte[]}&gt; obtained
 503          * from {@link BodySubscriber#asByteArray() BodySubscriber.asByteArray()}.
 504          *
 505          * <p> When the {@code HttpResponse} object is returned, the body has
 506          * been completely written to the byte array.
 507          *
 508          * @return a response body handler
 509          */
 510         public static BodyHandler<byte[]> asByteArray() {
 511             return (status, headers) -> BodySubscriber.asByteArray();
 512         }
 513 
 514         /**
 515          * Returns a {@code BodyHandler<String>} that returns a
 516          * {@link BodySubscriber BodySubscriber}{@code <String>} obtained from
 517          * {@link BodySubscriber#asString(java.nio.charset.Charset)
 518          * BodySubscriber.asString(Charset)}. The body is
 519          * decoded using the character set specified in
 520          * the {@code Content-encoding} response header. If there is no such
 521          * header, or the character set is not supported, then
 522          * {@link java.nio.charset.StandardCharsets#UTF_8 UTF_8} is used.
 523          *
 524          * <p> When the {@code HttpResponse} object is returned, the body has
 525          * been completely written to the string.
 526          *
 527          * @return a response body handler
 528          */
 529         public static BodyHandler<String> asString() {
 530             return (status, headers) -> BodySubscriber.asString(charsetFrom(headers));
 531         }
 532 
 533         /**
 534          * Returns a {@code BodyHandler} which, when invoked, returns a {@linkplain
 535          * BodySubscriber#buffering(BodySubscriber,int) buffering BodySubscriber}
 536          * that buffers data before delivering it to the downstream subscriber.
 537          * These {@code BodySubscriber} instances are created by calling
 538          * {@linkplain BodySubscriber#buffering(BodySubscriber,int)
 539          * BodySubscriber.buffering} with a subscriber obtained from the given
 540          * downstream handler and the {@code bufferSize} parameter.
 541          *
 542          * @param downstreamHandler the downstream handler
 543          * @param bufferSize the buffer size parameter passed to {@linkplain
 544          *        BodySubscriber#buffering(BodySubscriber,int) BodySubscriber.buffering}
 545          * @return a body handler
 546          * @throws IllegalArgumentException if {@code bufferSize <= 0}
 547          */
 548          public static <T> BodyHandler<T> buffering(BodyHandler<T> downstreamHandler,
 549                                                     int bufferSize) {
 550              if (bufferSize <= 0)
 551                  throw new IllegalArgumentException("must be greater than 0");
 552              return (status, headers) -> BodySubscriber
 553                      .buffering(downstreamHandler.apply(status, headers),
 554                                 bufferSize);
 555          }
 556     }
 557 
 558     /**
 559      * A subscriber for response bodies.
 560      * {@Incubating}
 561      *
 562      * <p> The object acts as a {@link Flow.Subscriber}&lt;{@link List}&lt;{@link
 563      * ByteBuffer}&gt;&gt; to the HTTP client implementation, which publishes
 564      * unmodifiable lists of ByteBuffers containing the response body. The Flow
 565      * of data, as well as the order of ByteBuffers in the Flow lists, is a
 566      * strictly ordered representation of the response body. Both the Lists and
 567      * the ByteBuffers, once passed to the subscriber, are no longer used by the
 568      * HTTP client. The subscriber converts the incoming buffers of data to some
 569      * user-defined object type {@code T}.
 570      *
 571      * <p> The {@link #getBody()} method returns a {@link CompletionStage}{@code
 572      * <T>} that provides the response body object. The {@code CompletionStage}
 573      * must be obtainable at any time. When it completes depends on the nature
 574      * of type {@code T}. In many cases, when {@code T} represents the entire
 575      * body after being read then it completes after the body has been read. If
 576      * {@code T} is a streaming type such as {@link java.io.InputStream} then it
 577      * completes before the body has been read, because the calling code uses it
 578      * to consume the data.
 579      *
 580      * @apiNote To ensure that all resources associated with the
 581      * corresponding exchange are properly released, an implementation
 582      * of {@code BodySubscriber} must ensure to {@linkplain
 583      * Flow.Subscription#request request} more data until {@link
 584      * #onComplete() onComplete} or {@link #onError(Throwable) onError}
 585      * are signalled, or {@linkplain Flow.Subscription#request cancel} its
 586      * {@linkplain #onSubscribe(Flow.Subscription) subscription}
 587      * if unable or unwilling to do so.
 588      * Calling {@code cancel} before exhausting the data may cause
 589      * the underlying HTTP connection to be closed and prevent it
 590      * from being reused for subsequent operations.
 591      *
 592      * @param <T> the response body type
 593      */
 594     public interface BodySubscriber<T>
 595             extends Flow.Subscriber<List<ByteBuffer>> {
 596 
 597         /**
 598          * Returns a {@code CompletionStage} which when completed will return
 599          * the response body object.
 600          *
 601          * @return a CompletionStage for the response body
 602          */
 603         public CompletionStage<T> getBody();
 604 
 605         /**
 606          * Returns a body subscriber which stores the response body as a {@code
 607          * String} converted using the given {@code Charset}.
 608          *
 609          * <p> The {@link HttpResponse} using this subscriber is available after
 610          * the entire response has been read.
 611          *
 612          * @param charset the character set to convert the String with
 613          * @return a body subscriber
 614          */
 615         public static BodySubscriber<String> asString(Charset charset) {
 616             return new ResponseSubscribers.ByteArraySubscriber<>(
 617                     bytes -> new String(bytes, charset)
 618             );
 619         }
 620 
 621         /**
 622          * Returns a {@code BodySubscriber} which stores the response body as a
 623          * byte array.
 624          *
 625          * <p> The {@link HttpResponse} using this subscriber is available after
 626          * the entire response has been read.
 627          *
 628          * @return a body subscriber
 629          */
 630         public static BodySubscriber<byte[]> asByteArray() {
 631             return new ResponseSubscribers.ByteArraySubscriber<>(
 632                     Function.identity() // no conversion
 633             );
 634         }
 635 
 636         // no security check
 637         private static BodySubscriber<Path> asFileImpl(Path file, OpenOption... openOptions) {
 638             return new ResponseSubscribers.PathSubscriber(file, openOptions);
 639         }
 640 
 641         /**
 642          * Returns a {@code BodySubscriber} which stores the response body in a
 643          * file opened with the given options and name. The file will be opened
 644          * with the given options using {@link FileChannel#open(Path,OpenOption...)
 645          * FileChannel.open} just before the body is read. Any exception thrown
 646          * will be returned or thrown from {@link HttpClient#send(HttpRequest,
 647          * BodyHandler) HttpClient::send} or {@link HttpClient#sendAsync(HttpRequest,
 648          * BodyHandler) HttpClient::sendAsync} as appropriate.
 649          *
 650          * <p> The {@link HttpResponse} using this subscriber is available after
 651          * the entire response has been read.
 652          *
 653          * @param file the file to store the body in
 654          * @param openOptions the list of options to open the file with
 655          * @return a body subscriber
 656          * @throws SecurityException If a security manager has been installed
 657          *          and it denies {@link SecurityManager#checkWrite(String)
 658          *          write access} to the file. The {@link
 659          *          SecurityManager#checkDelete(String) checkDelete} method is
 660          *          invoked to check delete access if the file is opened with the
 661          *          {@code DELETE_ON_CLOSE} option.
 662          */
 663         public static BodySubscriber<Path> asFile(Path file, OpenOption... openOptions) {
 664             Objects.requireNonNull(file);
 665             SecurityManager sm = System.getSecurityManager();
 666             if (sm != null) {
 667                 String fn = pathForSecurityCheck(file);
 668                 sm.checkWrite(fn);
 669                 List<OpenOption> opts = Arrays.asList(openOptions);
 670                 if (opts.contains(StandardOpenOption.DELETE_ON_CLOSE))
 671                     sm.checkDelete(fn);
 672                 if (opts.contains(StandardOpenOption.READ))
 673                     sm.checkRead(fn);
 674             }
 675             return asFileImpl(file, openOptions);
 676         }
 677 
 678         /**
 679          * Returns a {@code BodySubscriber} which stores the response body in a
 680          * file opened with the given name. Has the same effect as calling
 681          * {@link #asFile(Path, OpenOption...) asFile} with the standard open
 682          * options {@code CREATE} and {@code WRITE}
 683          *
 684          * <p> The {@link HttpResponse} using this subscriber is available after
 685          * the entire response has been read.
 686          *
 687          * @param file the file to store the body in
 688          * @return a body subscriber
 689          * @throws SecurityException if a security manager has been installed
 690          *          and it denies {@link SecurityManager#checkWrite(String)
 691          *          write access} to the file
 692          */
 693         public static BodySubscriber<Path> asFile(Path file) {
 694             return asFile(file, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
 695         }
 696 
 697         /**
 698          * Returns a {@code BodySubscriber} which provides the incoming body
 699          * data to the provided Consumer of {@code Optional<byte[]>}. Each
 700          * call to {@link Consumer#accept(java.lang.Object) Consumer.accept()}
 701          * will contain a non empty {@code Optional}, except for the final
 702          * invocation after all body data has been read, when the {@code
 703          * Optional} will be empty.
 704          *
 705          * <p> The {@link HttpResponse} using this subscriber is available after
 706          * the entire response has been read.
 707          *
 708          * @param consumer a Consumer of byte arrays
 709          * @return a BodySubscriber
 710          */
 711         public static BodySubscriber<Void> asByteArrayConsumer(Consumer<Optional<byte[]>> consumer) {
 712             return new ResponseSubscribers.ConsumerSubscriber(consumer);
 713         }
 714 
 715         /**
 716          * Returns a {@code BodySubscriber} which streams the response body as
 717          * an {@link InputStream}.
 718          *
 719          * <p> The {@link HttpResponse} using this subscriber is available
 720          * immediately after the response headers have been read, without
 721          * requiring to wait for the entire body to be processed. The response
 722          * body can then be read directly from the {@link InputStream}.
 723          *
 724          * @apiNote To ensure that all resources associated with the
 725          * corresponding exchange are properly released the caller must
 726          * ensure to either read all bytes until EOF is reached, or call
 727          * {@link InputStream#close} if it is unable or unwilling to do so.
 728          * Calling {@code close} before exhausting the stream may cause
 729          * the underlying HTTP connection to be closed and prevent it
 730          * from being reused for subsequent operations.
 731          *
 732          * @return a body subscriber that streams the response body as an
 733          *         {@link InputStream}.
 734          */
 735         public static BodySubscriber<InputStream> asInputStream() {
 736             return new ResponseSubscribers.HttpResponseInputStream();
 737         }
 738 
 739         /**
 740          * Returns a response subscriber which discards the response body. The
 741          * supplied value is the value that will be returned from
 742          * {@link HttpResponse#body()}.
 743          *
 744          * @param <U> The type of the response body
 745          * @param value the value to return from HttpResponse.body(), may be {@code null}
 746          * @return a {@code BodySubscriber}
 747          */
 748         public static <U> BodySubscriber<U> discard(U value) {
 749             return new ResponseSubscribers.NullSubscriber<>(Optional.ofNullable(value));
 750         }
 751 
 752         /**
 753          * Returns a {@code BodySubscriber} which buffers data before delivering
 754          * it to the given downstream subscriber. The subscriber guarantees to
 755          * deliver {@code buffersize} bytes of data to each invocation of the
 756          * downstream's {@linkplain #onNext(Object) onNext} method, except for
 757          * the final invocation, just before {@linkplain #onComplete() onComplete}
 758          * is invoked. The final invocation of {@code onNext} may contain fewer
 759          * than {@code buffersize} bytes.
 760          *
 761          * <p> The returned subscriber delegates its {@link #getBody()} method
 762          * to the downstream subscriber.
 763          *
 764          * @param downstream the downstream subscriber
 765          * @param bufferSize the buffer size
 766          * @return a buffering body subscriber
 767          * @throws IllegalArgumentException if {@code bufferSize <= 0}
 768          */
 769          public static <T> BodySubscriber<T> buffering(BodySubscriber<T> downstream,
 770                                                        int bufferSize) {
 771              if (bufferSize <= 0)
 772                  throw new IllegalArgumentException("must be greater than 0");
 773              return new BufferingSubscriber<T>(downstream, bufferSize);
 774          }
 775     }
 776 
 777     /**
 778      * A response subscriber for a HTTP/2 multi response.
 779      * {@Incubating}
 780      *
 781      * <p> A multi response comprises a main response, and zero or more additional
 782      * responses. Each additional response is sent by the server in response to
 783      * requests (PUSH_PROMISEs) that the server also generates. Additional responses are
 784      * typically resources that the server expects the client will need which
 785      * are related to the initial request.
 786      * <p>
 787      * Note. Instead of implementing this interface, applications should consider
 788      * first using the mechanism (built on this interface) provided by
 789      * {@link MultiSubscriber#asMap(java.util.function.Function, boolean)
 790      * MultiSubscriber.asMap()} which is a slightly simplified, but also
 791      * general purpose interface.
 792      * <p>
 793      * The server generated requests are also known as <i>push promises</i>.
 794      * The server is permitted to send any number of these requests up to the
 795      * point where the main response is fully received. Therefore, after
 796      * completion of the main response, the final number of additional
 797      * responses is known. Additional responses may be canceled, but given that
 798      * the server does not wait for any acknowledgment before sending the
 799      * response, this must be done quickly to avoid unnecessary data transmission.
 800      *
 801      * <p> {@code MultiSubscriber}s are parameterized with a type {@code U} which
 802      * represents some meaningful aggregate of the responses received. This
 803      * would typically be a collection of response or response body objects.
 804      *
 805      * @param <U> a type representing the aggregated results
 806      * @param <T> a type representing all of the response bodies
 807      *
 808      * @since 9
 809      */
 810     public interface MultiSubscriber<U,T> {
 811         /**
 812          * Called for the main request from the user. This {@link HttpRequest}
 813          * parameter is the request that was supplied to {@link
 814          * HttpClient#sendAsync(HttpRequest, MultiSubscriber)}. The
 815          * implementation must return an {@link BodyHandler} for the response
 816          * body.
 817          *
 818          * @param request the request
 819          *
 820          * @return an optional body handler
 821          */
 822         BodyHandler<T> onRequest(HttpRequest request);
 823 
 824         /**
 825          * Called for each push promise that is received. The {@link HttpRequest}
 826          * parameter represents the PUSH_PROMISE. The implementation must return
 827          * an {@code Optional} of {@link BodyHandler} for the response body.
 828          * Different handlers (of the same type) can be returned for different
 829          * pushes within the same multi send. If no handler (an empty {@code
 830          * Optional}) is returned, then the push will be canceled. If required,
 831          * the {@code CompletableFuture<Void>} supplied to the {@code
 832          * onFinalPushPromise} parameter of {@link
 833          * #completion(CompletableFuture, CompletableFuture)} can be used to
 834          * determine when the final PUSH_PROMISE is received.
 835          *
 836          * @param pushPromise the push promise
 837          *
 838          * @return an optional body handler
 839          */
 840         Optional<BodyHandler<T>> onPushPromise(HttpRequest pushPromise);
 841 
 842         /**
 843          * Called for each response received. For each request either one of
 844          * onResponse() or onError() is guaranteed to be called, but not both.
 845          *
 846          * <p> Note: The reason for switching to this callback interface rather
 847          * than using CompletableFutures supplied to onRequest() is that there
 848          * is a subtle interaction between those CFs and the CF returned from
 849          * completion() (or when onComplete() was called formerly). The completion()
 850          * CF will not complete until after all of the work done by the onResponse()
 851          * calls is done. Whereas if you just create CF's dependent on a supplied
 852          * CF (to onRequest()) then the implementation has no visibility of the
 853          * dependent CFs and can't guarantee to call onComplete() (or complete
 854          * the completion() CF) after the dependent CFs complete.
 855          *
 856          * @param response the response received
 857          */
 858         void onResponse(HttpResponse<T> response);
 859 
 860         /**
 861          * Called if an error occurs receiving a response. For each request
 862          * either one of onResponse() or onError() is guaranteed to be called,
 863          * but not both.
 864          *
 865          * @param request the main request or subsequent push promise
 866          * @param t the Throwable that caused the error
 867          */
 868         void onError(HttpRequest request, Throwable t);
 869 
 870         /**
 871          * Returns a {@link java.util.concurrent.CompletableFuture}{@code <U>}
 872          * which completes when the aggregate result object itself is available.
 873          * It is expected that the returned {@code CompletableFuture} will depend
 874          * on one of the given {@code CompletableFuture<Void}s which themselves
 875          * complete after all individual responses associated with the multi
 876          * response have completed, or after all push promises have been received.
 877          * This method is called after {@link #onRequest(HttpRequest)} but
 878          * before any other methods.
 879          *
 880          * @implNote Implementations might follow the pattern shown below
 881          * <pre>
 882          * {@code
 883          *      CompletableFuture<U> completion(
 884          *              CompletableFuture<Void> onComplete,
 885          *              CompletableFuture<Void> onFinalPushPromise)
 886          *      {
 887          *          return onComplete.thenApply((v) -> {
 888          *              U u = ... instantiate and populate a U instance
 889          *              return u;
 890          *          });
 891          *      }
 892          * }
 893          * </pre>
 894          *
 895          * @param onComplete a CompletableFuture which completes after all
 896          * responses have been received relating to this multi request.
 897          *
 898          * @param onFinalPushPromise CompletableFuture which completes after all
 899          * push promises have been received.
 900          *
 901          * @return the aggregate CF response object
 902          */
 903         CompletableFuture<U> completion(CompletableFuture<Void> onComplete,
 904                 CompletableFuture<Void> onFinalPushPromise);
 905 
 906         /**
 907          * Returns a general purpose handler for multi responses. The aggregated
 908          * result object produced by this handler is a
 909          * {@code Map<HttpRequest,CompletableFuture<HttpResponse<V>>>}. Each
 910          * request (both the original user generated request and each server
 911          * generated push promise) is returned as a key of the map. The value
 912          * corresponding to each key is a
 913          * {@code CompletableFuture<HttpResponse<V>>}.
 914          *
 915          * <p> There are two ways to use these handlers, depending on the value
 916          * of the <i>completion</I> parameter. If completion is true, then the
 917          * aggregated result will be available after all responses have
 918          * themselves completed. If <i>completion</i> is false, then the
 919          * aggregated result will be available immediately after the last push
 920          * promise was received. In the former case, this implies that all the
 921          * CompletableFutures in the map values will have completed. In the
 922          * latter case, they may or may not have completed yet.
 923          *
 924          * <p> The simplest way to use these handlers is to set completion to
 925          * {@code true}, and then all (results) values in the Map will be
 926          * accessible without blocking.
 927          * <p>
 928          * See {@link #asMap(java.util.function.Function, boolean)}
 929          * for a code sample of using this interface.
 930          *
 931          * <p> See {@link #asMap(Function, boolean)} for a code sample of using
 932          * this interface.
 933          *
 934          * @param <V> the body type used for all responses
 935          * @param reqHandler a function invoked for the user's request and each
 936          *                   push promise
 937          * @param completion {@code true} if the aggregate CompletableFuture
 938          *                   completes after all responses have been received,
 939          *                   or {@code false} after all push promises received
 940          *
 941          * @return a MultiSubscriber
 942          */
 943         public static <V> MultiSubscriber<MultiMapResult<V>,V> asMap(
 944                 Function<HttpRequest, Optional<HttpResponse.BodyHandler<V>>> reqHandler,
 945                 boolean completion) {
 946             return new MultiSubscriberImpl<V>(reqHandler.andThen(optv -> optv.get()),
 947                                               reqHandler,
 948                                               completion);
 949         }
 950 
 951         /**
 952          * Returns a general purpose handler for multi responses. This is a
 953          * convenience method which invokes {@link #asMap(Function,boolean)
 954          * asMap(Function, true)} meaning that the aggregate result
 955          * object completes after all responses have been received.
 956          *
 957          * <p><b>Example usage:</b>
 958          * <br>
 959          * <pre>
 960          * {@code
 961          *          HttpRequest request = HttpRequest.newBuilder()
 962          *                  .uri(URI.create("https://www.foo.com/"))
 963          *                  .GET()
 964          *                  .build();
 965          *
 966          *          HttpClient client = HttpClient.newHttpClient();
 967          *
 968          *          Map<HttpRequest,CompletableFuture<HttpResponse<String>>> results = client
 969          *              .sendAsync(request, MultiSubscriber.asMap(
 970          *                  (req) -> Optional.of(HttpResponse.BodyHandler.asString())))
 971          *              .join();
 972          * }</pre>
 973          *
 974          * <p> The lambda in this example is the simplest possible implementation,
 975          * where neither the incoming requests are examined, nor the response
 976          * headers, and every push that the server sends is accepted. When the
 977          * join() call returns, all {@code HttpResponse}s and their associated
 978          * body objects are available.
 979          *
 980          * @param <V> the body type used for all responses
 981          * @param reqHandler a function invoked for each push promise and the
 982          *                   main request
 983          * @return a MultiSubscriber
 984          */
 985         public static <V> MultiSubscriber<MultiMapResult<V>,V> asMap(
 986                 Function<HttpRequest, Optional<HttpResponse.BodyHandler<V>>> reqHandler) {
 987 
 988             return asMap(reqHandler, true);
 989         }
 990 
 991     }
 992 }