1 //
2 // ========================================================================
3 // Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
8 //
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
11 //
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
14 //
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
17 //
18
19 package org.eclipse.jetty.client.api;
20
21 import java.io.IOException;
22 import java.net.HttpCookie;
23 import java.net.URI;
24 import java.net.URLEncoder;
25 import java.nio.ByteBuffer;
26 import java.nio.file.Path;
27 import java.util.EventListener;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.concurrent.ExecutionException;
31 import java.util.concurrent.TimeUnit;
32 import java.util.concurrent.TimeoutException;
33
34 import org.eclipse.jetty.client.HttpClient;
35 import org.eclipse.jetty.client.util.InputStreamResponseListener;
36 import org.eclipse.jetty.http.HttpFields;
37 import org.eclipse.jetty.http.HttpHeader;
38 import org.eclipse.jetty.http.HttpMethod;
39 import org.eclipse.jetty.http.HttpVersion;
40 import org.eclipse.jetty.util.Fields;
41
42 /**
43 * <p>{@link Request} represents a HTTP request, and offers a fluent interface to customize
44 * various attributes such as the path, the headers, the content, etc.</p>
45 * <p>You can create {@link Request} objects via {@link HttpClient#newRequest(String)} and
46 * you can send them using either {@link #send()} for a blocking semantic, or
47 * {@link #send(Response.CompleteListener)} for an asynchronous semantic.</p>
48 *
49 * @see Response
50 */
51 public interface Request
52 {
53 /**
54 * @return the scheme of this request, such as "http" or "https"
55 */
56 String getScheme();
57
58 /**
59 * @param scheme the scheme of this request, such as "http" or "https"
60 * @return this request object
61 */
62 Request scheme(String scheme);
63
64 /**
65 * @return the host of this request, such as "127.0.0.1" or "google.com"
66 */
67 String getHost();
68
69 /**
70 * @return the port of this request such as 80 or 443
71 */
72 int getPort();
73
74 /**
75 * @return the method of this request, such as GET or POST, as a String
76 */
77 String getMethod();
78
79 /**
80 * @param method the method of this request, such as GET or POST
81 * @return this request object
82 */
83 Request method(HttpMethod method);
84
85 /**
86 * @param method the method of this request, such as GET or POST
87 * @return this request object
88 */
89 Request method(String method);
90
91 /**
92 * @return the path of this request, such as "/" or "/path" - without the query
93 * @see #getQuery()
94 */
95 String getPath();
96
97 /**
98 * Specifies the path - and possibly the query - of this request.
99 * If the query part is specified, parameter values must be properly
100 * {@link URLEncoder#encode(String, String) UTF-8 URL encoded}.
101 * For example, if the value for parameter "currency" is the euro symbol € then the
102 * query string for this parameter must be "currency=%E2%82%AC".
103 * For transparent encoding of parameter values, use {@link #param(String, String)}.
104 *
105 * @param path the path of this request, such as "/" or "/path?param=1"
106 * @return this request object
107 */
108 Request path(String path);
109
110 /**
111 * @return the query string of this request such as "param=1"
112 * @see #getPath()
113 * @see #getParams()
114 */
115 String getQuery();
116
117 /**
118 * @return the full URI of this request such as "http://host:port/path?param=1"
119 */
120 URI getURI();
121
122 /**
123 * @return the HTTP version of this request, such as "HTTP/1.1"
124 */
125 HttpVersion getVersion();
126
127 /**
128 * @param version the HTTP version of this request, such as "HTTP/1.1"
129 * @return this request object
130 */
131 Request version(HttpVersion version);
132
133 /**
134 * @return the query parameters of this request
135 */
136 Fields getParams();
137
138 /**
139 * Adds a query parameter with the given name and value.
140 * The value is {@link URLEncoder#encode(String, String) UTF-8 URL encoded}.
141 *
142 * @param name the name of the query parameter
143 * @param value the value of the query parameter
144 * @return this request object
145 */
146 Request param(String name, String value);
147
148 /**
149 * @return the headers of this request
150 */
151 HttpFields getHeaders();
152
153 /**
154 * @param name the name of the header
155 * @param value the value of the header
156 * @return this request object
157 * @see #header(HttpHeader, String)
158 */
159 Request header(String name, String value);
160
161 /**
162 * <p>Adds the given {@code value} to the specified {@code header}.</p>
163 * <p>Multiple calls with the same parameters will add multiple values;
164 * use the value {@code null} to remove the header completely.</p>
165 *
166 * @param header the header name
167 * @param value the value of the header
168 * @return this request object
169 */
170 Request header(HttpHeader header, String value);
171
172 /**
173 * @return the cookies associated with this request
174 */
175 List<HttpCookie> getCookies();
176
177 /**
178 * @param cookie a cookie for this request
179 * @return this request object
180 */
181 Request cookie(HttpCookie cookie);
182
183 /**
184 * @param name the name of the attribute
185 * @param value the value of the attribute
186 * @return this request object
187 */
188 Request attribute(String name, Object value);
189
190 /**
191 * @return the attributes of this request
192 */
193 Map<String, Object> getAttributes();
194
195 /**
196 * @return the content provider of this request
197 */
198 ContentProvider getContent();
199
200 /**
201 * @param content the content provider of this request
202 * @return this request object
203 */
204 Request content(ContentProvider content);
205
206 /**
207 * @param content the content provider of this request
208 * @param contentType the content type
209 * @return this request object
210 */
211 Request content(ContentProvider content, String contentType);
212
213 /**
214 * Shortcut method to specify a file as a content for this request, with the default content type of
215 * "application/octect-stream".
216 *
217 * @param file the file to upload
218 * @return this request object
219 * @throws IOException if the file does not exist or cannot be read
220 */
221 Request file(Path file) throws IOException;
222
223 /**
224 * Shortcut method to specify a file as a content for this request, with the given content type.
225 *
226 * @param file the file to upload
227 * @param contentType the content type of the file
228 * @return this request object
229 * @throws IOException if the file does not exist or cannot be read
230 */
231 Request file(Path file, String contentType) throws IOException;
232
233 /**
234 * @return the user agent for this request
235 */
236 String getAgent();
237
238 /**
239 * @param agent the user agent for this request (corresponds to the {@code User-Agent} header)
240 * @return this request object
241 */
242 Request agent(String agent);
243
244 /**
245 * @param accepts the media types that are acceptable in the response, such as
246 * "text/plain;q=0.5" or "text/html" (corresponds to the {@code Accept} header)
247 * @return this request object
248 */
249 Request accept(String... accepts);
250
251 /**
252 * @return the idle timeout for this request, in milliseconds
253 */
254 long getIdleTimeout();
255
256 /**
257 * @param timeout the idle timeout for this request
258 * @param unit the idle timeout unit
259 * @return this request object
260 */
261 Request idleTimeout(long timeout, TimeUnit unit);
262
263 /**
264 * @return the total timeout for this request, in milliseconds
265 */
266 long getTimeout();
267
268 /**
269 * @param timeout the total timeout for the request/response conversation
270 * @param unit the timeout unit
271 * @return this request object
272 */
273 Request timeout(long timeout, TimeUnit unit);
274
275 /**
276 * @return whether this request follows redirects
277 */
278 boolean isFollowRedirects();
279
280 /**
281 * @param follow whether this request follows redirects
282 * @return this request object
283 */
284 Request followRedirects(boolean follow);
285
286 /**
287 * @param listenerClass the class of the listener, or null for all listeners classes
288 * @return the listeners for request events of the given class
289 * @param <T> the type of listener class
290 */
291 <T extends RequestListener> List<T> getRequestListeners(Class<T> listenerClass);
292
293 /**
294 * @param listener a listener for request events
295 * @return this request object
296 */
297 Request listener(Listener listener);
298
299 /**
300 * @param listener a listener for request queued event
301 * @return this request object
302 */
303 Request onRequestQueued(QueuedListener listener);
304
305 /**
306 * @param listener a listener for request begin event
307 * @return this request object
308 */
309 Request onRequestBegin(BeginListener listener);
310
311 /**
312 * @param listener a listener for request headers event
313 * @return this request object
314 */
315 Request onRequestHeaders(HeadersListener listener);
316
317 /**
318 * @param listener a listener for request commit event
319 * @return this request object
320 */
321 Request onRequestCommit(CommitListener listener);
322
323 /**
324 * @param listener a listener for request content events
325 * @return this request object
326 */
327 Request onRequestContent(ContentListener listener);
328
329 /**
330 * @param listener a listener for request success event
331 * @return this request object
332 */
333 Request onRequestSuccess(SuccessListener listener);
334
335 /**
336 * @param listener a listener for request failure event
337 * @return this request object
338 */
339 Request onRequestFailure(FailureListener listener);
340
341 /**
342 * @param listener a listener for response begin event
343 * @return this request object
344 */
345 Request onResponseBegin(Response.BeginListener listener);
346
347 /**
348 * @param listener a listener for response header event
349 * @return this request object
350 */
351 Request onResponseHeader(Response.HeaderListener listener);
352
353 /**
354 * @param listener a listener for response headers event
355 * @return this request object
356 */
357 Request onResponseHeaders(Response.HeadersListener listener);
358
359 /**
360 * @param listener a consuming listener for response content events
361 * @return this request object
362 */
363 Request onResponseContent(Response.ContentListener listener);
364
365 /**
366 * @param listener an asynchronous listener for response content events
367 * @return this request object
368 */
369 Request onResponseContentAsync(Response.AsyncContentListener listener);
370
371 /**
372 * @param listener a listener for response success event
373 * @return this request object
374 */
375 Request onResponseSuccess(Response.SuccessListener listener);
376
377 /**
378 * @param listener a listener for response failure event
379 * @return this request object
380 */
381 Request onResponseFailure(Response.FailureListener listener);
382
383 /**
384 * @param listener a listener for complete event
385 * @return this request object
386 */
387 Request onComplete(Response.CompleteListener listener);
388
389 /**
390 * Sends this request and returns the response.
391 * <p>
392 * This method should be used when a simple blocking semantic is needed, and when it is known
393 * that the response content can be buffered without exceeding memory constraints.
394 * <p>
395 * For example, this method is not appropriate to download big files from a server; consider using
396 * {@link #send(Response.CompleteListener)} instead, passing your own {@link Response.Listener} or a utility
397 * listener such as {@link InputStreamResponseListener}.
398 * <p>
399 * The method returns when the {@link Response.CompleteListener complete event} is fired.
400 *
401 * @return a {@link ContentResponse} for this request
402 * @throws InterruptedException if send thread is interrupted
403 * @throws TimeoutException if send times out
404 * @throws ExecutionException if execution fails
405 * @see Response.CompleteListener#onComplete(Result)
406 */
407 ContentResponse send() throws InterruptedException, TimeoutException, ExecutionException;
408
409 /**
410 * <p>Sends this request and asynchronously notifies the given listener for response events.</p>
411 * <p>This method should be used when the application needs to be notified of the various response events
412 * as they happen, or when the application needs to efficiently manage the response content.</p>
413 * <p>The listener passed to this method may implement not only {@link Response.CompleteListener}
414 * but also other response listener interfaces, and all the events implemented will be notified.
415 * This allows application code to write a single listener class to handle all relevant events.</p>
416 *
417 * @param listener the listener that receives response events
418 */
419 void send(Response.CompleteListener listener);
420
421 /**
422 * Attempts to abort the send of this request.
423 *
424 * @param cause the abort cause, must not be null
425 * @return whether the abort succeeded
426 */
427 boolean abort(Throwable cause);
428
429 /**
430 * @return the abort cause passed to {@link #abort(Throwable)},
431 * or null if this request has not been aborted
432 */
433 Throwable getAbortCause();
434
435 /**
436 * Common, empty, super-interface for request listeners.
437 */
438 public interface RequestListener extends EventListener
439 {
440 }
441
442 /**
443 * Listener for the request queued event.
444 */
445 public interface QueuedListener extends RequestListener
446 {
447 /**
448 * Callback method invoked when the request is queued, waiting to be sent
449 *
450 * @param request the request being queued
451 */
452 public void onQueued(Request request);
453 }
454
455 /**
456 * Listener for the request begin event.
457 */
458 public interface BeginListener extends RequestListener
459 {
460 /**
461 * Callback method invoked when the request begins being processed in order to be sent.
462 * This is the last opportunity to modify the request.
463 *
464 * @param request the request that begins being processed
465 */
466 public void onBegin(Request request);
467 }
468
469 /**
470 * Listener for the request headers event.
471 */
472 public interface HeadersListener extends RequestListener
473 {
474 /**
475 * Callback method invoked when the request headers (and perhaps small content) are ready to be sent.
476 * The request has been converted into bytes, but not yet sent to the server, and further modifications
477 * to the request may have no effect.
478 * @param request the request that is about to be committed
479 */
480 public void onHeaders(Request request);
481 }
482
483 /**
484 * Listener for the request committed event.
485 */
486 public interface CommitListener extends RequestListener
487 {
488 /**
489 * Callback method invoked when the request headers (and perhaps small content) have been sent.
490 * The request is now committed, and in transit to the server, and further modifications to the
491 * request may have no effect.
492 * @param request the request that has been committed
493 */
494 public void onCommit(Request request);
495 }
496
497 /**
498 * Listener for the request content event.
499 */
500 public interface ContentListener extends RequestListener
501 {
502 /**
503 * Callback method invoked when a chunk of request content has been sent successfully.
504 * Changes to bytes in the given buffer have no effect, as the content has already been sent.
505 * @param request the request that has been committed
506 * @param content the content
507 */
508 public void onContent(Request request, ByteBuffer content);
509 }
510
511 /**
512 * Listener for the request succeeded event.
513 */
514 public interface SuccessListener extends RequestListener
515 {
516 /**
517 * Callback method invoked when the request has been successfully sent.
518 *
519 * @param request the request sent
520 */
521 public void onSuccess(Request request);
522 }
523
524 /**
525 * Listener for the request failed event.
526 */
527 public interface FailureListener extends RequestListener
528 {
529 /**
530 * Callback method invoked when the request has failed to be sent
531 * @param request the request that failed
532 * @param failure the failure
533 */
534 public void onFailure(Request request, Throwable failure);
535 }
536
537 /**
538 * Listener for all request events.
539 */
540 public interface Listener extends QueuedListener, BeginListener, HeadersListener, CommitListener, ContentListener, SuccessListener, FailureListener
541 {
542 /**
543 * An empty implementation of {@link Listener}
544 */
545 public static class Adapter implements Listener
546 {
547 @Override
548 public void onQueued(Request request)
549 {
550 }
551
552 @Override
553 public void onBegin(Request request)
554 {
555 }
556
557 @Override
558 public void onHeaders(Request request)
559 {
560 }
561
562 @Override
563 public void onCommit(Request request)
564 {
565 }
566
567 @Override
568 public void onContent(Request request, ByteBuffer content)
569 {
570 }
571
572 @Override
573 public void onSuccess(Request request)
574 {
575 }
576
577 @Override
578 public void onFailure(Request request, Throwable failure)
579 {
580 }
581 }
582 }
583 }