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.UncheckedIOException;
30 import java.net.URI;
31 import jdk.incubator.http.ResponseProcessors.MultiFile;
32 import jdk.incubator.http.ResponseProcessors.MultiProcessorImpl;
33 import static jdk.incubator.http.internal.common.Utils.unchecked;
34 import static jdk.incubator.http.internal.common.Utils.charsetFrom;
35 import java.nio.ByteBuffer;
36 import java.nio.charset.Charset;
37 import java.nio.charset.StandardCharsets;
38 import java.nio.file.OpenOption;
39 import java.nio.file.Path;
40 import java.nio.file.Paths;
41 import java.nio.file.StandardOpenOption;
42 import java.util.Map;
43 import java.util.Optional;
44 import java.util.concurrent.CompletableFuture;
45 import java.util.concurrent.CompletionStage;
46 import java.util.concurrent.Flow;
47 import java.util.function.Consumer;
48 import java.util.function.Function;
49 import javax.net.ssl.SSLParameters;
50
51 /**
52 * Represents a response to a {@link HttpRequest}.
53 * {@Incubating}
54 *
55 * <p>A {@code HttpResponse} is available when the response status code and
56 * headers have been received, and typically after the response body has also
57 * been received. This depends on the response body handler provided when
58 * sending the request. In all cases, the response body handler is invoked
59 * before the body is read. This gives applications an opportunity to decide
60 * how to handle the body.
61 *
62 * <p> Methods are provided in this class for accessing the response headers,
380 }
381
382 /**
383 * Returns a {@code BodyHandler<String>} that returns a
384 * {@link BodyProcessor BodyProcessor}{@code <String>} obtained from
385 * {@link BodyProcessor#asString(java.nio.charset.Charset)
386 * BodyProcessor.asString(Charset)}. The body is
387 * decoded using the character set specified in
388 * the {@code Content-encoding} response header. If there is no such
389 * header, or the character set is not supported, then
390 * {@link java.nio.charset.StandardCharsets#UTF_8 UTF_8} is used.
391 * <p>
392 * When the {@code HttpResponse} object is returned, the body has been completely
393 * written to the string.
394 *
395 * @return a response body handler
396 */
397 public static BodyHandler<String> asString() {
398 return (status, headers) -> BodyProcessor.asString(charsetFrom(headers));
399 }
400 }
401
402 /**
403 * A processor for response bodies.
404 * {@Incubating}
405 * <p>
406 * The object acts as a {@link Flow.Subscriber}<{@link ByteBuffer}> to
407 * the HTTP client implementation which publishes ByteBuffers containing the
408 * response body. The processor converts the incoming buffers of data to
409 * some user-defined object type {@code T}.
410 * <p>
411 * The {@link #getBody()} method returns a {@link CompletionStage}{@code <T>}
412 * that provides the response body object. The {@code CompletionStage} must
413 * be obtainable at any time. When it completes depends on the nature
414 * of type {@code T}. In many cases, when {@code T} represents the entire body after being
415 * read then it completes after the body has been read. If {@code T} is a streaming
416 * type such as {@link java.io.InputStream} then it completes before the
417 * body has been read, because the calling code uses it to consume the data.
418 *
419 * @param <T> the response body type
420 */
421 public interface BodyProcessor<T>
422 extends Flow.Subscriber<ByteBuffer> {
423
424 /**
425 * Returns a {@code CompletionStage} which when completed will return the
426 * response body object.
427 *
428 * @return a CompletionStage for the response body
429 */
430 public CompletionStage<T> getBody();
431
432 /**
433 * Returns a body processor which stores the response body as a {@code
434 * String} converted using the given {@code Charset}.
435 * <p>
436 * The {@link HttpResponse} using this processor is available after the
437 * entire response has been read.
438 *
439 * @param charset the character set to convert the String with
440 * @return a body processor
441 */
442 public static BodyProcessor<String> asString(Charset charset) {
513 * @return a body processor
514 */
515 public static BodyProcessor<Path> asFile(Path file) {
516 return new ResponseProcessors.PathProcessor(
517 file,
518 StandardOpenOption.CREATE, StandardOpenOption.WRITE);
519 }
520
521 /**
522 * Returns a response processor which discards the response body. The
523 * supplied value is the value that will be returned from
524 * {@link HttpResponse#body()}.
525 *
526 * @param <U> The type of the response body
527 * @param value the value to return from HttpResponse.body()
528 * @return a {@code BodyProcessor}
529 */
530 public static <U> BodyProcessor<U> discard(U value) {
531 return new ResponseProcessors.NullProcessor<>(Optional.ofNullable(value));
532 }
533 }
534
535 /**
536 * A response processor for a HTTP/2 multi response.
537 * {@Incubating}
538 * <p>
539 * A multi response comprises a main response, and zero or more additional
540 * responses. Each additional response is sent by the server in response to
541 * requests that the server also generates. Additional responses are
542 * typically resources that the server expects the client will need which
543 * are related to the initial request.
544 * <p>
545 * Note. Instead of implementing this interface, applications should consider
546 * first using the mechanism (built on this interface) provided by
547 * {@link MultiProcessor#asMap(java.util.function.Function, boolean)
548 * MultiProcessor.asMap()} which is a slightly simplified, but
549 * general purpose interface.
550 * <p>
551 * The server generated requests are also known as <i>push promises</i>.
552 * The server is permitted to send any number of these requests up to the
|
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.net.URI;
30 import jdk.incubator.http.ResponseProcessors.MultiProcessorImpl;
31 import static jdk.incubator.http.internal.common.Utils.unchecked;
32 import static jdk.incubator.http.internal.common.Utils.charsetFrom;
33 import java.nio.ByteBuffer;
34 import java.nio.charset.Charset;
35 import java.nio.file.OpenOption;
36 import java.nio.file.Path;
37 import java.nio.file.Paths;
38 import java.nio.file.StandardOpenOption;
39 import java.util.List;
40 import java.util.Optional;
41 import java.util.concurrent.CompletableFuture;
42 import java.util.concurrent.CompletionStage;
43 import java.util.concurrent.Flow;
44 import java.util.function.Consumer;
45 import java.util.function.Function;
46 import javax.net.ssl.SSLParameters;
47
48 /**
49 * Represents a response to a {@link HttpRequest}.
50 * {@Incubating}
51 *
52 * <p>A {@code HttpResponse} is available when the response status code and
53 * headers have been received, and typically after the response body has also
54 * been received. This depends on the response body handler provided when
55 * sending the request. In all cases, the response body handler is invoked
56 * before the body is read. This gives applications an opportunity to decide
57 * how to handle the body.
58 *
59 * <p> Methods are provided in this class for accessing the response headers,
377 }
378
379 /**
380 * Returns a {@code BodyHandler<String>} that returns a
381 * {@link BodyProcessor BodyProcessor}{@code <String>} obtained from
382 * {@link BodyProcessor#asString(java.nio.charset.Charset)
383 * BodyProcessor.asString(Charset)}. The body is
384 * decoded using the character set specified in
385 * the {@code Content-encoding} response header. If there is no such
386 * header, or the character set is not supported, then
387 * {@link java.nio.charset.StandardCharsets#UTF_8 UTF_8} is used.
388 * <p>
389 * When the {@code HttpResponse} object is returned, the body has been completely
390 * written to the string.
391 *
392 * @return a response body handler
393 */
394 public static BodyHandler<String> asString() {
395 return (status, headers) -> BodyProcessor.asString(charsetFrom(headers));
396 }
397
398 /**
399 * Returns a {@code BodyHandler} which, when invoked, returns a {@linkplain
400 * BodyProcessor#buffering(BodyProcessor,int) buffering BodyProcessor}
401 * that buffers data before delivering it to the downstream processor.
402 * These {@code BodyProcessor} instances are created by calling
403 * {@linkplain BodyProcessor#buffering(BodyProcessor,int)
404 * BodyProcessor.buffering} with a processor obtained from the given
405 * downstream handler and the {@code bufferSize} parameter.
406 *
407 * @param downstreamHandler the downstream handler
408 * @param bufferSize the buffer size parameter passed to {@linkplain
409 * BodyProcessor#buffering(BodyProcessor,int) BodyProcessor.buffering}
410 * @return a body handler
411 * @throws IllegalArgumentException if {@code bufferSize <= 0}
412 */
413 public static <T> BodyHandler<T> buffering(BodyHandler<T> downstreamHandler,
414 int bufferSize) {
415 if (bufferSize <= 0)
416 throw new IllegalArgumentException("must be greater than 0");
417 return (status, headers) -> BodyProcessor
418 .buffering(downstreamHandler.apply(status, headers),
419 bufferSize);
420 }
421 }
422
423 /**
424 * A processor for response bodies.
425 * {@Incubating}
426 * <p>
427 * The object acts as a {@link Flow.Subscriber}<{@link List}<{@link
428 * ByteBuffer}>> to the HTTP client implementation which publishes
429 * ByteBuffers containing the response body. The processor converts the
430 * incoming buffers of data to some user-defined object type {@code T}.
431 * <p>
432 * The {@link #getBody()} method returns a {@link CompletionStage}{@code <T>}
433 * that provides the response body object. The {@code CompletionStage} must
434 * be obtainable at any time. When it completes depends on the nature
435 * of type {@code T}. In many cases, when {@code T} represents the entire body after being
436 * read then it completes after the body has been read. If {@code T} is a streaming
437 * type such as {@link java.io.InputStream} then it completes before the
438 * body has been read, because the calling code uses it to consume the data.
439 *
440 * @param <T> the response body type
441 */
442 public interface BodyProcessor<T>
443 extends Flow.Subscriber<List<ByteBuffer>> {
444
445 /**
446 * Returns a {@code CompletionStage} which when completed will return the
447 * response body object.
448 *
449 * @return a CompletionStage for the response body
450 */
451 public CompletionStage<T> getBody();
452
453 /**
454 * Returns a body processor which stores the response body as a {@code
455 * String} converted using the given {@code Charset}.
456 * <p>
457 * The {@link HttpResponse} using this processor is available after the
458 * entire response has been read.
459 *
460 * @param charset the character set to convert the String with
461 * @return a body processor
462 */
463 public static BodyProcessor<String> asString(Charset charset) {
534 * @return a body processor
535 */
536 public static BodyProcessor<Path> asFile(Path file) {
537 return new ResponseProcessors.PathProcessor(
538 file,
539 StandardOpenOption.CREATE, StandardOpenOption.WRITE);
540 }
541
542 /**
543 * Returns a response processor which discards the response body. The
544 * supplied value is the value that will be returned from
545 * {@link HttpResponse#body()}.
546 *
547 * @param <U> The type of the response body
548 * @param value the value to return from HttpResponse.body()
549 * @return a {@code BodyProcessor}
550 */
551 public static <U> BodyProcessor<U> discard(U value) {
552 return new ResponseProcessors.NullProcessor<>(Optional.ofNullable(value));
553 }
554
555 /**
556 * Returns a {@code BodyProcessor} which buffers data before delivering
557 * it to the given downstream processor. The processor guarantees to
558 * deliver {@code buffersize} bytes of data to each invocation of the
559 * downstream's {@linkplain #onNext(Object) onNext} method, except for
560 * the final invocation, just before {@linkplain #onComplete() onComplete}
561 * is invoked. The final invocation of {@code onNext} may contain fewer
562 * than {@code buffersize} bytes.
563 * <p>
564 * The returned processor delegates its {@link #getBody()} method to the
565 * downstream processor.
566 *
567 * @param downstream the downstream processor
568 * @param bufferSize the buffer size
569 * @return a buffering body processor
570 * @throws IllegalArgumentException if {@code bufferSize <= 0}
571 */
572 public static <T> BodyProcessor<T> buffering(BodyProcessor<T> downstream,
573 int bufferSize) {
574 if (bufferSize <= 0)
575 throw new IllegalArgumentException("must be greater than 0");
576 return new BufferingProcessor<T>(downstream, bufferSize);
577 }
578 }
579
580 /**
581 * A response processor for a HTTP/2 multi response.
582 * {@Incubating}
583 * <p>
584 * A multi response comprises a main response, and zero or more additional
585 * responses. Each additional response is sent by the server in response to
586 * requests that the server also generates. Additional responses are
587 * typically resources that the server expects the client will need which
588 * are related to the initial request.
589 * <p>
590 * Note. Instead of implementing this interface, applications should consider
591 * first using the mechanism (built on this interface) provided by
592 * {@link MultiProcessor#asMap(java.util.function.Function, boolean)
593 * MultiProcessor.asMap()} which is a slightly simplified, but
594 * general purpose interface.
595 * <p>
596 * The server generated requests are also known as <i>push promises</i>.
597 * The server is permitted to send any number of these requests up to the
|