26 package jdk.incubator.http; |
26 package jdk.incubator.http; |
27 |
27 |
28 import java.io.FileNotFoundException; |
28 import java.io.FileNotFoundException; |
29 import java.io.InputStream; |
29 import java.io.InputStream; |
30 import java.net.URI; |
30 import java.net.URI; |
|
31 import java.net.URLPermission; |
31 import java.nio.ByteBuffer; |
32 import java.nio.ByteBuffer; |
32 import java.nio.charset.*; |
33 import java.nio.charset.Charset; |
|
34 import java.nio.charset.StandardCharsets; |
|
35 import java.nio.file.Files; |
33 import java.nio.file.Path; |
36 import java.nio.file.Path; |
|
37 import java.security.AccessController; |
|
38 import java.security.PrivilegedAction; |
34 import java.time.Duration; |
39 import java.time.Duration; |
35 import java.util.Iterator; |
40 import java.util.Iterator; |
|
41 import java.util.Objects; |
36 import java.util.Optional; |
42 import java.util.Optional; |
37 import java.util.concurrent.CompletableFuture; |
43 import java.util.concurrent.CompletableFuture; |
|
44 import java.util.concurrent.Executor; |
38 import java.util.concurrent.Flow; |
45 import java.util.concurrent.Flow; |
39 import java.util.function.Supplier; |
46 import java.util.function.Supplier; |
|
47 import static java.nio.charset.StandardCharsets.UTF_8; |
40 |
48 |
41 /** |
49 /** |
42 * Represents one HTTP request which can be sent to a server. |
50 * Represents one HTTP request which can be sent to a server. |
43 * {@Incubating } |
51 * {@Incubating } |
44 * |
52 * |
45 * <p> {@code HttpRequest}s are built from {@code HttpRequest} |
53 * <p> {@code HttpRequest} instances are built from {@code HttpRequest} |
46 * {@link HttpRequest.Builder builder}s. {@code HttpRequest} builders are |
54 * {@linkplain HttpRequest.Builder builders}. {@code HttpRequest} builders |
47 * obtained by calling {@link HttpRequest#newBuilder(java.net.URI) |
55 * are obtained by calling {@link HttpRequest#newBuilder(URI) HttpRequest.newBuilder}. |
48 * HttpRequest.newBuilder}. |
56 * A request's {@linkplain URI}, headers and body can be set. Request bodies are |
49 * A request's {@link java.net.URI}, headers and body can be set. Request bodies |
57 * provided through a {@link BodyPublisher} object supplied to the |
50 * are provided through a {@link BodyProcessor} object supplied to the |
58 * {@link Builder#DELETE(BodyPublisher) DELETE}, |
51 * {@link Builder#DELETE(jdk.incubator.http.HttpRequest.BodyProcessor) DELETE}, |
59 * {@link Builder#POST(BodyPublisher) POST} or |
52 * {@link Builder#POST(jdk.incubator.http.HttpRequest.BodyProcessor) POST} or |
60 * {@link Builder#PUT(BodyPublisher) PUT} methods. |
53 * {@link Builder#PUT(jdk.incubator.http.HttpRequest.BodyProcessor) PUT} methods. |
|
54 * {@link Builder#GET() GET} does not take a body. Once all required |
61 * {@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 |
62 * parameters have been set in the builder, {@link Builder#build() } is called |
56 * to return the {@code HttpRequest}. Builders can also be copied |
63 * to return the {@code HttpRequest}. Builders can also be copied and modified |
57 * and modified multiple times in order to build multiple related requests that |
64 * multiple times in order to build multiple related requests that differ in |
58 * differ in some parameters. |
65 * some parameters. |
59 * |
66 * |
60 * <p> Two simple, example HTTP interactions are shown below: |
67 * <p> Two simple, example HTTP interactions are shown below: |
61 * <pre> |
68 * <pre> |
62 * {@code |
69 * {@code |
63 * HttpClient client = HttpClient.newHttpClient(); |
70 * HttpClient client = HttpClient.newHttpClient(); |
77 * // POST |
84 * // POST |
78 * HttpResponse<Path> response = client.send( |
85 * HttpResponse<Path> response = client.send( |
79 * HttpRequest |
86 * HttpRequest |
80 * .newBuilder(new URI("http://www.foo.com/")) |
87 * .newBuilder(new URI("http://www.foo.com/")) |
81 * .headers("Foo", "foovalue", "Bar", "barvalue") |
88 * .headers("Foo", "foovalue", "Bar", "barvalue") |
82 * .POST(BodyProcessor.fromString("Hello world")) |
89 * .POST(BodyPublisher.fromString("Hello world")) |
83 * .build(), |
90 * .build(), |
84 * BodyHandler.asFile(Paths.get("/path")) |
91 * BodyHandler.asFile(Paths.get("/path")) |
85 * ); |
92 * ); |
86 * int statusCode = response.statusCode(); |
93 * int statusCode = response.statusCode(); |
87 * Path body = response.body(); // should be "/path" |
94 * Path body = response.body(); // should be "/path" |
88 * } |
95 * } |
89 * </pre> |
96 * </pre> |
|
97 * |
90 * <p> The request is sent and the response obtained by calling one of the |
98 * <p> The request is sent and the response obtained by calling one of the |
91 * following methods in {@link HttpClient}. |
99 * following methods in {@link HttpClient}. |
92 * <ul><li>{@link HttpClient#send(HttpRequest, HttpResponse.BodyHandler)} blocks |
100 * <ul><li>{@link HttpClient#send(HttpRequest, HttpResponse.BodyHandler)} blocks |
93 * until the entire request has been sent and the response has been received.</li> |
101 * until the entire request has been sent and the response has been received.</li> |
94 * <li>{@link HttpClient#sendAsync(HttpRequest,HttpResponse.BodyHandler)} sends the |
102 * <li>{@link HttpClient#sendAsync(HttpRequest,HttpResponse.BodyHandler)} sends the |
95 * request and receives the response asynchronously. Returns immediately with a |
103 * request and receives the response asynchronously. Returns immediately with a |
96 * {@link java.util.concurrent.CompletableFuture CompletableFuture}<{@link |
104 * {@link java.util.concurrent.CompletableFuture CompletableFuture}<{@link |
97 * HttpResponse}>.</li> |
105 * HttpResponse}>.</li> |
98 * <li>{@link HttpClient#sendAsync(HttpRequest,HttpResponse.MultiProcessor) } |
106 * <li>{@link HttpClient#sendAsync(HttpRequest, HttpResponse.MultiSubscriber) } |
99 * sends the request asynchronously, expecting multiple responses. This |
107 * sends the request asynchronously, expecting multiple responses. This |
100 * capability is of most relevance to HTTP/2 server push, but can be used for |
108 * 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> |
109 * single responses (HTTP/1.1 or HTTP/2) also.</li> |
102 * </ul> |
110 * </ul> |
103 * |
111 * |
107 * |
115 * |
108 * <p> See below for discussion of synchronous versus asynchronous usage. |
116 * <p> See below for discussion of synchronous versus asynchronous usage. |
109 * |
117 * |
110 * <p> <b>Request bodies</b> |
118 * <p> <b>Request bodies</b> |
111 * |
119 * |
112 * <p> Request bodies are sent using one of the request processor implementations |
120 * <p> Request bodies can be sent using one of the convenience request publisher |
113 * below provided in {@link HttpRequest.BodyProcessor}, or else a custom implementation can be |
121 * implementations below, provided in {@link BodyPublisher}. Alternatively, a |
114 * used. |
122 * custom Publisher implementation can be used. |
115 * <ul> |
123 * <ul> |
116 * <li>{@link BodyProcessor#fromByteArray(byte[]) fromByteArray(byte[])} from byte array</li> |
124 * <li>{@link BodyPublisher#fromByteArray(byte[]) fromByteArray(byte[])} from byte array</li> |
117 * <li>{@link BodyProcessor#fromByteArrays(Iterable) fromByteArrays(Iterable)} |
125 * <li>{@link BodyPublisher#fromByteArrays(Iterable) fromByteArrays(Iterable)} |
118 * from an Iterable of byte arrays</li> |
126 * from an Iterable of byte arrays</li> |
119 * <li>{@link BodyProcessor#fromFile(java.nio.file.Path) fromFile(Path)} from the file located |
127 * <li>{@link BodyPublisher#fromFile(java.nio.file.Path) fromFile(Path)} from the file located |
120 * at the given Path</li> |
128 * at the given Path</li> |
121 * <li>{@link BodyProcessor#fromString(java.lang.String) fromString(String)} from a String </li> |
129 * <li>{@link BodyPublisher#fromString(java.lang.String) fromString(String)} from a String </li> |
122 * <li>{@link BodyProcessor#fromInputStream(Supplier) fromInputStream}({@link Supplier}< |
130 * <li>{@link BodyPublisher#fromInputStream(Supplier) fromInputStream}({@link Supplier}< |
123 * {@link InputStream}>) from an InputStream obtained from a Supplier</li> |
131 * {@link InputStream}>) from an InputStream obtained from a Supplier</li> |
124 * <li>{@link BodyProcessor#noBody() } no request body is sent</li> |
132 * <li>{@link BodyPublisher#noBody() } no request body is sent</li> |
125 * </ul> |
133 * </ul> |
126 * |
134 * |
127 * <p> <b>Response bodies</b> |
135 * <p> <b>Response bodies</b> |
128 * |
136 * |
129 * <p>Responses bodies are handled at two levels. When sending the request, |
137 * <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}) |
138 * a response body handler is specified. This is a function ({@linkplain |
131 * which will be called with the response status code and headers, once these are received. This |
139 * HttpResponse.BodyHandler}) which will be called with the response status code |
132 * function is then expected to return a {@link HttpResponse.BodyProcessor} |
140 * and headers, once they are received. This function is then expected to return |
133 * {@code <T>} which is then used to read the response body converting it |
141 * a {@link HttpResponse.BodySubscriber}{@code <T>} which is then used to read |
134 * into an instance of T. After this occurs, the response becomes |
142 * the response body, converting it into an instance of T. After this occurs, |
135 * available in a {@link HttpResponse} and {@link HttpResponse#body()} can then |
143 * the response becomes available in a {@link HttpResponse}, and {@link |
136 * be called to obtain the body. Some implementations and examples of usage of both {@link |
144 * HttpResponse#body()} can then be called to obtain the actual body. Some |
137 * HttpResponse.BodyProcessor} and {@link HttpResponse.BodyHandler} |
145 * implementations and examples of usage of both {@link |
138 * are provided in {@link HttpResponse}: |
146 * HttpResponse.BodySubscriber} and {@link HttpResponse.BodyHandler} are |
139 * <p><b>Some of the pre-defined body handlers</b><br> |
147 * provided in {@link HttpResponse}: |
|
148 * |
|
149 * <p> <b>Some of the pre-defined body handlers</b><br> |
140 * <ul> |
150 * <ul> |
141 * <li>{@link HttpResponse.BodyHandler#asByteArray() BodyHandler.asByteArray()} |
151 * <li>{@link HttpResponse.BodyHandler#asByteArray() BodyHandler.asByteArray()} |
142 * stores the body in a byte array</li> |
152 * stores the body in a byte array</li> |
143 * <li>{@link HttpResponse.BodyHandler#asString() BodyHandler.asString()} |
153 * <li>{@link HttpResponse.BodyHandler#asString() BodyHandler.asString()} |
144 * stores the body as a String </li> |
154 * stores the body as a String </li> |
150 * |
160 * |
151 * <p> <b>Multi responses</b> |
161 * <p> <b>Multi responses</b> |
152 * |
162 * |
153 * <p> With HTTP/2 it is possible for a server to return a main response and zero |
163 * <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 |
164 * or more additional responses (known as server pushes) to a client-initiated |
155 * request. These are handled using a special response processor called {@link |
165 * request. These are handled using a special response subscriber called {@link |
156 * HttpResponse.MultiProcessor}. |
166 * HttpResponse.MultiSubscriber}. |
157 * |
167 * |
158 * <p> <b>Blocking/asynchronous behavior and thread usage</b> |
168 * <p> <b>Blocking/asynchronous behavior and thread usage</b> |
159 * |
169 * |
160 * <p> There are two styles of request sending: <i>synchronous</i> and |
170 * <p> There are two styles of request sending: <i>synchronous</i> and |
161 * <i>asynchronous</i>. {@link HttpClient#send(HttpRequest, HttpResponse.BodyHandler) } |
171 * <i>asynchronous</i>. {@link HttpClient#send(HttpRequest, HttpResponse.BodyHandler) } |
162 * blocks the calling thread until the request has been sent and the response received. |
172 * blocks the calling thread until the request has been sent and the response received. |
163 * |
173 * |
164 * <p> {@link HttpClient#sendAsync(HttpRequest, HttpResponse.BodyHandler)} is asynchronous and returns |
174 * <p> {@link HttpClient#sendAsync(HttpRequest, HttpResponse.BodyHandler)} is |
165 * immediately with a {@link java.util.concurrent.CompletableFuture}<{@link |
175 * asynchronous and returns immediately with a {@link CompletableFuture}<{@link |
166 * HttpResponse}> and when this object completes (in a background thread) the |
176 * HttpResponse}> and when this object completes (possibly in a different |
167 * response has been received. |
177 * thread) the response has been received. |
168 * |
178 * |
169 * <p> {@link HttpClient#sendAsync(HttpRequest,HttpResponse.MultiProcessor)} |
179 * <p> {@link HttpClient#sendAsync(HttpRequest, HttpResponse.MultiSubscriber)} |
170 * is the variant for multi responses and is also asynchronous. |
180 * is the variant for multi responses and is also asynchronous. |
171 * |
181 * |
172 * <p> {@code CompletableFuture}s can be combined in different ways to declare the |
182 * <p> Instances of {@code CompletableFuture} can be combined in different ways |
173 * dependencies among several asynchronous tasks, while allowing for the maximum |
183 * to declare the dependencies among several asynchronous tasks, while allowing |
174 * level of parallelism to be utilized. |
184 * for the maximum level of parallelism to be utilized. |
175 * |
185 * |
176 * <p> <b>Security checks</b> |
186 * <p> <a id="securitychecks"></a><b>Security checks</b></a> |
177 * |
187 * |
178 * <p> If a security manager is present then security checks are performed by |
188 * <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 |
189 * the HTTP Client's sending methods. An appropriate {@link URLPermission} is |
180 * access any destination origin server and proxy server utilised. {@code URLPermission}s |
190 * required to access the destination server, and proxy server if one has |
181 * should be preferred in policy files over {@code SocketPermission}s given the more |
191 * been configured. The {@code URLPermission} form used to access proxies uses a |
182 * limited scope of {@code URLPermission}. Permission is always implicitly granted to a |
192 * method parameter of {@code "CONNECT"} (for all kinds of proxying) and a URL |
183 * system's default proxies. The {@code URLPermission} form used to access proxies uses |
193 * string of the form {@code "socket://host:port"} where host and port specify |
184 * a method parameter of {@code "CONNECT"} (for all kinds of proxying) and a url string |
194 * the proxy's address. |
185 * of the form {@code "socket://host:port"} where host and port specify the proxy's |
195 * |
186 * address. |
196 * <p> In this implementation, if an explicit {@linkplain |
|
197 * HttpClient.Builder#executor(Executor) executor} has not been set for an |
|
198 * {@code HttpClient}, and a security manager has been installed, then the |
|
199 * default executor will execute asynchronous and dependent tasks in a context |
|
200 * that is granted no permissions. Custom {@linkplain HttpRequest.BodyPublisher |
|
201 * request body publishers}, {@linkplain HttpResponse.BodyHandler response body |
|
202 * handlers}, {@linkplain HttpResponse.BodySubscriber response body subscribers}, |
|
203 * and {@linkplain WebSocket.Listener WebSocket Listeners}, if executing |
|
204 * operations that require privileges, should do so within an appropriate |
|
205 * {@linkplain AccessController#doPrivileged(PrivilegedAction) privileged context}. |
187 * |
206 * |
188 * <p> <b>Examples</b> |
207 * <p> <b>Examples</b> |
189 * <pre>{@code |
208 * <pre>{@code |
190 * HttpClient client = HttpClient |
209 * HttpClient client = HttpClient |
191 * .newBuilder() |
210 * .newBuilder() |
192 * .build(); |
211 * .build(); |
193 * |
212 * |
194 * HttpRequest request = HttpRequest |
213 * HttpRequest request = HttpRequest |
195 * .newBuilder(new URI("http://www.foo.com/")) |
214 * .newBuilder(new URI("http://www.foo.com/")) |
196 * .POST(BodyProcessor.fromString("Hello world")) |
215 * .POST(BodyPublisher.fromString("Hello world")) |
197 * .build(); |
216 * .build(); |
198 * |
217 * |
199 * HttpResponse<Path> response = |
218 * HttpResponse<Path> response = |
200 * client.send(request, BodyHandler.asFile(Paths.get("/path"))); |
219 * client.send(request, BodyHandler.asFile(Paths.get("/path"))); |
201 * |
220 * |
284 * Sets this {@code HttpRequest}'s request {@code URI}. |
304 * Sets this {@code HttpRequest}'s request {@code URI}. |
285 * |
305 * |
286 * @param uri the request URI |
306 * @param uri the request URI |
287 * @return this request builder |
307 * @return this request builder |
288 * @throws IllegalArgumentException if the {@code URI} scheme is not |
308 * @throws IllegalArgumentException if the {@code URI} scheme is not |
289 * supported. |
309 * supported |
290 */ |
310 */ |
291 public abstract Builder uri(URI uri); |
311 public abstract Builder uri(URI uri); |
292 |
312 |
293 /** |
313 /** |
294 * Request server to acknowledge request before sending request |
314 * Requests the server to acknowledge the request before sending the |
295 * body. This is disabled by default. If enabled, the server is requested |
315 * body. This is disabled by default. If enabled, the server is |
296 * to send an error response or a {@code 100 Continue} response before the client |
316 * requested to send an error response or a {@code 100 Continue} |
297 * sends the request body. This means the request processor for the |
317 * response before the client sends the request body. This means the |
298 * request will not be invoked until this interim response is received. |
318 * request publisher for the request will not be invoked until this |
|
319 * interim response is received. |
299 * |
320 * |
300 * @param enable {@code true} if Expect continue to be sent |
321 * @param enable {@code true} if Expect continue to be sent |
301 * @return this request builder |
322 * @return this request builder |
302 */ |
323 */ |
303 public abstract Builder expectContinue(boolean enable); |
324 public abstract Builder expectContinue(boolean enable); |
304 |
325 |
305 /** |
326 /** |
306 * Sets the preferred {@link HttpClient.Version} for this |
327 * Sets the preferred {@link HttpClient.Version} for this request. |
307 * request. The corresponding {@link HttpResponse} should be checked |
328 * |
308 * for the version that was used. If the version is not set |
329 * <p> The corresponding {@link HttpResponse} should be checked for the |
309 * in a request, then the version requested will be that of the |
330 * version that was actually used. If the version is not set in a |
310 * sending {@link HttpClient}. |
331 * request, then the version requested will be that of the sending |
|
332 * {@link HttpClient}. |
311 * |
333 * |
312 * @param version the HTTP protocol version requested |
334 * @param version the HTTP protocol version requested |
313 * @return this request builder |
335 * @return this request builder |
314 */ |
336 */ |
315 public abstract Builder version(HttpClient.Version version); |
337 public abstract Builder version(HttpClient.Version version); |
316 |
338 |
317 /** |
339 /** |
318 * Adds the given name value pair to the set of headers for this request. |
340 * Adds the given name value pair to the set of headers for this request. |
|
341 * The given value is added to the list of values for that name. |
319 * |
342 * |
320 * @param name the header name |
343 * @param name the header name |
321 * @param value the header value |
344 * @param value the header value |
322 * @return this request builder |
345 * @return this request builder |
|
346 * @throws IllegalArgumentException if the header name or value is not |
|
347 * valid, see <a href="https://tools.ietf.org/html/rfc7230#section-3.2"> |
|
348 * RFC 7230 section-3.2</a> |
323 */ |
349 */ |
324 public abstract Builder header(String name, String value); |
350 public abstract Builder header(String name, String value); |
325 |
351 |
326 // /** |
|
327 // * Overrides the {@code ProxySelector} set on the request's client for this |
|
328 // * request. |
|
329 // * |
|
330 // * @param proxy the ProxySelector to use |
|
331 // * @return this request builder |
|
332 // */ |
|
333 // public abstract Builder proxy(ProxySelector proxy); |
|
334 |
|
335 /** |
352 /** |
336 * Adds the given name value pairs to the set of headers for this |
353 * Adds the given name value pairs to the set of headers for this |
337 * request. The supplied {@code String}s must alternate as names and values. |
354 * request. The supplied {@code String} instances must alternate as |
338 * |
355 * header names and header values. |
339 * @param headers the list of String name value pairs |
356 * To add several values to the same name then the same name must |
|
357 * be supplied with each new value. |
|
358 * |
|
359 * @param headers the list of name value pairs |
340 * @return this request builder |
360 * @return this request builder |
341 * @throws IllegalArgumentException if there is an odd number of |
361 * @throws IllegalArgumentException if there are an odd number of |
342 * parameters |
362 * parameters, or if a header name or value is not valid, see |
343 */ |
363 * <a href="https://tools.ietf.org/html/rfc7230#section-3.2"> |
344 // TODO (spec): consider signature change |
364 * RFC 7230 section-3.2</a> |
345 // public abstract Builder headers(java.util.Map.Entry<String,String>... headers); |
365 */ |
346 public abstract Builder headers(String... headers); |
366 public abstract Builder headers(String... headers); |
347 |
367 |
348 /** |
368 /** |
349 * Sets a timeout for this request. If the response is not received |
369 * Sets a timeout for this request. If the response is not received |
350 * within the specified timeout then a {@link HttpTimeoutException} is |
370 * within the specified timeout then a {@link HttpTimeoutException} is |
356 * of not setting a timeout is the same as setting an infinite Duration, ie. |
376 * of not setting a timeout is the same as setting an infinite Duration, ie. |
357 * block forever. |
377 * block forever. |
358 * |
378 * |
359 * @param duration the timeout duration |
379 * @param duration the timeout duration |
360 * @return this request builder |
380 * @return this request builder |
|
381 * @throws IllegalArgumentException if the duration is non-positive |
361 */ |
382 */ |
362 public abstract Builder timeout(Duration duration); |
383 public abstract Builder timeout(Duration duration); |
363 |
384 |
364 /** |
385 /** |
365 * Sets the given name value pair to the set of headers for this |
386 * Sets the given name value pair to the set of headers for this |
366 * request. This overwrites any previously set values for name. |
387 * request. This overwrites any previously set values for name. |
367 * |
388 * |
368 * @param name the header name |
389 * @param name the header name |
369 * @param value the header value |
390 * @param value the header value |
370 * @return this request builder |
391 * @return this request builder |
|
392 * @throws IllegalArgumentException if the header name or value is not valid, |
|
393 * see <a href="https://tools.ietf.org/html/rfc7230#section-3.2"> |
|
394 * RFC 7230 section-3.2</a> |
371 */ |
395 */ |
372 public abstract Builder setHeader(String name, String value); |
396 public abstract Builder setHeader(String name, String value); |
373 |
397 |
374 /** |
398 /** |
375 * Sets the request method of this builder to GET. |
399 * Sets the request method of this builder to GET. |
|
400 * This is the default. |
376 * |
401 * |
377 * @return a {@code HttpRequest} |
402 * @return a {@code HttpRequest} |
378 */ |
403 */ |
379 public abstract Builder GET(); |
404 public abstract Builder GET(); |
380 |
405 |
381 /** |
406 /** |
382 * Sets the request method of this builder to POST and sets its |
407 * Sets the request method of this builder to POST and sets its |
383 * request body processor to the given value. |
408 * request body publisher to the given value. |
384 * |
409 * |
385 * @param body the body processor |
410 * @param bodyPublisher the body publisher |
386 * |
411 * |
387 * @return a {@code HttpRequest} |
412 * @return a {@code HttpRequest} |
388 */ |
413 */ |
389 public abstract Builder POST(BodyProcessor body); |
414 public abstract Builder POST(BodyPublisher bodyPublisher); |
390 |
415 |
391 /** |
416 /** |
392 * Sets the request method of this builder to PUT and sets its |
417 * Sets the request method of this builder to PUT and sets its |
393 * request body processor to the given value. |
418 * request body publisher to the given value. |
394 * |
419 * |
395 * @param body the body processor |
420 * @param bodyPublisher the body publisher |
396 * |
421 * |
397 * @return a {@code HttpRequest} |
422 * @return a {@code HttpRequest} |
398 */ |
423 */ |
399 public abstract Builder PUT(BodyProcessor body); |
424 public abstract Builder PUT(BodyPublisher bodyPublisher); |
400 |
425 |
401 /** |
426 /** |
402 * Sets the request method of this builder to DELETE and sets its |
427 * Sets the request method of this builder to DELETE and sets its |
403 * request body processor to the given value. |
428 * request body publisher to the given value. |
404 * |
429 * |
405 * @param body the body processor |
430 * @param bodyPublisher the body publisher |
406 * |
431 * |
407 * @return a {@code HttpRequest} |
432 * @return a {@code HttpRequest} |
408 */ |
433 */ |
409 |
434 |
410 public abstract Builder DELETE(BodyProcessor body); |
435 public abstract Builder DELETE(BodyPublisher bodyPublisher); |
411 |
436 |
412 /** |
437 /** |
413 * Sets the request method and request body of this builder to the |
438 * Sets the request method and request body of this builder to the |
414 * given values. |
439 * given values. |
415 * |
440 * |
416 * @param body the body processor |
441 * @apiNote The {@linkplain BodyPublisher#noBody() noBody} request |
|
442 * body publisher can be used where no request body is required or |
|
443 * appropriate. |
|
444 * |
417 * @param method the method to use |
445 * @param method the method to use |
|
446 * @param bodyPublisher the body publisher |
418 * @return a {@code HttpRequest} |
447 * @return a {@code HttpRequest} |
419 * @throws IllegalArgumentException if an unrecognized method is used |
448 * @throws IllegalArgumentException if the method is unrecognised |
420 */ |
449 */ |
421 public abstract Builder method(String method, BodyProcessor body); |
450 public abstract Builder method(String method, BodyPublisher bodyPublisher); |
422 |
451 |
423 /** |
452 /** |
424 * Builds and returns a {@link HttpRequest}. |
453 * Builds and returns a {@link HttpRequest}. |
425 * |
454 * |
426 * @return the request |
455 * @return the request |
|
456 * @throws IllegalStateException if a URI has not been set |
427 */ |
457 */ |
428 public abstract HttpRequest build(); |
458 public abstract HttpRequest build(); |
429 |
459 |
430 /** |
460 /** |
431 * Returns an exact duplicate copy of this {@code Builder} based on current |
461 * Returns an exact duplicate copy of this {@code Builder} based on |
432 * state. The new builder can then be modified independently of this |
462 * current state. The new builder can then be modified independently of |
433 * builder. |
463 * this builder. |
434 * |
464 * |
435 * @return an exact copy of this Builder |
465 * @return an exact copy of this Builder |
436 */ |
466 */ |
437 public abstract Builder copy(); |
467 public abstract Builder copy(); |
438 } |
468 } |
515 * |
546 * |
516 * @return this request's HttpHeaders |
547 * @return this request's HttpHeaders |
517 */ |
548 */ |
518 public abstract HttpHeaders headers(); |
549 public abstract HttpHeaders headers(); |
519 |
550 |
520 |
551 /** |
521 /** |
552 * Tests this HTTP request instance for equality with the given object. |
522 * A request body handler which sends no request body. |
553 * |
523 * |
554 * <p> If the given object is not an {@code HttpRequest} then this |
524 * @return a BodyProcessor |
555 * method returns {@code false}. Two HTTP requests are equal if their URI, |
525 */ |
556 * method, and headers fields are all equal. |
526 public static BodyProcessor noBody() { |
557 * |
527 return new RequestProcessors.EmptyProcessor(); |
558 * <p> This method satisfies the general contract of the {@link |
|
559 * Object#equals(Object) Object.equals} method. |
|
560 * |
|
561 * @param obj the object to which this object is to be compared |
|
562 * @return {@code true} if, and only if, the given object is an {@code |
|
563 * HttpRequest} that is equal to this HTTP request |
|
564 */ |
|
565 @Override |
|
566 public final boolean equals(Object obj) { |
|
567 if (! (obj instanceof HttpRequest)) |
|
568 return false; |
|
569 HttpRequest that = (HttpRequest)obj; |
|
570 if (!that.method().equals(this.method())) |
|
571 return false; |
|
572 if (!that.uri().equals(this.uri())) |
|
573 return false; |
|
574 if (!that.headers().equals(this.headers())) |
|
575 return false; |
|
576 return true; |
528 } |
577 } |
529 |
578 |
530 /** |
579 /** |
531 * A processor which converts high level Java objects into flows of |
580 * Computes a hash code for this HTTP request instance. |
532 * {@link java.nio.ByteBuffer}s suitable for sending as request bodies. |
581 * |
|
582 * <p> The hash code is based upon the HTTP request's URI, method, and |
|
583 * header components, and satisfies the general contract of the |
|
584 * {@link Object#hashCode Object.hashCode} method. |
|
585 * |
|
586 * @return the hash-code value for this HTTP request |
|
587 */ |
|
588 public final int hashCode() { |
|
589 return method().hashCode() |
|
590 + uri().hashCode() |
|
591 + headers().hashCode(); |
|
592 } |
|
593 |
|
594 /** |
|
595 * A Publisher which converts high level Java objects into flows of |
|
596 * byte buffers suitable for sending as request bodies. |
533 * {@Incubating} |
597 * {@Incubating} |
534 * <p> |
598 * |
535 * {@code BodyProcessor}s implement {@link Flow.Publisher} which means they |
599 * <p> The {@code BodyPublisher} class implements {@link Flow.Publisher |
536 * act as a publisher of byte buffers. |
600 * Flow.Publisher<ByteBuffer>} which means that a {@code BodyPublisher} |
537 * <p> |
601 * acts as a publisher of {@linkplain ByteBuffer byte buffers}. |
538 * The HTTP client implementation subscribes to the processor in |
602 * |
539 * order to receive the flow of outgoing data buffers. The normal semantics |
603 * <p> The HTTP client implementation subscribes to the publisher in order |
540 * of {@link Flow.Subscriber} and {@link Flow.Publisher} are implemented |
604 * to receive the flow of outgoing data buffers. The normal semantics of |
541 * by the library and expected from processor implementations. |
605 * {@link Flow.Subscriber} and {@link Flow.Publisher} are implemented by the |
542 * Each outgoing request results in one {@code Subscriber} subscribing to the |
606 * library and are expected from publisher implementations. Each outgoing |
543 * {@code Publisher} in order to provide the sequence of {@code ByteBuffer}s containing |
607 * request results in one {@code Subscriber} subscribing to the {@code |
544 * the request body. {@code ByteBuffer}s must be allocated by the processor, |
608 * BodyPublisher} in order to provide the sequence of byte buffers |
545 * and must not be accessed after being handed over to the library. |
609 * containing the request body. |
546 * These subscriptions complete normally when the request is fully |
610 * Instances of {@code ByteBuffer} published by the publisher must be |
547 * sent, and can be canceled or terminated early through error. If a request |
611 * allocated by the publisher, and must not be accessed after being handed |
|
612 * over to the library. |
|
613 * These subscriptions complete normally when the request is fully sent, |
|
614 * and can be canceled or terminated early through error. If a request |
548 * needs to be resent for any reason, then a new subscription is created |
615 * needs to be resent for any reason, then a new subscription is created |
549 * which is expected to generate the same data as before. |
616 * which is expected to generate the same data as before. |
550 */ |
617 * |
551 public interface BodyProcessor extends Flow.Publisher<ByteBuffer> { |
618 * <p> A publisher that reports a {@linkplain #contentLength() content |
552 |
619 * length} of {@code 0} may not be subscribed to by the HTTP client |
553 /** |
620 * implementation, as it has effectively no data to publish. |
554 * Returns a request body processor whose body is the given {@code String}, |
621 */ |
555 * converted using the {@link java.nio.charset.StandardCharsets#UTF_8 UTF_8} |
622 public interface BodyPublisher extends Flow.Publisher<ByteBuffer> { |
|
623 |
|
624 /** |
|
625 * Returns a request body publisher whose body is the given {@code |
|
626 * String}, converted using the {@link StandardCharsets#UTF_8 UTF_8} |
556 * character set. |
627 * character set. |
557 * |
628 * |
558 * @param body the String containing the body |
629 * @param body the String containing the body |
559 * @return a BodyProcessor |
630 * @return a BodyPublisher |
560 */ |
631 */ |
561 static BodyProcessor fromString(String body) { |
632 static BodyPublisher fromString(String body) { |
562 return fromString(body, StandardCharsets.UTF_8); |
633 return fromString(body, UTF_8); |
563 } |
634 } |
564 |
635 |
565 /** |
636 /** |
566 * Returns a request body processor whose body is the given {@code String}, converted |
637 * Returns a request body publisher whose body is the given {@code |
567 * using the given character set. |
638 * String}, converted using the given character set. |
568 * |
639 * |
569 * @param s the String containing the body |
640 * @param s the String containing the body |
570 * @param charset the character set to convert the string to bytes |
641 * @param charset the character set to convert the string to bytes |
571 * @return a BodyProcessor |
642 * @return a BodyPublisher |
572 */ |
643 */ |
573 static BodyProcessor fromString(String s, Charset charset) { |
644 static BodyPublisher fromString(String s, Charset charset) { |
574 return new RequestProcessors.StringProcessor(s, charset); |
645 return new RequestPublishers.StringPublisher(s, charset); |
575 } |
646 } |
576 |
647 |
577 /** |
648 /** |
578 * A request body processor that reads its data from an {@link java.io.InputStream}. |
649 * A request body publisher that reads its data from an {@link |
579 * A {@link Supplier} of {@code InputStream} is used in case the request needs |
650 * InputStream}. A {@link Supplier} of {@code InputStream} is used in |
580 * to be sent again as the content is not buffered. The {@code Supplier} may return |
651 * case the request needs to be repeated, as the content is not buffered. |
581 * {@code null} on subsequent attempts in which case, the request fails. |
652 * The {@code Supplier} may return {@code null} on subsequent attempts, |
|
653 * in which case the request fails. |
582 * |
654 * |
583 * @param streamSupplier a Supplier of open InputStreams |
655 * @param streamSupplier a Supplier of open InputStreams |
584 * @return a BodyProcessor |
656 * @return a BodyPublisher |
585 */ |
657 */ |
586 // TODO (spec): specify that the stream will be closed |
658 // TODO (spec): specify that the stream will be closed |
587 static BodyProcessor fromInputStream(Supplier<? extends InputStream> streamSupplier) { |
659 static BodyPublisher fromInputStream(Supplier<? extends InputStream> streamSupplier) { |
588 return new RequestProcessors.InputStreamProcessor(streamSupplier); |
660 return new RequestPublishers.InputStreamPublisher(streamSupplier); |
589 } |
661 } |
590 |
662 |
591 /** |
663 /** |
592 * Returns a request body processor whose body is the given byte array. |
664 * Returns a request body publisher whose body is the given byte array. |
593 * |
665 * |
594 * @param buf the byte array containing the body |
666 * @param buf the byte array containing the body |
595 * @return a BodyProcessor |
667 * @return a BodyPublisher |
596 */ |
668 */ |
597 static BodyProcessor fromByteArray(byte[] buf) { |
669 static BodyPublisher fromByteArray(byte[] buf) { |
598 return new RequestProcessors.ByteArrayProcessor(buf); |
670 return new RequestPublishers.ByteArrayPublisher(buf); |
599 } |
671 } |
600 |
672 |
601 /** |
673 /** |
602 * Returns a request body processor whose body is the content of the given byte |
674 * Returns a request body publisher whose body is the content of the |
603 * array of {@code length} bytes starting from the specified |
675 * given byte array of {@code length} bytes starting from the specified |
604 * {@code offset}. |
676 * {@code offset}. |
605 * |
677 * |
606 * @param buf the byte array containing the body |
678 * @param buf the byte array containing the body |
607 * @param offset the offset of the first byte |
679 * @param offset the offset of the first byte |
608 * @param length the number of bytes to use |
680 * @param length the number of bytes to use |
609 * @return a BodyProcessor |
681 * @return a BodyPublisher |
610 */ |
682 * @throws IndexOutOfBoundsException if the sub-range is defined to be |
611 static BodyProcessor fromByteArray(byte[] buf, int offset, int length) { |
683 * out-of-bounds |
612 return new RequestProcessors.ByteArrayProcessor(buf, offset, length); |
684 */ |
613 } |
685 static BodyPublisher fromByteArray(byte[] buf, int offset, int length) { |
614 |
686 Objects.checkFromIndexSize(offset, length, buf.length); |
615 /** |
687 return new RequestPublishers.ByteArrayPublisher(buf, offset, length); |
616 * A request body processor that takes data from the contents of a File. |
688 } |
|
689 |
|
690 private static String pathForSecurityCheck(Path path) { |
|
691 return path.toFile().getPath(); |
|
692 } |
|
693 |
|
694 /** |
|
695 * A request body publisher that takes data from the contents of a File. |
617 * |
696 * |
618 * @param path the path to the file containing the body |
697 * @param path the path to the file containing the body |
619 * @return a BodyProcessor |
698 * @return a BodyPublisher |
620 * @throws java.io.FileNotFoundException if path not found |
699 * @throws java.io.FileNotFoundException if the path is not found |
621 */ |
700 * @throws SecurityException if a security manager has been installed |
622 static BodyProcessor fromFile(Path path) throws FileNotFoundException { |
701 * and it denies {@link SecurityManager#checkRead(String) |
623 return new RequestProcessors.FileProcessor(path); |
702 * read access} to the given file |
624 } |
703 */ |
625 |
704 static BodyPublisher fromFile(Path path) throws FileNotFoundException { |
626 /** |
705 Objects.requireNonNull(path); |
627 * A request body processor that takes data from an {@code Iterable} of byte arrays. |
706 SecurityManager sm = System.getSecurityManager(); |
628 * An {@link Iterable} is provided which supplies {@link Iterator} instances. |
707 if (sm != null) |
629 * Each attempt to send the request results in one invocation of the |
708 sm.checkRead(pathForSecurityCheck(path)); |
630 * {@code Iterable} |
709 if (Files.notExists(path)) |
|
710 throw new FileNotFoundException(path + " not found"); |
|
711 return new RequestPublishers.FilePublisher(path); |
|
712 } |
|
713 |
|
714 /** |
|
715 * A request body publisher that takes data from an {@code Iterable} |
|
716 * of byte arrays. An {@link Iterable} is provided which supplies |
|
717 * {@link Iterator} instances. Each attempt to send the request results |
|
718 * in one invocation of the {@code Iterable}. |
631 * |
719 * |
632 * @param iter an Iterable of byte arrays |
720 * @param iter an Iterable of byte arrays |
633 * @return a BodyProcessor |
721 * @return a BodyPublisher |
634 */ |
722 */ |
635 static BodyProcessor fromByteArrays(Iterable<byte[]> iter) { |
723 static BodyPublisher fromByteArrays(Iterable<byte[]> iter) { |
636 return new RequestProcessors.IterableProcessor(iter); |
724 return new RequestPublishers.IterablePublisher(iter); |
637 } |
725 } |
|
726 |
|
727 /** |
|
728 * A request body publisher which sends no request body. |
|
729 * |
|
730 * @return a BodyPublisher which completes immediately and sends |
|
731 * no request body. |
|
732 */ |
|
733 static BodyPublisher noBody() { |
|
734 return new RequestPublishers.EmptyPublisher(); |
|
735 } |
|
736 |
638 /** |
737 /** |
639 * Returns the content length for this request body. May be zero |
738 * Returns the content length for this request body. May be zero |
640 * if no request content being sent, greater than zero for a fixed |
739 * if no request body being sent, greater than zero for a fixed |
641 * length content, and less than zero for an unknown content length. |
740 * length content, or less than zero for an unknown content length. |
642 * |
741 * |
643 * @return the content length for this request body if known |
742 * This method may be invoked before the publisher is subscribed to. |
|
743 * This method may be invoked more than once by the HTTP client |
|
744 * implementation, and MUST return the same constant value each time. |
|
745 * |
|
746 * @return the content length for this request body, if known |
644 */ |
747 */ |
645 long contentLength(); |
748 long contentLength(); |
646 |
|
647 // /** |
|
648 // * Returns a used {@code ByteBuffer} to this request processor. When the |
|
649 // * HTTP implementation has finished sending the contents of a buffer, |
|
650 // * this method is called to return it to the processor for re-use. |
|
651 // * |
|
652 // * @param buffer a used ByteBuffer |
|
653 // */ |
|
654 //void returnBuffer(ByteBuffer buffer); |
|
655 } |
749 } |
656 } |
750 } |