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