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