1 /*
  2  * Copyright (c) 2015, 2020, 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 java.net.http;
 27 
 28 import java.io.FileNotFoundException;
 29 import java.io.InputStream;
 30 import java.net.URI;
 31 import java.nio.ByteBuffer;
 32 import java.nio.charset.Charset;
 33 import java.nio.charset.StandardCharsets;
 34 import java.nio.file.Files;
 35 import java.nio.file.OpenOption;
 36 import java.nio.file.Path;
 37 import java.time.Duration;
 38 import java.util.Iterator;
 39 import java.util.Objects;
 40 import java.util.Optional;
 41 import java.util.concurrent.Flow;
 42 import java.util.function.Supplier;
 43 import jdk.internal.net.http.HttpRequestBuilderImpl;
 44 import jdk.internal.net.http.RequestPublishers;
 45 import static java.nio.charset.StandardCharsets.UTF_8;
 46 
 47 /**
 48  * An HTTP request.
 49  *
 50  * <p> An {@code HttpRequest} instance is built through an {@code HttpRequest}
 51  * {@linkplain HttpRequest.Builder builder}. An {@code HttpRequest} builder
 52  * is obtained from one of the {@link HttpRequest#newBuilder(URI) newBuilder}
 53  * methods. A request's {@link URI}, headers, and body can be set. Request
 54  * bodies are provided through a {@link BodyPublisher BodyPublisher} supplied
 55  * to one of the {@link Builder#POST(BodyPublisher) POST},
 56  * {@link Builder#PUT(BodyPublisher) PUT} or
 57  * {@link Builder#method(String,BodyPublisher) method} methods.
 58  * Once all required parameters have been set in the builder, {@link
 59  * Builder#build() build} will return the {@code HttpRequest}. Builders can be
 60  * copied and modified many times in order to build multiple related requests
 61  * that differ in some parameters.
 62  *
 63  * <p> The following is an example of a GET request that prints the response
 64  * body as a String:
 65  *
 66  * <pre>{@code    HttpClient client = HttpClient.newHttpClient();
 67  *   HttpRequest request = HttpRequest.newBuilder()
 68  *         .uri(URI.create("http://foo.com/"))
 69  *         .build();
 70  *   client.sendAsync(request, BodyHandlers.ofString())
 71  *         .thenApply(HttpResponse::body)
 72  *         .thenAccept(System.out::println)
 73  *         .join(); }</pre>
 74  *
 75  * <p>The class {@link BodyPublishers BodyPublishers} provides implementations
 76  * of many common publishers. Alternatively, a custom {@code BodyPublisher}
 77  * implementation can be used.
 78  *
 79  * @since 11
 80  */
 81 public abstract class HttpRequest {
 82 
 83     /**
 84      * Creates an HttpRequest.
 85      */
 86     protected HttpRequest() {}
 87 
 88     /**
 89      * A builder of {@linkplain HttpRequest HTTP requests}.
 90      *
 91      * <p> Instances of {@code HttpRequest.Builder} are created by calling {@link
 92      * HttpRequest#newBuilder(URI)} or {@link HttpRequest#newBuilder()}.
 93      *
 94      * <p> The builder can be used to configure per-request state, such as: the
 95      * request URI, the request method (default is GET unless explicitly set),
 96      * specific request headers, etc. Each of the setter methods modifies the
 97      * state of the builder and returns the same instance. The methods are not
 98      * synchronized and should not be called from multiple threads without
 99      * external synchronization. The {@link #build() build} method returns a new
100      * {@code HttpRequest} each time it is invoked. Once built an {@code
101      * HttpRequest} is immutable, and can be sent multiple times.
102      *
103      * <p> Note, that not all request headers may be set by user code. Some are
104      * restricted for security reasons and others such as the headers relating
105      * to authentication, redirection and cookie management may be managed by
106      * specific APIs rather than through directly user set headers.
107      *
108      * @since 11
109      */
110     public interface Builder {
111 
112         /**
113          * Sets this {@code HttpRequest}'s request {@code URI}.
114          *
115          * @param uri the request URI
116          * @return this builder
117          * @throws IllegalArgumentException if the {@code URI} scheme is not
118          *         supported
119          */
120         public Builder uri(URI uri);
121 
122         /**
123          * Requests the server to acknowledge the request before sending the
124          * body. This is disabled by default. If enabled, the server is
125          * requested to send an error response or a {@code 100 Continue}
126          * response before the client sends the request body. This means the
127          * request publisher for the request will not be invoked until this
128          * interim response is received.
129          *
130          * @param enable {@code true} if Expect continue to be sent
131          * @return this builder
132          */
133         public Builder expectContinue(boolean enable);
134 
135         /**
136          * Sets the preferred {@link HttpClient.Version} for this request.
137          *
138          * <p> The corresponding {@link HttpResponse} should be checked for the
139          * version that was actually used. If the version is not set in a
140          * request, then the version requested will be that of the sending
141          * {@link HttpClient}.
142          *
143          * @param version the HTTP protocol version requested
144          * @return this builder
145          */
146         public Builder version(HttpClient.Version version);
147 
148         /**
149          * Adds the given name value pair to the set of headers for this request.
150          * The given value is added to the list of values for that name.
151          *
152          * @implNote An implementation may choose to restrict some header names
153          *           or values, as the HTTP Client may determine their value itself.
154          *           For example, "Content-Length", which will be determined by
155          *           the request Publisher. In such a case, an implementation of
156          *           {@code HttpRequest.Builder} may choose to throw an
157          *           {@code IllegalArgumentException} if such a header is passed
158          *           to the builder.
159          *
160          * @param name the header name
161          * @param value the header value
162          * @return this builder
163          * @throws IllegalArgumentException if the header name or value is not
164          *         valid, see <a href="https://tools.ietf.org/html/rfc7230#section-3.2">
165          *         RFC 7230 section-3.2</a>, or the header name or value is restricted
166          *         by the implementation.
167          */
168         public Builder header(String name, String value);
169 
170         /**
171          * Adds the given name value pairs to the set of headers for this
172          * request. The supplied {@code String} instances must alternate as
173          * header names and header values.
174          * To add several values to the same name then the same name must
175          * be supplied with each new value.
176          *
177          * @param headers the list of name value pairs
178          * @return this builder
179          * @throws IllegalArgumentException if there are an odd number of
180          *         parameters, or if a header name or value is not valid, see
181          *         <a href="https://tools.ietf.org/html/rfc7230#section-3.2">
182          *         RFC 7230 section-3.2</a>, or a header name or value is
183          *         {@linkplain #header(String, String) restricted} by the
184          *         implementation.
185          */
186         public Builder headers(String... headers);
187 
188         /**
189          * Sets a timeout for this request. If the response is not received
190          * within the specified timeout then an {@link HttpTimeoutException} is
191          * thrown from {@link HttpClient#send(java.net.http.HttpRequest,
192          * java.net.http.HttpResponse.BodyHandler) HttpClient::send} or
193          * {@link HttpClient#sendAsync(java.net.http.HttpRequest,
194          * java.net.http.HttpResponse.BodyHandler) HttpClient::sendAsync}
195          * completes exceptionally with an {@code HttpTimeoutException}. The effect
196          * of not setting a timeout is the same as setting an infinite Duration,
197          * i.e. block forever.
198          *
199          * @param duration the timeout duration
200          * @return this builder
201          * @throws IllegalArgumentException if the duration is non-positive
202          */
203         public abstract Builder timeout(Duration duration);
204 
205         /**
206          * Sets the given name value pair to the set of headers for this
207          * request. This overwrites any previously set values for name.
208          *
209          * @param name the header name
210          * @param value the header value
211          * @return this builder
212          * @throws IllegalArgumentException if the header name or value is not valid,
213          *         see <a href="https://tools.ietf.org/html/rfc7230#section-3.2">
214          *         RFC 7230 section-3.2</a>, or the header name or value is
215          *         {@linkplain #header(String, String) restricted} by the
216          *         implementation.
217          */
218         public Builder setHeader(String name, String value);
219 
220         /**
221          * Sets the request method of this builder to GET.
222          * This is the default.
223          *
224          * @return this builder
225          */
226         public Builder GET();
227 
228         /**
229          * Sets the request method of this builder to POST and sets its
230          * request body publisher to the given value.
231          *
232          * @param bodyPublisher the body publisher
233          *
234          * @return this builder
235          */
236         public Builder POST(BodyPublisher bodyPublisher);
237 
238         /**
239          * Sets the request method of this builder to PUT and sets its
240          * request body publisher to the given value.
241          *
242          * @param bodyPublisher the body publisher
243          *
244          * @return this builder
245          */
246         public Builder PUT(BodyPublisher bodyPublisher);
247 
248         /**
249          * Sets the request method of this builder to DELETE.
250          *
251          * @return this builder
252          */
253         public Builder DELETE();
254 
255         /**
256          * Sets the request method and request body of this builder to the
257          * given values.
258          *
259          * @apiNote The {@link BodyPublishers#noBody() noBody} request
260          * body publisher can be used where no request body is required or
261          * appropriate. Whether a method is restricted, or not, is
262          * implementation specific. For example, some implementations may choose
263          * to restrict the {@code CONNECT} method.
264          *
265          * @param method the method to use
266          * @param bodyPublisher the body publisher
267          * @return this builder
268          * @throws IllegalArgumentException if the method name is not
269          *         valid, see <a href="https://tools.ietf.org/html/rfc7230#section-3.1.1">
270          *         RFC 7230 section-3.1.1</a>, or the method is restricted by the
271          *         implementation.
272          */
273         public Builder method(String method, BodyPublisher bodyPublisher);
274 
275         /**
276          * Builds and returns an {@link HttpRequest}.
277          *
278          * @return a new {@code HttpRequest}
279          * @throws IllegalStateException if a URI has not been set
280          */
281         public HttpRequest build();
282 
283         /**
284          * Returns an exact duplicate copy of this {@code Builder} based on
285          * current state. The new builder can then be modified independently of
286          * this builder.
287          *
288          * @return an exact copy of this builder
289          */
290         public Builder copy();
291     }
292 
293     /**
294      * Creates an {@code HttpRequest} builder with the given URI.
295      *
296      * @param uri the request URI
297      * @return a new request builder
298      * @throws IllegalArgumentException if the URI scheme is not supported.
299      */
300     public static HttpRequest.Builder newBuilder(URI uri) {
301         return new HttpRequestBuilderImpl(uri);
302     }
303 
304     /**
305      * Creates an {@code HttpRequest} builder.
306      *
307      * @return a new request builder
308      */
309     public static HttpRequest.Builder newBuilder() {
310         return new HttpRequestBuilderImpl();
311     }
312 
313     /**
314      * Returns an {@code Optional} containing the {@link BodyPublisher} set on
315      * this request. If no {@code BodyPublisher} was set in the requests's
316      * builder, then the {@code Optional} is empty.
317      *
318      * @return an {@code Optional} containing this request's {@code BodyPublisher}
319      */
320     public abstract Optional<BodyPublisher> bodyPublisher();
321 
322     /**
323      * Returns the request method for this request. If not set explicitly,
324      * the default method for any request is "GET".
325      *
326      * @return this request's method
327      */
328     public abstract String method();
329 
330     /**
331      * Returns an {@code Optional} containing this request's timeout duration.
332      * If the timeout duration was not set in the request's builder, then the
333      * {@code Optional} is empty.
334      *
335      * @return an {@code Optional} containing this request's timeout duration
336      */
337     public abstract Optional<Duration> timeout();
338 
339     /**
340      * Returns this request's {@linkplain HttpRequest.Builder#expectContinue(boolean)
341      * expect continue} setting.
342      *
343      * @return this request's expect continue setting
344      */
345     public abstract boolean expectContinue();
346 
347     /**
348      * Returns this request's {@code URI}.
349      *
350      * @return this request's URI
351      */
352     public abstract URI uri();
353 
354     /**
355      * Returns an {@code Optional} containing the HTTP protocol version that
356      * will be requested for this {@code HttpRequest}. If the version was not
357      * set in the request's builder, then the {@code Optional} is empty.
358      * In that case, the version requested will be that of the sending
359      * {@link HttpClient}. The corresponding {@link HttpResponse} should be
360      * queried to determine the version that was actually used.
361      *
362      * @return HTTP protocol version
363      */
364     public abstract Optional<HttpClient.Version> version();
365 
366     /**
367      * The (user-accessible) request headers that this request was (or will be)
368      * sent with.
369      *
370      * @return this request's HttpHeaders
371      */
372     public abstract HttpHeaders headers();
373 
374     /**
375      * Tests this HTTP request instance for equality with the given object.
376      *
377      * <p> If the given object is not an {@code HttpRequest} then this
378      * method returns {@code false}. Two HTTP requests are equal if their URI,
379      * method, and headers fields are all equal.
380      *
381      * <p> This method satisfies the general contract of the {@link
382      * Object#equals(Object) Object.equals} method.
383      *
384      * @param obj the object to which this object is to be compared
385      * @return {@code true} if, and only if, the given object is an {@code
386      *         HttpRequest} that is equal to this HTTP request
387      */
388     @Override
389     public final boolean equals(Object obj) {
390        if (! (obj instanceof HttpRequest))
391            return false;
392        HttpRequest that = (HttpRequest)obj;
393        if (!that.method().equals(this.method()))
394            return false;
395        if (!that.uri().equals(this.uri()))
396            return false;
397        if (!that.headers().equals(this.headers()))
398            return false;
399        return true;
400     }
401 
402     /**
403      * Computes a hash code for this HTTP request instance.
404      *
405      * <p> The hash code is based upon the HTTP request's URI, method, and
406      * header components, and satisfies the general contract of the
407      * {@link Object#hashCode Object.hashCode} method.
408      *
409      * @return the hash-code value for this HTTP request
410      */
411     public final int hashCode() {
412         return method().hashCode()
413                 + uri().hashCode()
414                 + headers().hashCode();
415     }
416 
417     /**
418      * A {@code BodyPublisher} converts high-level Java objects into a flow of
419      * byte buffers suitable for sending as a request body.  The class
420      * {@link BodyPublishers BodyPublishers} provides implementations of many
421      * common publishers.
422      *
423      * <p> The {@code BodyPublisher} interface extends {@link Flow.Publisher
424      * Flow.Publisher&lt;ByteBuffer&gt;}, which means that a {@code BodyPublisher}
425      * acts as a publisher of {@linkplain ByteBuffer byte buffers}.
426      *
427      * <p> When sending a request that contains a body, the HTTP Client
428      * subscribes to the request's {@code BodyPublisher} in order to receive the
429      * flow of outgoing request body data. The normal semantics of {@link
430      * Flow.Subscriber} and {@link Flow.Publisher} are implemented by the HTTP
431      * Client and are expected from {@code BodyPublisher} implementations. Each
432      * outgoing request results in one HTTP Client {@code Subscriber}
433      * subscribing to the {@code BodyPublisher} in order to provide the sequence
434      * of byte buffers containing the request body. Instances of {@code
435      * ByteBuffer} published by the publisher must be allocated by the
436      * publisher, and must not be accessed after being published to the HTTP
437      * Client. These subscriptions complete normally when the request body is
438      * fully sent, and can be canceled or terminated early through error. If a
439      * request needs to be resent for any reason, then a new subscription is
440      * created which is expected to generate the same data as before.
441      *
442      * <p> A {@code BodyPublisher} that reports a {@linkplain #contentLength()
443      * content length} of {@code 0} may not be subscribed to by the HTTP Client,
444      * as it has effectively no data to publish.
445      *
446      * @see BodyPublishers
447      * @since 11
448      */
449     public interface BodyPublisher extends Flow.Publisher<ByteBuffer> {
450 
451         /**
452          * Returns the content length for this request body. May be zero
453          * if no request body being sent, greater than zero for a fixed
454          * length content, or less than zero for an unknown content length.
455          *
456          * <p> This method may be invoked before the publisher is subscribed to.
457          * This method may be invoked more than once by the HTTP client
458          * implementation, and MUST return the same constant value each time.
459          *
460          * @return the content length for this request body, if known
461          */
462         long contentLength();
463     }
464 
465     /**
466      * Implementations of {@link BodyPublisher BodyPublisher} that implement
467      * various useful publishers, such as publishing the request body from a
468      * String, or from a file.
469      *
470      * <p> The following are examples of using the predefined body publishers to
471      * convert common high-level Java objects into a flow of data suitable for
472      * sending as a request body:
473      *
474      *  <pre>{@code    // Request body from a String
475      *   HttpRequest request = HttpRequest.newBuilder()
476      *        .uri(URI.create("https://foo.com/"))
477      *        .header("Content-Type", "text/plain; charset=UTF-8")
478      *        .POST(BodyPublishers.ofString("some body text"))
479      *        .build();
480      *
481      *   // Request body from a File
482      *   HttpRequest request = HttpRequest.newBuilder()
483      *        .uri(URI.create("https://foo.com/"))
484      *        .header("Content-Type", "application/json")
485      *        .POST(BodyPublishers.ofFile(Paths.get("file.json")))
486      *        .build();
487      *
488      *   // Request body from a byte array
489      *   HttpRequest request = HttpRequest.newBuilder()
490      *        .uri(URI.create("https://foo.com/"))
491      *        .POST(BodyPublishers.ofByteArray(new byte[] { ... }))
492      *        .build(); }</pre>
493      *
494      * @since 11
495      */
496     public static class BodyPublishers {
497 
498         private BodyPublishers() { }
499 
500         /**
501          * Returns a request body publisher whose body is retrieved from the
502          * given {@code Flow.Publisher}. The returned request body publisher
503          * has an unknown content length.
504          *
505          * @apiNote This method can be used as an adapter between {@code
506          * BodyPublisher} and {@code Flow.Publisher}, where the amount of
507          * request body that the publisher will publish is unknown.
508          *
509          * @param publisher the publisher responsible for publishing the body
510          * @return a BodyPublisher
511          */
512         public static BodyPublisher
513         fromPublisher(Flow.Publisher<? extends ByteBuffer> publisher) {
514             return new RequestPublishers.PublisherAdapter(publisher, -1L);
515         }
516 
517         /**
518          * Returns a request body publisher whose body is retrieved from the
519          * given {@code Flow.Publisher}. The returned request body publisher
520          * has the given content length.
521          *
522          * <p> The given {@code contentLength} is a positive number, that
523          * represents the exact amount of bytes the {@code publisher} must
524          * publish.
525          *
526          * @apiNote This method can be used as an adapter between {@code
527          * BodyPublisher} and {@code Flow.Publisher}, where the amount of
528          * request body that the publisher will publish is known.
529          *
530          * @param publisher the publisher responsible for publishing the body
531          * @param contentLength a positive number representing the exact
532          *                      amount of bytes the publisher will publish
533          * @throws IllegalArgumentException if the content length is
534          *                                  non-positive
535          * @return a BodyPublisher
536          */
537         public static BodyPublisher
538         fromPublisher(Flow.Publisher<? extends ByteBuffer> publisher,
539                       long contentLength) {
540             if (contentLength < 1)
541                 throw new IllegalArgumentException("non-positive contentLength: "
542                         + contentLength);
543             return new RequestPublishers.PublisherAdapter(publisher, contentLength);
544         }
545 
546         /**
547          * Returns a request body publisher whose body is the given {@code
548          * String}, converted using the {@link StandardCharsets#UTF_8 UTF_8}
549          * character set.
550          *
551          * @param body the String containing the body
552          * @return a BodyPublisher
553          */
554         public static BodyPublisher ofString(String body) {
555             return ofString(body, UTF_8);
556         }
557 
558         /**
559          * Returns a request body publisher whose body is the given {@code
560          * String}, converted using the given character set.
561          *
562          * @param s the String containing the body
563          * @param charset the character set to convert the string to bytes
564          * @return a BodyPublisher
565          */
566         public static BodyPublisher ofString(String s, Charset charset) {
567             return new RequestPublishers.StringPublisher(s, charset);
568         }
569 
570         /**
571          * A request body publisher that reads its data from an {@link
572          * InputStream}. A {@link Supplier} of {@code InputStream} is used in
573          * case the request needs to be repeated, as the content is not buffered.
574          * The {@code Supplier} may return {@code null} on subsequent attempts,
575          * in which case the request fails.
576          *
577          * @param streamSupplier a Supplier of open InputStreams
578          * @return a BodyPublisher
579          */
580         // TODO (spec): specify that the stream will be closed
581         public static BodyPublisher ofInputStream(Supplier<? extends InputStream> streamSupplier) {
582             return new RequestPublishers.InputStreamPublisher(streamSupplier);
583         }
584 
585         /**
586          * Returns a request body publisher whose body is the given byte array.
587          *
588          * @param buf the byte array containing the body
589          * @return a BodyPublisher
590          */
591         public static BodyPublisher ofByteArray(byte[] buf) {
592             return new RequestPublishers.ByteArrayPublisher(buf);
593         }
594 
595         /**
596          * Returns a request body publisher whose body is the content of the
597          * given byte array of {@code length} bytes starting from the specified
598          * {@code offset}.
599          *
600          * @param buf the byte array containing the body
601          * @param offset the offset of the first byte
602          * @param length the number of bytes to use
603          * @return a BodyPublisher
604          * @throws IndexOutOfBoundsException if the sub-range is defined to be
605          *                                   out of bounds
606          */
607         public static BodyPublisher ofByteArray(byte[] buf, int offset, int length) {
608             Objects.checkFromIndexSize(offset, length, buf.length);
609             return new RequestPublishers.ByteArrayPublisher(buf, offset, length);
610         }
611 
612         /**
613          * A request body publisher that takes data from the contents of a File.
614          *
615          * <p> Security manager permission checks are performed in this factory
616          * method, when the {@code BodyPublisher} is created. Care must be taken
617          * that the {@code BodyPublisher} is not shared with untrusted code.
618          *
619          * @param  path the path to the file containing the body
620          * @return a BodyPublisher
621          * @throws java.io.FileNotFoundException if the path is not found
622          * @throws SecurityException if
623          *         {@linkplain Files#newInputStream(Path, OpenOption...)
624          *         opening the file for reading} is denied:
625          *         in the case of the system-default file system provider,
626          *         and a security manager is installed,
627          *         {@link SecurityManager#checkRead(String) checkRead}
628          *         is invoked to check read access to the given file
629          */
630         public static BodyPublisher ofFile(Path path) throws FileNotFoundException {
631             Objects.requireNonNull(path);
632             return RequestPublishers.FilePublisher.create(path);
633         }
634 
635         /**
636          * A request body publisher that takes data from an {@code Iterable}
637          * of byte arrays. An {@link Iterable} is provided which supplies
638          * {@link Iterator} instances. Each attempt to send the request results
639          * in one invocation of the {@code Iterable}.
640          *
641          * @param iter an Iterable of byte arrays
642          * @return a BodyPublisher
643          */
644         public static BodyPublisher ofByteArrays(Iterable<byte[]> iter) {
645             return new RequestPublishers.IterablePublisher(iter);
646         }
647 
648         /**
649          * A request body publisher which sends no request body.
650          *
651          * @return a BodyPublisher which completes immediately and sends
652          *         no request body.
653          */
654         public static BodyPublisher noBody() {
655             return new RequestPublishers.EmptyPublisher();
656         }
657     }
658 }