Skip to main content
summaryrefslogtreecommitdiffstats
blob: e7e527eaf7e3acb67f94c2f1d63936dcf2712ea2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
//
//  ========================================================================
//  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.client.api;

import java.io.IOException;
import java.net.HttpCookie;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.util.EventListener;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.util.Fields;

/**
 * <p>{@link Request} represents a HTTP request, and offers a fluent interface to customize
 * various attributes such as the path, the headers, the content, etc.</p>
 * <p>You can create {@link Request} objects via {@link HttpClient#newRequest(String)} and
 * you can send them using either {@link #send()} for a blocking semantic, or
 * {@link #send(Response.CompleteListener)} for an asynchronous semantic.</p>
 *
 * @see Response
 */
public interface Request
{
    /**
     * @return the scheme of this request, such as "http" or "https"
     */
    String getScheme();

    /**
     * @param scheme the scheme of this request, such as "http" or "https"
     * @return this request object
     */
    Request scheme(String scheme);

    /**
     * @return the host of this request, such as "127.0.0.1" or "google.com"
     */
    String getHost();

    /**
     * @return the port of this request such as 80 or 443
     */
    int getPort();

    /**
     * @return the method of this request, such as GET or POST, as a String
     */
    String getMethod();

    /**
     * @param method the method of this request, such as GET or POST
     * @return this request object
     */
    Request method(HttpMethod method);

    /**
     * @param method the method of this request, such as GET or POST
     * @return this request object
     */
    Request method(String method);

    /**
     * @return the path of this request, such as "/" or "/path" - without the query
     * @see #getQuery()
     */
    String getPath();

    /**
     * Specifies the path - and possibly the query - of this request.
     * If the query part is specified, parameter values must be properly
     * {@link URLEncoder#encode(String, String) UTF-8 URL encoded}.
     * For example, if the value for parameter "currency" is the euro symbol &euro; then the
     * query string for this parameter must be "currency=%E2%82%AC".
     * For transparent encoding of parameter values, use {@link #param(String, String)}.
     *
     * @param path the path of this request, such as "/" or "/path?param=1"
     * @return this request object
     */
    Request path(String path);

    /**
     * @return the query string of this request such as "param=1"
     * @see #getPath()
     * @see #getParams()
     */
    String getQuery();

    /**
     * @return the full URI of this request such as "http://host:port/path?param=1"
     */
    URI getURI();

    /**
     * @return the HTTP version of this request, such as "HTTP/1.1"
     */
    HttpVersion getVersion();

    /**
     * @param version the HTTP version of this request, such as "HTTP/1.1"
     * @return this request object
     */
    Request version(HttpVersion version);

    /**
     * @return the query parameters of this request
     */
    Fields getParams();

    /**
     * Adds a query parameter with the given name and value.
     * The value is {@link URLEncoder#encode(String, String) UTF-8 URL encoded}.
     *
     * @param name the name of the query parameter
     * @param value the value of the query parameter
     * @return this request object
     */
    Request param(String name, String value);

    /**
     * @return the headers of this request
     */
    HttpFields getHeaders();

    /**
     * @param name the name of the header
     * @param value the value of the header
     * @return this request object
     * @see #header(HttpHeader, String)
     */
    Request header(String name, String value);

    /**
     * <p>Adds the given {@code value} to the specified {@code header}.</p>
     * <p>Multiple calls with the same parameters will add multiple values;
     * use the value {@code null} to remove the header completely.</p>
     *
     * @param header the header name
     * @param value the value of the header
     * @return this request object
     */
    Request header(HttpHeader header, String value);

    /**
     * @return the cookies associated with this request
     */
    List<HttpCookie> getCookies();

    /**
     * @param cookie a cookie for this request
     * @return this request object
     */
    Request cookie(HttpCookie cookie);

    /**
     * @param name the name of the attribute
     * @param value the value of the attribute
     * @return this request object
     */
    Request attribute(String name, Object value);

    /**
     * @return the attributes of this request
     */
    Map<String, Object> getAttributes();

    /**
     * @return the content provider of this request
     */
    ContentProvider getContent();

    /**
     * @param content the content provider of this request
     * @return this request object
     */
    Request content(ContentProvider content);

    /**
     * @param content the content provider of this request
     * @return this request object
     */
    Request content(ContentProvider content, String contentType);

    /**
     * Shortcut method to specify a file as a content for this request, with the default content type of
     * "application/octect-stream".
     *
     * @param file the file to upload
     * @return this request object
     * @throws IOException if the file does not exist or cannot be read
     */
    Request file(Path file) throws IOException;

    /**
     * Shortcut method to specify a file as a content for this request, with the given content type.
     *
     * @param file the file to upload
     * @param contentType the content type of the file
     * @return this request object
     * @throws IOException if the file does not exist or cannot be read
     */
    Request file(Path file, String contentType) throws IOException;

    /**
     * @return the user agent for this request
     */
    String getAgent();

    /**
     * @param agent the user agent for this request (corresponds to the {@code User-Agent} header)
     * @return this request object
     */
    Request agent(String agent);

    /**
     * @param accepts the media types that are acceptable in the response, such as
     *                "text/plain;q=0.5" or "text/html" (corresponds to the {@code Accept} header)
     * @return this request object
     */
    Request accept(String... accepts);

    /**
     * @return the idle timeout for this request, in milliseconds
     */
    long getIdleTimeout();

    /**
     * @param timeout the idle timeout for this request
     * @param unit the idle timeout unit
     * @return this request object
     */
    Request idleTimeout(long timeout, TimeUnit unit);

    /**
     * @return the total timeout for this request, in milliseconds
     */
    long getTimeout();

    /**
     * @param timeout the total timeout for the request/response conversation
     * @param unit the timeout unit
     * @return this request object
     */
    Request timeout(long timeout, TimeUnit unit);

    /**
     * @return whether this request follows redirects
     */
    boolean isFollowRedirects();

    /**
     * @param follow whether this request follows redirects
     * @return this request object
     */
    Request followRedirects(boolean follow);

    /**
     * @param listenerClass the class of the listener, or null for all listeners classes
     * @return the listeners for request events of the given class
     */
    <T extends RequestListener> List<T> getRequestListeners(Class<T> listenerClass);

    /**
     * @param listener a listener for request events
     * @return this request object
     */
    Request listener(Listener listener);

    /**
     * @param listener a listener for request queued event
     * @return this request object
     */
    Request onRequestQueued(QueuedListener listener);

    /**
     * @param listener a listener for request begin event
     * @return this request object
     */
    Request onRequestBegin(BeginListener listener);

    /**
     * @param listener a listener for request headers event
     * @return this request object
     */
    Request onRequestHeaders(HeadersListener listener);

    /**
     * @param listener a listener for request commit event
     * @return this request object
     */
    Request onRequestCommit(CommitListener listener);

    /**
     * @param listener a listener for request content events
     * @return this request object
     */
    Request onRequestContent(ContentListener listener);

    /**
     * @param listener a listener for request success event
     * @return this request object
     */
    Request onRequestSuccess(SuccessListener listener);

    /**
     * @param listener a listener for request failure event
     * @return this request object
     */
    Request onRequestFailure(FailureListener listener);

    /**
     * @param listener a listener for response begin event
     * @return this request object
     */
    Request onResponseBegin(Response.BeginListener listener);

    /**
     * @param listener a listener for response header event
     * @return this request object
     */
    Request onResponseHeader(Response.HeaderListener listener);

    /**
     * @param listener a listener for response headers event
     * @return this request object
     */
    Request onResponseHeaders(Response.HeadersListener listener);

    /**
     * @param listener a consuming listener for response content events
     * @return this request object
     */
    Request onResponseContent(Response.ContentListener listener);

    /**
     * @param listener an asynchronous listener for response content events
     * @return this request object
     */
    Request onResponseContentAsync(Response.AsyncContentListener listener);

    /**
     * @param listener a listener for response success event
     * @return this request object
     */
    Request onResponseSuccess(Response.SuccessListener listener);

    /**
     * @param listener a listener for response failure event
     * @return this request object
     */
    Request onResponseFailure(Response.FailureListener listener);

    /**
     * @param listener a listener for complete event
     * @return this request object
     */
    Request onComplete(Response.CompleteListener listener);

    /**
     * Sends this request and returns the response.
     * <p />
     * This method should be used when a simple blocking semantic is needed, and when it is known
     * that the response content can be buffered without exceeding memory constraints.
     * <p />
     * For example, this method is not appropriate to download big files from a server; consider using
     * {@link #send(Response.CompleteListener)} instead, passing your own {@link Response.Listener} or a utility
     * listener such as {@link InputStreamResponseListener}.
     * <p />
     * The method returns when the {@link Response.CompleteListener complete event} is fired.
     *
     * @return a {@link ContentResponse} for this request
     * @see Response.CompleteListener#onComplete(Result)
     */
    ContentResponse send() throws InterruptedException, TimeoutException, ExecutionException;

    /**
     * <p>Sends this request and asynchronously notifies the given listener for response events.</p>
     * <p>This method should be used when the application needs to be notified of the various response events
     * as they happen, or when the application needs to efficiently manage the response content.</p>
     * <p>The listener passed to this method may implement not only {@link Response.CompleteListener}
     * but also other response listener interfaces, and all the events implemented will be notified.
     * This allows application code to write a single listener class to handle all relevant events.</p>
     *
     * @param listener the listener that receives response events
     */
    void send(Response.CompleteListener listener);

    /**
     * Attempts to abort the send of this request.
     *
     * @param cause the abort cause, must not be null
     * @return whether the abort succeeded
     */
    boolean abort(Throwable cause);

    /**
     * @return the abort cause passed to {@link #abort(Throwable)},
     * or null if this request has not been aborted
     */
    Throwable getAbortCause();

    /**
     * Common, empty, super-interface for request listeners.
     */
    public interface RequestListener extends EventListener
    {
    }

    /**
     * Listener for the request queued event.
     */
    public interface QueuedListener extends RequestListener
    {
        /**
         * Callback method invoked when the request is queued, waiting to be sent
         *
         * @param request the request being queued
         */
        public void onQueued(Request request);
    }

    /**
     * Listener for the request begin event.
     */
    public interface BeginListener extends RequestListener
    {
        /**
         * Callback method invoked when the request begins being processed in order to be sent.
         * This is the last opportunity to modify the request.
         *
         * @param request the request that begins being processed
         */
        public void onBegin(Request request);
    }

    /**
     * Listener for the request headers event.
     */
    public interface HeadersListener extends RequestListener
    {
        /**
         * Callback method invoked when the request headers (and perhaps small content) are ready to be sent.
         * The request has been converted into bytes, but not yet sent to the server, and further modifications
         * to the request may have no effect.
         * @param request the request that is about to be committed
         */
        public void onHeaders(Request request);
    }

    /**
     * Listener for the request committed event.
     */
    public interface CommitListener extends RequestListener
    {
        /**
         * Callback method invoked when the request headers (and perhaps small content) have been sent.
         * The request is now committed, and in transit to the server, and further modifications to the
         * request may have no effect.
         * @param request the request that has been committed
         */
        public void onCommit(Request request);
    }

    /**
     * Listener for the request content event.
     */
    public interface ContentListener extends RequestListener
    {
        /**
         * Callback method invoked when a chunk of request content has been sent successfully.
         * Changes to bytes in the given buffer have no effect, as the content has already been sent.
         * @param request the request that has been committed
         */
        public void onContent(Request request, ByteBuffer content);
    }

    /**
     * Listener for the request succeeded event.
     */
    public interface SuccessListener extends RequestListener
    {
        /**
         * Callback method invoked when the request has been successfully sent.
         *
         * @param request the request sent
         */
        public void onSuccess(Request request);
    }

    /**
     * Listener for the request failed event.
     */
    public interface FailureListener extends RequestListener
    {
        /**
         * Callback method invoked when the request has failed to be sent
         * @param request the request that failed
         * @param failure the failure
         */
        public void onFailure(Request request, Throwable failure);
    }

    /**
     * Listener for all request events.
     */
    public interface Listener extends QueuedListener, BeginListener, HeadersListener, CommitListener, ContentListener, SuccessListener, FailureListener
    {
        /**
         * An empty implementation of {@link Listener}
         */
        public static class Adapter implements Listener
        {
            @Override
            public void onQueued(Request request)
            {
            }

            @Override
            public void onBegin(Request request)
            {
            }

            @Override
            public void onHeaders(Request request)
            {
            }

            @Override
            public void onCommit(Request request)
            {
            }

            @Override
            public void onContent(Request request, ByteBuffer content)
            {
            }

            @Override
            public void onSuccess(Request request)
            {
            }

            @Override
            public void onFailure(Request request, Throwable failure)
            {
            }
        }
    }
}

Back to the top