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<ByteBuffer>}, 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 }