1 /* 2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.incubator.http; 27 28 import java.io.FileNotFoundException; 29 import java.io.InputStream; 30 import java.net.URI; 31 import java.nio.ByteBuffer; 32 import java.nio.charset.*; 33 import java.nio.file.Path; 34 import java.time.Duration; 35 import java.util.Iterator; 36 import java.util.Optional; 37 import java.util.concurrent.CompletableFuture; 38 import java.util.concurrent.Flow; 39 import java.util.function.Supplier; 40 41 /** 42 * Represents one HTTP request which can be sent to a server. 43 * {@Incubating } 44 * 45 * <p> {@code HttpRequest}s are built from {@code HttpRequest} 46 * {@link HttpRequest.Builder builder}s. {@code HttpRequest} builders are 47 * obtained by calling {@link HttpRequest#newBuilder(java.net.URI) 48 * HttpRequest.newBuilder}. 49 * A request's {@link java.net.URI}, headers and body can be set. Request bodies 50 * are provided through a {@link BodyProcessor} object supplied to the 51 * {@link Builder#DELETE(jdk.incubator.http.HttpRequest.BodyProcessor) DELETE}, 52 * {@link Builder#POST(jdk.incubator.http.HttpRequest.BodyProcessor) POST} or 53 * {@link Builder#PUT(jdk.incubator.http.HttpRequest.BodyProcessor) PUT} methods. 54 * {@link Builder#GET() GET} does not take a body. Once all required 55 * parameters have been set in the builder, {@link Builder#build() } is called 56 * to return the {@code HttpRequest}. Builders can also be copied 57 * and modified multiple times in order to build multiple related requests that 58 * differ in some parameters. 59 * 60 * <p> Two simple, example HTTP interactions are shown below: 61 * <pre> 62 * {@code 63 * HttpClient client = HttpClient.newHttpClient(); 64 * 65 * // GET 66 * HttpResponse<String> response = client.send( 67 * HttpRequest 68 * .newBuilder(new URI("http://www.foo.com/")) 69 * .headers("Foo", "foovalue", "Bar", "barvalue") 70 * .GET() 71 * .build(), 72 * BodyHandler.asString() 73 * ); 74 * int statusCode = response.statusCode(); 75 * String body = response.body(); 76 * 77 * // POST 78 * HttpResponse<Path> response = client.send( 79 * HttpRequest 80 * .newBuilder(new URI("http://www.foo.com/")) 81 * .headers("Foo", "foovalue", "Bar", "barvalue") 82 * .POST(BodyProcessor.fromString("Hello world")) 83 * .build(), 84 * BodyHandler.asFile(Paths.get("/path")) 85 * ); 86 * int statusCode = response.statusCode(); 87 * Path body = response.body(); // should be "/path" 88 * } 89 * </pre> 90 * <p> The request is sent and the response obtained by calling one of the 91 * following methods in {@link HttpClient}. 92 * <ul><li>{@link HttpClient#send(HttpRequest, HttpResponse.BodyHandler)} blocks 93 * until the entire request has been sent and the response has been received.</li> 94 * <li>{@link HttpClient#sendAsync(HttpRequest,HttpResponse.BodyHandler)} sends the 95 * request and receives the response asynchronously. Returns immediately with a 96 * {@link java.util.concurrent.CompletableFuture CompletableFuture}<{@link 97 * HttpResponse}>.</li> 98 * <li>{@link HttpClient#sendAsync(HttpRequest,HttpResponse.MultiProcessor) } 99 * sends the request asynchronously, expecting multiple responses. This 100 * capability is of most relevance to HTTP/2 server push, but can be used for 101 * single responses (HTTP/1.1 or HTTP/2) also.</li> 102 * </ul> 103 * 104 * <p> Once a {@link HttpResponse} is received, the headers, response code 105 * and body (typically) are available. Whether the body has been read or not 106 * depends on the type {@code <T>} of the response body. See below. 107 * 108 * <p> See below for discussion of synchronous versus asynchronous usage. 109 * 110 * <p> <b>Request bodies</b> 111 * 112 * <p> Request bodies are sent using one of the request processor implementations 113 * below provided in {@link HttpRequest.BodyProcessor}, or else a custom implementation can be 114 * used. 115 * <ul> 116 * <li>{@link BodyProcessor#fromByteArray(byte[]) fromByteArray(byte[])} from byte array</li> 117 * <li>{@link BodyProcessor#fromByteArrays(Iterable) fromByteArrays(Iterable)} 118 * from an Iterable of byte arrays</li> 119 * <li>{@link BodyProcessor#fromFile(java.nio.file.Path) fromFile(Path)} from the file located 120 * at the given Path</li> 121 * <li>{@link BodyProcessor#fromString(java.lang.String) fromString(String)} from a String </li> 122 * <li>{@link BodyProcessor#fromInputStream(Supplier) fromInputStream}({@link Supplier}< 123 * {@link InputStream}>) from an InputStream obtained from a Supplier</li> 124 * <li>{@link BodyProcessor#noBody() } no request body is sent</li> 125 * </ul> 126 * 127 * <p> <b>Response bodies</b> 128 * 129 * <p>Responses bodies are handled at two levels. When sending the request, 130 * a response body handler is specified. This is a function ({@link HttpResponse.BodyHandler}) 131 * which will be called with the response status code and headers, once these are received. This 132 * function is then expected to return a {@link HttpResponse.BodyProcessor} 133 * {@code <T>} which is then used to read the response body converting it 134 * into an instance of T. After this occurs, the response becomes 135 * available in a {@link HttpResponse} and {@link HttpResponse#body()} can then 136 * be called to obtain the body. Some implementations and examples of usage of both {@link 137 * HttpResponse.BodyProcessor} and {@link HttpResponse.BodyHandler} 138 * are provided in {@link HttpResponse}: 139 * <p><b>Some of the pre-defined body handlers</b><br> 140 * <ul> 141 * <li>{@link HttpResponse.BodyHandler#asByteArray() BodyHandler.asByteArray()} 142 * stores the body in a byte array</li> 143 * <li>{@link HttpResponse.BodyHandler#asString() BodyHandler.asString()} 144 * stores the body as a String </li> 145 * <li>{@link HttpResponse.BodyHandler#asFile(java.nio.file.Path) 146 * BodyHandler.asFile(Path)} stores the body in a named file</li> 147 * <li>{@link HttpResponse.BodyHandler#discard(Object) BodyHandler.discard()} 148 * discards the response body and returns the given value instead.</li> 149 * </ul> 150 * 151 * <p> <b>Multi responses</b> 152 * 153 * <p> With HTTP/2 it is possible for a server to return a main response and zero 154 * or more additional responses (known as server pushes) to a client-initiated 155 * request. These are handled using a special response processor called {@link 156 * HttpResponse.MultiProcessor}. 157 * 158 * <p> <b>Blocking/asynchronous behavior and thread usage</b> 159 * 160 * <p> There are two styles of request sending: <i>synchronous</i> and 161 * <i>asynchronous</i>. {@link HttpClient#send(HttpRequest, HttpResponse.BodyHandler) } 162 * blocks the calling thread until the request has been sent and the response received. 163 * 164 * <p> {@link HttpClient#sendAsync(HttpRequest, HttpResponse.BodyHandler)} is asynchronous and returns 165 * immediately with a {@link java.util.concurrent.CompletableFuture}<{@link 166 * HttpResponse}> and when this object completes (in a background thread) the 167 * response has been received. 168 * 169 * <p> {@link HttpClient#sendAsync(HttpRequest,HttpResponse.MultiProcessor)} 170 * is the variant for multi responses and is also asynchronous. 171 * 172 * <p> {@code CompletableFuture}s can be combined in different ways to declare the 173 * dependencies among several asynchronous tasks, while allowing for the maximum 174 * level of parallelism to be utilized. 175 * 176 * <p> <b>Security checks</b> 177 * 178 * <p> If a security manager is present then security checks are performed by 179 * the sending methods. A {@link java.net.URLPermission} or {@link java.net.SocketPermission} is required to 180 * access any destination origin server and proxy server utilised. {@code URLPermission}s 181 * should be preferred in policy files over {@code SocketPermission}s given the more 182 * limited scope of {@code URLPermission}. Permission is always implicitly granted to a 183 * system's default proxies. The {@code URLPermission} form used to access proxies uses 184 * a method parameter of {@code "CONNECT"} (for all kinds of proxying) and a url string 185 * of the form {@code "socket://host:port"} where host and port specify the proxy's 186 * address. 187 * 188 * <p> <b>Examples</b> 189 * <pre>{@code 190 * HttpClient client = HttpClient 191 * .newBuilder() 192 * .build(); 193 * 194 * HttpRequest request = HttpRequest 195 * .newBuilder(new URI("http://www.foo.com/")) 196 * .POST(BodyProcessor.fromString("Hello world")) 197 * .build(); 198 * 199 * HttpResponse<Path> response = 200 * client.send(request, BodyHandler.asFile(Paths.get("/path"))); 201 * 202 * Path body = response.body(); 203 * }</pre> 204 * 205 * <p><b>Asynchronous Example</b> 206 * 207 * <p> The above example will work asynchronously, if {@link HttpClient#sendAsync 208 * (HttpRequest, HttpResponse.BodyHandler) sendAsync} is used instead of 209 * {@link HttpClient#send(HttpRequest,HttpResponse.BodyHandler) send} 210 * in which case the returned object is a {@link CompletableFuture}{@code <HttpResponse>} 211 * instead of {@link HttpResponse}. The following example shows how multiple requests 212 * can be sent asynchronously. It also shows how dependent asynchronous operations 213 * (receiving response, and receiving response body) can be chained easily using 214 * one of the many methods in {@code CompletableFuture}. 215 * <pre> 216 * {@code 217 * // fetch a list of target URIs asynchronously and store them in Files. 218 * 219 * List<URI> targets = ... 220 * 221 * List<CompletableFuture<File>> futures = targets 222 * .stream() 223 * .map(target -> client 224 * .sendAsync( 225 * HttpRequest.newBuilder(target) 226 * .GET() 227 * .build(), 228 * BodyHandler.asFile(Paths.get("base", target.getPath()))) 229 * .thenApply(response -> response.body()) 230 * .thenApply(path -> path.toFile())) 231 * .collect(Collectors.toList()); 232 * 233 * // all async operations waited for here 234 * 235 * CompletableFuture.allOf(futures.toArray(new CompletableFuture<?>[0])) 236 * .join(); 237 * 238 * // all elements of futures have completed and can be examined. 239 * // Use File.exists() to check whether file was successfully downloaded 240 * } 241 * </pre> 242 * <p> 243 * Unless otherwise stated, {@code null} parameter values will cause methods 244 * of this class to throw {@code NullPointerException}. 245 * 246 * @since 9 247 */ 248 public abstract class HttpRequest { 249 250 /** 251 * Creates an HttpRequest. 252 */ 253 protected HttpRequest() {} 254 255 /** 256 * A builder of {@link HttpRequest}s. 257 * {@Incubating} 258 * 259 * <p> {@code HttpRequest.Builder}s are created by calling {@link 260 * HttpRequest#newBuilder(URI)} or {@link HttpRequest#newBuilder()}. 261 * 262 * <p> Each of the setter methods in this class modifies the state of the 263 * builder and returns <i>this</i> (ie. the same instance). The methods are 264 * not synchronized and should not be called from multiple threads without 265 * external synchronization. 266 * <p>Note, that not all request headers may be set by user code. Some are 267 * restricted for security reasons and others such as the headers relating 268 * to authentication, redirection and cookie management are managed by 269 * specific APIs rather than through directly user set headers. 270 * 271 * <p> The {@linkplain #build() build} method returns a new {@code 272 * HttpRequest} each time it is invoked. 273 * 274 * @since 9 275 */ 276 public abstract static class Builder { 277 278 /** 279 * Creates a Builder. 280 */ 281 protected Builder() {} 282 283 /** 284 * Sets this {@code HttpRequest}'s request {@code URI}. 285 * 286 * @param uri the request URI 287 * @return this request builder 288 * @throws IllegalArgumentException if the {@code URI} scheme is not 289 * supported. 290 */ 291 public abstract Builder uri(URI uri); 292 293 /** 294 * Request server to acknowledge request before sending request 295 * body. This is disabled by default. If enabled, the server is requested 296 * to send an error response or a {@code 100 Continue} response before the client 297 * sends the request body. This means the request processor for the 298 * request will not be invoked until this interim response is received. 299 * 300 * @param enable {@code true} if Expect continue to be sent 301 * @return this request builder 302 */ 303 public abstract Builder expectContinue(boolean enable); 304 305 /** 306 * Overrides the {@link HttpClient#version() } setting for this 307 * request. This sets the version requested. The corresponding 308 * {@link HttpResponse} should be checked for the version that was 309 * used. 310 * 311 * @param version the HTTP protocol version requested 312 * @return this request builder 313 */ 314 public abstract Builder version(HttpClient.Version version); 315 316 /** 317 * Adds the given name value pair to the set of headers for this request. 318 * 319 * @param name the header name 320 * @param value the header value 321 * @return this request builder 322 */ 323 public abstract Builder header(String name, String value); 324 325 // /** 326 // * Overrides the {@code ProxySelector} set on the request's client for this 327 // * request. 328 // * 329 // * @param proxy the ProxySelector to use 330 // * @return this request builder 331 // */ 332 // public abstract Builder proxy(ProxySelector proxy); 333 334 /** 335 * Adds the given name value pairs to the set of headers for this 336 * request. The supplied {@code String}s must alternate as names and values. 337 * 338 * @param headers the list of String name value pairs 339 * @return this request builder 340 * @throws IllegalArgumentException if there is an odd number of 341 * parameters 342 */ 343 // TODO (spec): consider signature change 344 // public abstract Builder headers(java.util.Map.Entry<String,String>... headers); 345 public abstract Builder headers(String... headers); 346 347 /** 348 * Sets a timeout for this request. If the response is not received 349 * within the specified timeout then a {@link HttpTimeoutException} is 350 * thrown from {@link HttpClient#send(jdk.incubator.http.HttpRequest, 351 * jdk.incubator.http.HttpResponse.BodyHandler) HttpClient::send} or 352 * {@link HttpClient#sendAsync(jdk.incubator.http.HttpRequest, 353 * jdk.incubator.http.HttpResponse.BodyHandler) HttpClient::sendAsync} 354 * completes exceptionally with a {@code HttpTimeoutException}. The effect 355 * of not setting a timeout is the same as setting an infinite Duration, ie. 356 * block forever. 357 * 358 * @param duration the timeout duration 359 * @return this request builder 360 */ 361 public abstract Builder timeout(Duration duration); 362 363 /** 364 * Sets the given name value pair to the set of headers for this 365 * request. This overwrites any previously set values for name. 366 * 367 * @param name the header name 368 * @param value the header value 369 * @return this request builder 370 */ 371 public abstract Builder setHeader(String name, String value); 372 373 /** 374 * Sets the request method of this builder to GET. 375 * 376 * @return a {@code HttpRequest} 377 */ 378 public abstract Builder GET(); 379 380 /** 381 * Sets the request method of this builder to POST and sets its 382 * request body processor to the given value. 383 * 384 * @param body the body processor 385 * 386 * @return a {@code HttpRequest} 387 */ 388 public abstract Builder POST(BodyProcessor body); 389 390 /** 391 * Sets the request method of this builder to PUT and sets its 392 * request body processor to the given value. 393 * 394 * @param body the body processor 395 * 396 * @return a {@code HttpRequest} 397 */ 398 public abstract Builder PUT(BodyProcessor body); 399 400 /** 401 * Sets the request method of this builder to DELETE and sets its 402 * request body processor to the given value. 403 * 404 * @param body the body processor 405 * 406 * @return a {@code HttpRequest} 407 */ 408 409 public abstract Builder DELETE(BodyProcessor body); 410 411 /** 412 * Sets the request method and request body of this builder to the 413 * given values. 414 * 415 * @param body the body processor 416 * @param method the method to use 417 * @return a {@code HttpRequest} 418 * @throws IllegalArgumentException if an unrecognized method is used 419 */ 420 public abstract Builder method(String method, BodyProcessor body); 421 422 /** 423 * Builds and returns a {@link HttpRequest}. 424 * 425 * @return the request 426 */ 427 public abstract HttpRequest build(); 428 429 /** 430 * Returns an exact duplicate copy of this {@code Builder} based on current 431 * state. The new builder can then be modified independently of this 432 * builder. 433 * 434 * @return an exact copy of this Builder 435 */ 436 public abstract Builder copy(); 437 } 438 439 /** 440 * Creates a {@code HttpRequest} builder. 441 * 442 * @param uri the request URI 443 * @return a new request builder 444 * @throws IllegalArgumentException if the URI scheme is not supported. 445 */ 446 public static HttpRequest.Builder newBuilder(URI uri) { 447 return new HttpRequestBuilderImpl(uri); 448 } 449 450 /** 451 * Creates a {@code HttpRequest} builder. 452 * 453 * @return a new request builder 454 */ 455 public static HttpRequest.Builder newBuilder() { 456 return new HttpRequestBuilderImpl(); 457 } 458 459 /** 460 * Returns an {@code Optional} containing the {@link BodyProcessor} 461 * set on this request. If no {@code BodyProcessor} was set in the 462 * requests's builder, then the {@code Optional} is empty. 463 * 464 * @return an {@code Optional} containing this request's 465 * {@code BodyProcessor} 466 */ 467 public abstract Optional<BodyProcessor> bodyProcessor(); 468 469 /** 470 * Returns the request method for this request. If not set explicitly, 471 * the default method for any request is "GET". 472 * 473 * @return this request's method 474 */ 475 public abstract String method(); 476 477 /** 478 * Returns the duration for this request. 479 * 480 * @return this requests duration 481 */ 482 public abstract Duration duration(); 483 484 /** 485 * Returns this request's {@link HttpRequest.Builder#expectContinue(boolean) 486 * expect continue } setting. 487 * 488 * @return this request's expect continue setting 489 */ 490 public abstract boolean expectContinue(); 491 492 /** 493 * Returns this request's request {@code URI}. 494 * 495 * @return this request's URI 496 */ 497 public abstract URI uri(); 498 499 /** 500 * Returns the HTTP protocol version that will be requested for this 501 * {@code HttpRequest}. The corresponding {@link HttpResponse} should be 502 * queried to determine the version that was actually used. 503 * 504 * @return HTTP protocol version 505 */ 506 public abstract HttpClient.Version version(); 507 508 /** 509 * The (user-accessible) request headers that this request was (or will be) 510 * sent with. 511 * 512 * @return this request's HttpHeaders 513 */ 514 public abstract HttpHeaders headers(); 515 516 517 /** 518 * A request body handler which sends no request body. 519 * 520 * @return a BodyProcessor 521 */ 522 public static BodyProcessor noBody() { 523 return new RequestProcessors.EmptyProcessor(); 524 } 525 526 /** 527 * A processor which converts high level Java objects into flows of 528 * {@link java.nio.ByteBuffer}s suitable for sending as request bodies. 529 * {@Incubating} 530 * <p> 531 * {@code BodyProcessor}s implement {@link Flow.Publisher} which means they 532 * act as a publisher of byte buffers. 533 * <p> 534 * The HTTP client implementation subscribes to the processor in 535 * order to receive the flow of outgoing data buffers. The normal semantics 536 * of {@link Flow.Subscriber} and {@link Flow.Publisher} are implemented 537 * by the library and expected from processor implementations. 538 * Each outgoing request results in one {@code Subscriber} subscribing to the 539 * {@code Publisher} in order to provide the sequence of {@code ByteBuffer}s containing 540 * the request body. {@code ByteBuffer}s must be allocated by the processor, 541 * and must not be accessed after being handed over to the library. 542 * These subscriptions complete normally when the request is fully 543 * sent, and can be canceled or terminated early through error. If a request 544 * needs to be resent for any reason, then a new subscription is created 545 * which is expected to generate the same data as before. 546 */ 547 public interface BodyProcessor extends Flow.Publisher<ByteBuffer> { 548 549 /** 550 * Returns a request body processor whose body is the given {@code String}, 551 * converted using the {@link java.nio.charset.StandardCharsets#UTF_8 UTF_8} 552 * character set. 553 * 554 * @param body the String containing the body 555 * @return a BodyProcessor 556 */ 557 static BodyProcessor fromString(String body) { 558 return fromString(body, StandardCharsets.UTF_8); 559 } 560 561 /** 562 * Returns a request body processor whose body is the given {@code String}, converted 563 * using the given character set. 564 * 565 * @param s the String containing the body 566 * @param charset the character set to convert the string to bytes 567 * @return a BodyProcessor 568 */ 569 static BodyProcessor fromString(String s, Charset charset) { 570 return new RequestProcessors.StringProcessor(s, charset); 571 } 572 573 /** 574 * A request body processor that reads its data from an {@link java.io.InputStream}. 575 * A {@link Supplier} of {@code InputStream} is used in case the request needs 576 * to be sent again as the content is not buffered. The {@code Supplier} may return 577 * {@code null} on subsequent attempts in which case, the request fails. 578 * 579 * @param streamSupplier a Supplier of open InputStreams 580 * @return a BodyProcessor 581 */ 582 // TODO (spec): specify that the stream will be closed 583 static BodyProcessor fromInputStream(Supplier<? extends InputStream> streamSupplier) { 584 return new RequestProcessors.InputStreamProcessor(streamSupplier); 585 } 586 587 /** 588 * Returns a request body processor whose body is the given byte array. 589 * 590 * @param buf the byte array containing the body 591 * @return a BodyProcessor 592 */ 593 static BodyProcessor fromByteArray(byte[] buf) { 594 return new RequestProcessors.ByteArrayProcessor(buf); 595 } 596 597 /** 598 * Returns a request body processor whose body is the content of the given byte 599 * array of {@code length} bytes starting from the specified 600 * {@code offset}. 601 * 602 * @param buf the byte array containing the body 603 * @param offset the offset of the first byte 604 * @param length the number of bytes to use 605 * @return a BodyProcessor 606 */ 607 static BodyProcessor fromByteArray(byte[] buf, int offset, int length) { 608 return new RequestProcessors.ByteArrayProcessor(buf, offset, length); 609 } 610 611 /** 612 * A request body processor that takes data from the contents of a File. 613 * 614 * @param path the path to the file containing the body 615 * @return a BodyProcessor 616 * @throws java.io.FileNotFoundException if path not found 617 */ 618 static BodyProcessor fromFile(Path path) throws FileNotFoundException { 619 return new RequestProcessors.FileProcessor(path); 620 } 621 622 /** 623 * A request body processor that takes data from an {@code Iterable} of byte arrays. 624 * An {@link Iterable} is provided which supplies {@link Iterator} instances. 625 * Each attempt to send the request results in one invocation of the 626 * {@code Iterable} 627 * 628 * @param iter an Iterable of byte arrays 629 * @return a BodyProcessor 630 */ 631 static BodyProcessor fromByteArrays(Iterable<byte[]> iter) { 632 return new RequestProcessors.IterableProcessor(iter); 633 } 634 /** 635 * Returns the content length for this request body. May be zero 636 * if no request content being sent, greater than zero for a fixed 637 * length content, and less than zero for an unknown content length. 638 * 639 * @return the content length for this request body if known 640 */ 641 long contentLength(); 642 643 // /** 644 // * Returns a used {@code ByteBuffer} to this request processor. When the 645 // * HTTP implementation has finished sending the contents of a buffer, 646 // * this method is called to return it to the processor for re-use. 647 // * 648 // * @param buffer a used ByteBuffer 649 // */ 650 //void returnBuffer(ByteBuffer buffer); 651 } 652 }