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