-
Notifications
You must be signed in to change notification settings - Fork 2k
/
package-info.java
1098 lines (1095 loc) · 42.4 KB
/
package-info.java
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
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright 2014 Red Hat, Inc.
*
* 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.
*/
/**
* == Writing HTTP servers and clients
*
* Vert.x allows you to easily write non blocking HTTP clients and servers.
*
* === Creating an HTTP Server
*
* The simplest way to create an HTTP server, using all default options is as follows:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example1}
* ----
*
* === Configuring an HTTP server
*
* If you don't want the default, a server can be configured by passing in a {@link io.vertx.core.http.HttpServerOptions}
* instance when creating it:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example2}
* ----
*
* === Start the Server Listening
*
* To tell the server to listen for incoming requests you use one of the {@link io.vertx.core.http.HttpServer#listen}
* alternatives.
*
* To tell the server to listen at the host and port as specified in the options:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example3}
* ----
*
* Or to specify the host and port in the call to listen, ignoring what is configured in the options:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example4}
* ----
*
* The default host is `0.0.0.0` which means 'listen on all available addresses' and the default port is `80`.
*
* The actual bind is asynchronous so the server might not actually be listening until some time *after* the call to
* listen has returned.
*
* If you want to be notified when the server is actually listening you can provide a handler to the `listen` call.
* For example:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example5}
* ----
*
* === Getting notified of incoming requests
*
* To be notified when a request arrives you need to set a {@link io.vertx.core.http.HttpServer#requestHandler}:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example6}
* ----
*
* === Handling requests
*
* When a request arrives, the request handler is called passing in an instance of {@link io.vertx.core.http.HttpServerRequest}.
* This object represents the server side HTTP request.
*
* The handler is called when the headers of the request have been fully read.
*
* If the request contains a body, that body will arrive at the server some time after the request handler has been called.
*
* The server request object allows you to retrieve the {@link io.vertx.core.http.HttpServerRequest#uri},
* {@link io.vertx.core.http.HttpServerRequest#path}, {@link io.vertx.core.http.HttpServerRequest#params} and
* {@link io.vertx.core.http.HttpServerRequest#headers}, amongst other things.
*
* Each server request object is associated with one server response object. You use
* {@link io.vertx.core.http.HttpServerRequest#response} to get a reference to the {@link io.vertx.core.http.HttpServerResponse}
* object.
*
* Here's a simple example of a server handling a request and replying with "hello world" to it.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example7_1}
* ----
*
* ==== Request version
*
* The version of HTTP specified in the request can be retrieved with {@link io.vertx.core.http.HttpServerRequest#version}
*
* ==== Request method
*
* Use {@link io.vertx.core.http.HttpServerRequest#method} to retrieve the HTTP method of the request.
* (i.e. whether it's GET, POST, PUT, DELETE, HEAD, OPTIONS, etc).
*
* ==== Request URI
*
* Use {@link io.vertx.core.http.HttpServerRequest#uri} to retrieve the URI of the request.
*
* Note that this is the actual URI as passed in the HTTP request, and it's almost always a relative URI.
*
* The URI is as defined in http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html[Section 5.1.2 of the HTTP specification - Request-URI]
*
* ==== Request path
*
* Use {@link io.vertx.core.http.HttpServerRequest#path} to return the path part of the URI
*
* For example, if the request URI was:
*
* a/b/c/page.html?param1=abc¶m2=xyz
*
* Then the path would be
*
* /a/b/c/page.html
*
* ==== Request query
*
* Use {@link io.vertx.core.http.HttpServerRequest#query} to return the query part of the URI
*
* For example, if the request URI was:
*
* a/b/c/page.html?param1=abc¶m2=xyz
*
* Then the query would be
*
* param1=abc¶m2=xyz
*
* ==== Request headers
*
* Use {@link io.vertx.core.http.HttpServerRequest#headers} to return the headers of the HTTP request.
*
* This returns an instance of {@link io.vertx.core.MultiMap} - which is like a normal Map or Hash but allows multiple
* values for the same key - this is because HTTP allows multiple header values with the same key.
*
* It also has case-insensitive keys, that means you can do the following:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example8}
* ----
*
* ==== Request parameters
*
* Use {@link io.vertx.core.http.HttpServerRequest#params} to return the parameters of the HTTP request.
*
* Just like {@link io.vertx.core.http.HttpServerRequest#headers} this returns an instance of {@link io.vertx.core.MultiMap}
* as there can be more than one parameter with the same name.
*
* Request parameters are sent on the request URI, after the path. For example if the URI was:
*
* /page.html?param1=abc¶m2=xyz
*
* Then the parameters would contain the following:
*
* ----
* param1: 'abc'
* param2: 'xyz
* ----
*
* Note that these request parameters are retrieved from the URL of the request. If you have form attributes that
* have been sent as part of the submission of an HTML form submitted in the body of a `multi-part/form-data` request
* then they will not appear in the params here.
*
* ==== Remote address
*
* The address of the sender of the request can be retrieved with {@link io.vertx.core.http.HttpServerRequest#remoteAddress}.
*
* ==== Absolute URI
*
* The URI passed in an HTTP request is usually relative. If you wish to retrieve the absolute URI corresponding
* to the request, you can get it with {@link io.vertx.core.http.HttpServerRequest#absoluteURI}
*
* ==== End handler
*
* The {@link io.vertx.core.http.HttpServerRequest#endHandler} of the request is invoked when the entire request,
* including any body has been fully read.
*
* ==== Reading Data from the Request Body
*
* Often an HTTP request contains a body that we want to read. As previously mentioned the request handler is called
* when just the headers of the request have arrived so the request object does not have a body at that point.
*
* This is because the body may be very large (e.g. a file upload) and we don't generally want to buffer the entire
* body in memory before handing it to you, as that could cause the server to exhaust available memory.
*
* To receive the body, you can use the {@link io.vertx.core.http.HttpServerRequest#handler} on the request,
* this will get called every time a chunk of the request body arrives. Here's an example:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example9}
* ----
*
* The object passed into the handler is a {@link io.vertx.core.buffer.Buffer}, and the handler can be called
* multiple times as data arrives from the network, depending on the size of the body.
*
* In some cases (e.g. if the body is small) you will want to aggregate the entire body in memory, so you could do
* the aggregation yourself as follows:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example10}
* ----
*
* This is such a common case, that Vert.x provides a {@link io.vertx.core.http.HttpServerRequest#bodyHandler} to do this
* for you. The body handler is called once when all the body has been received:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example11}
* ----
*
* ==== Pumping requests
*
* The request object is a {@link io.vertx.core.streams.ReadStream} so you can pump the request body to any
* {@link io.vertx.core.streams.WriteStream} instance.
*
* See the chapter on <<streams, streams and pumps>> for a detailed explanation.
*
* ==== Handling HTML forms
*
* HTML forms can be submitted with either a content type of `application/x-www-form-urlencoded` or `multipart/form-data`.
*
* For url encoded forms, the form attributes are encoded in the url, just like normal query parameters.
*
* For multi-part forms they are encoded in the request body, and as such are not available until the entire body
* has been read from the wire.
*
* Multi-part forms can also contain file uploads.
*
* If you want to retrieve the attributes of a multi-part form you should tell Vert.x that you expect to receive
* such a form *before* any of the body is read by calling {@link io.vertx.core.http.HttpServerRequest#setExpectMultipart}
* with true, and then you should retrieve the actual attributes using {@link io.vertx.core.http.HttpServerRequest#formAttributes}
* once the entire body has been read:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example12}
* ----
*
* ==== Handling form file uploads
*
* Vert.x can also handle file uploads which are encoded in a multi-part request body.
*
* To receive file uploads you tell Vert.x to expect a multi-part form and set an
* {@link io.vertx.core.http.HttpServerRequest#uploadHandler} on the request.
*
* This handler will be called once for every
* upload that arrives on the server.
*
* The object passed into the handler is a {@link io.vertx.core.http.HttpServerFileUpload} instance.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example13}
* ----
*
* File uploads can be large we don't provide the entire upload in a single buffer as that might result in memory
* exhaustion, instead, the upload data is received in chunks:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example14}
* ----
*
* The upload object is a {@link io.vertx.core.streams.ReadStream} so you can pump the request body to any
* {@link io.vertx.core.streams.WriteStream} instance. See the chapter on <<streams, streams and pumps>> for a
* detailed explanation.
*
* If you just want to upload the file to disk somewhere you can use {@link io.vertx.core.http.HttpServerFileUpload#streamToFileSystem}:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example15}
* ----
*
* WARNING: Make sure you check the filename in a production system to avoid malicious clients uploading files
* to arbitrary places on your filesystem. See <<Security notes, security notes>> for more information.
*
* === Sending back responses
*
* The server response object is an instance of {@link io.vertx.core.http.HttpServerResponse} and is obtained from the
* request with {@link io.vertx.core.http.HttpServerRequest#response}.
*
* You use the response object to write a response back to the HTTP client.
*
* ==== Setting status code and message
*
* The default HTTP status code for a response is `200`, representing `OK`.
*
* Use {@link io.vertx.core.http.HttpServerResponse#setStatusCode} to set a different code.
*
* You can also specify a custom status message with {@link io.vertx.core.http.HttpServerResponse#setStatusMessage}.
*
* If you don't specify a status message, the default one corresponding to the status code will be used.
*
* ==== Writing HTTP responses
*
* To write data to an HTTP response, you use one the {@link io.vertx.core.http.HttpServerResponse#write} operations.
*
* These can be invoked multiple times before the response is ended. They can be invoked in a few ways:
*
* With a single buffer:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example16}
* ----
*
* With a string. In this case the string will encoded using UTF-8 and the result written to the wire.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example17}
* ----
*
* With a string and an encoding. In this case the string will encoded using the specified encoding and the
* result written to the wire.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example18}
* ----
*
* Writing to a response is asynchronous and always returns immediately after the write has been queued.
*
* If you are just writing a single string or buffer to the HTTP response you can write it and end the response in a
* single call to the {@link io.vertx.core.http.HttpServerResponse#end(String)}
*
* The first call to write results in the response header being being written to the response. Consequently, if you are
* not using HTTP chunking then you must set the `Content-Length` header before writing to the response, since it will
* be too late otherwise. If you are using HTTP chunking you do not have to worry.
*
* ==== Ending HTTP responses
*
* Once you have finished with the HTTP response you should {@link io.vertx.core.http.HttpServerResponse#end} it.
*
* This can be done in several ways:
*
* With no arguments, the response is simply ended.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example19}
* ----
*
* It can also be called with a string or buffer in the same way `write` is called. In this case it's just the same as
* calling write with a string or buffer followed by calling end with no arguments. For example:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example20}
* ----
*
* ==== Closing the underlying connection
*
* You can close the underlying TCP connection with {@link io.vertx.core.http.HttpServerResponse#close}.
*
* Non keep-alive connections will be automatically closed by Vert.x when the response is ended.
*
* Keep-alive connections are not automatically closed by Vert.x by default. If you want keep-alive connections to be
* closed after an idle time, then you configure {@link io.vertx.core.http.HttpServerOptions#setIdleTimeout}.
*
* ==== Setting response headers
*
* HTTP response headers can be added to the response by adding them directly to the
* {@link io.vertx.core.http.HttpServerResponse#headers}:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example21}
* ----
*
* Or you can use {@link io.vertx.core.http.HttpServerResponse#putHeader}
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example22}
* ----
*
* Headers must all be added before any parts of the response body are written.
*
* ==== Chunked HTTP responses and trailers
*
* Vert.x supports http://en.wikipedia.org/wiki/Chunked_transfer_encoding[HTTP Chunked Transfer Encoding].
*
* This allows the HTTP response body to be written in chunks, and is normally used when a large response body is
* being streamed to a client and the total size is not known in advance.
*
* You put the HTTP response into chunked mode as follows:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example23}
* ----
*
* Default is non-chunked. When in chunked mode, each call to one of the {@link io.vertx.core.http.HttpServerResponse#write}
* methods will result in a new HTTP chunk being written out.
*
* When in chunked mode you can also write HTTP response trailers to the response. These are actually written in
* the final chunk of the response.
*
* To add trailers to the response, add them directly to the {@link io.vertx.core.http.HttpServerResponse#trailers}.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example24}
* ----
*
* Or use {@link io.vertx.core.http.HttpServerResponse#putTrailer}.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example25}
* ----
*
* ==== Serving files directly from disk
*
* If you were writing a web server, one way to serve a file from disk would be to open it as an {@link io.vertx.core.file.AsyncFile}
* and pump it to the HTTP response.
*
* Or you could load it it one go using {@link io.vertx.core.file.FileSystem#readFile} and write it straight to the response.
*
* Alternatively, Vert.x provides a method which allows you to serve a file from disk to an HTTP response in one operation.
* Where supported by the underlying operating system this may result in the OS directly transferring bytes from the
* file to the socket without being copied through user-space at all.
*
* This is done by using {@link io.vertx.core.http.HttpServerResponse#sendFile}, and is usually more efficient for large
* files, but may be slower for small files.
*
* Here's a very simple web server that serves files from the file system using sendFile:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example26}
* ----
*
* Sending a file is asynchronous and may not complete until some time after the call has returned. If you want to
* be notified when the file has been writen you can use {@link io.vertx.core.http.HttpServerResponse#sendFile(String, io.vertx.core.Handler)}
*
* NOTE: If you use `sendFile` while using HTTPS it will copy through user-space, since if the kernel is copying data
* directly from disk to socket it doesn't give us an opportunity to apply any encryption.
*
* WARNING: If you're going to write web servers directly using Vert.x be careful that users cannot exploit the
* path to access files outside the directory from which you want to serve them. It may be safer instead to use
* Vert.x Web.
*
* ==== Pumping responses
*
* The server response is a {@link io.vertx.core.streams.WriteStream} instance so you can pump to it from any
* {@link io.vertx.core.streams.ReadStream}, e.g. {@link io.vertx.core.file.AsyncFile}, {@link io.vertx.core.net.NetSocket},
* {@link io.vertx.core.http.WebSocket} or {@link io.vertx.core.http.HttpServerRequest}.
*
* Here's an example which echoes the request body back in the response for any PUT methods.
* It uses a pump for the body, so it will work even if the HTTP request body is much larger than can fit in memory
* at any one time:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example27}
* ----
*
* === HTTP Compression
*
* Vert.x comes with support for HTTP Compression out of the box.
*
* This means you are able to automatically compress the body of the responses before they are sent back to the client.
*
* If the client does not support HTTP compression the responses are sent back without compressing the body.
*
* This allows to handle Client that support HTTP Compression and those that not support it at the same time.
*
* To enable compression use can configure it with {@link io.vertx.core.http.HttpServerOptions#setCompressionSupported}.
*
* By default compression is not enabled.
*
* When HTTP compression is enabled the server will check if the client incldes an `Accept-Encoding` header which
* includes the supported compressions. Commonly used are deflate and gzip. Both are supported by Vert.x.
*
* If such a header is found the server will automatically compress the body of the response with one of the supported
* compressions and send it back to the client.
*
* Be aware that compression may be able to reduce network traffic but is more CPU-intensive.
*
* === Creating an HTTP client
*
* You create an {@link io.vertx.core.http.HttpClient} instance with default options as follows:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example28}
* ----
*
* If you want to configure options for the client, you create it as follows:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example29}
* ----
*
* === Making requests
*
* The http client is very flexible and there are various ways you can make requests with it.
*
*
* Often you want to make many requests to the same host/port with an http client. To avoid you repeating the host/port
* every time you make a request you can configure the client with a default host/port:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example30}
* ----
*
* Alternatively if you find yourself making lots of requests to different host/ports with the same client you can
* simply specify the host/port when doing the request.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example31}
* ----
*
* Both methods of specifying host/port are supported for all the different ways of making requests with the client.
*
* ==== Simple requests with no request body
*
* Often, you'll want to make HTTP requests with no request body. This is usually the case with HTTP GET, OPTIONS and
* HEAD requests.
*
* The simplest way to do this with the Vert.x http client is using the methods prefixed with `Now`. For example
* {@link io.vertx.core.http.HttpClient#getNow}.
*
* These methods create the http request and send it in a single method call and allow you to provide a handler that will be
* called with the http response when it comes back.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example32}
* ----
*
* ==== Writing general requests
*
* At other times you don't know the request method you want to send until run-time. For that use case we provide
* general purpose request methods such as {@link io.vertx.core.http.HttpClient#request} which allow you to specify
* the HTTP method at run-time:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example33}
* ----
*
* ==== Writing request bodies
*
* Sometimes you'll want to write requests which have a body, or perhaps you want to write headers to a request
* before sending it.
*
* To do this you can call one of the specific request methods such as {@link io.vertx.core.http.HttpClient#post} or
* one of the general purpose request methods such as {@link io.vertx.core.http.HttpClient#request}.
*
* These methods don't send the request immediately, but instead return an instance of {@link io.vertx.core.http.HttpClientRequest}
* which can be used to write to the request body or write headers.
*
* Here are some examples of writing a POST request with a body:
*m
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example34}
* ----
*
* Methods exist to write strings in UTF-8 encoding and in any specific encoding and to write buffers:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example35}
* ----
*
* If you are just writing a single string or buffer to the HTTP request you can write it and end the request in a
* single call to the `end` function.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example36}
* ----
*
* When you're writing to a request, the first call to `write` will result in the request headers being written
* out to the wire.
*
* The actual write is asynchronous and might not occur until some time after the call has returned.
*
* Non-chunked HTTP requests with a request body require a `Content-Length` header to be provided.
*
* Consequently, if you are not using chunked HTTP then you must set the `Content-Length` header before writing
* to the request, as it will be too late otherwise.
*
* If you are calling one of the `end` methods that take a string or buffer then Vert.x will automatically calculate
* and set the `Content-Length` header before writing the request body.
*
* If you are using HTTP chunking a a `Content-Length` header is not required, so you do not have to calculate the size
* up-front.
*
* ==== Writing request headers
*
* You can write headers to a request using the {@link io.vertx.core.http.HttpClientRequest#headers()} multi-map as follows:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example37}
* ----
*
* The headers are an instance of {@link io.vertx.core.MultiMap} which provides operations for adding, setting and removing
* entries. Http headers allow more than one value for a specific key.
*
* You can also write headers using {@link io.vertx.core.http.HttpClientRequest#putHeader}
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example38}
* ----
*
* If you wish to write headers to the request you must do so before any part of the request body is written.
*
* ==== Ending HTTP requests
*
* Once you have finished with the HTTP request you must end it with one of the {@link io.vertx.core.http.HttpClientRequest#end}
* operations.
*
* Ending a request causes any headers to be written, if they have not already been written and the request to be marked
* as complete.
*
* Requests can be ended in several ways. With no arguments the request is simply ended:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example39}
* ----
*
* Or a string or buffer can be provided in the call to `end`. This is like calling `write` with the string or buffer
* before calling `end` with no arguments
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example40}
* ----
*
* ==== Chunked HTTP requests
*
* Vert.x supports http://en.wikipedia.org/wiki/Chunked_transfer_encoding[HTTP Chunked Transfer Encoding] for requests.
*
* This allows the HTTP request body to be written in chunks, and is normally used when a large request body is being streamed
* to the server, whose size is not known in advance.
*
* You put the HTTP request into chunked mode using {@link io.vertx.core.http.HttpClientRequest#setChunked(boolean)}.
*
* In chunked mode each call to write will cause a new chunk to be written to the wire. In chunked mode there is
* no need to set the `Content-Length` of the request up-front.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example41}
* ----
*
* ==== Request timeouts
*
* You can set a timeout for a specific http request using {@link io.vertx.core.http.HttpClientRequest#setTimeout(long)}.
*
* If the request does not return any data within the timeout period an exception will be passed to the exception handler
* (if provided) and the request will be closed.
*
* ==== Handling exceptions
*
* You can handle exceptions corresponding to a request by setting an exception handler on the
* {@link io.vertx.core.http.HttpClientRequest} instance:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example42}
* ----
*
* This does not handle non _2xx_ response that need to be handled in the
* {@link io.vertx.core.http.HttpClientResponse} code:
*
* [source, $lang]
* ----
* {@link examples.HTTPExamples#statusCodeHandling}
* ----
*
* IMPORTANT: `XXXNow` methods cannot receive an exception handler.
*
* ==== Specifying a handler on the client request
*
* Instead of providing a response handler in the call to create the client request object, alternatively, you can
* not provide a handler when the request is created and set it later on the request object itself, using
* {@link io.vertx.core.http.HttpClientRequest#handler(io.vertx.core.Handler)}, for example:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example43}
* ----
*
* ==== Using the request as a stream
*
* The {@link io.vertx.core.http.HttpClientRequest} instance is also a {@link io.vertx.core.streams.WriteStream} which means
* you can pump to it from any {@link io.vertx.core.streams.ReadStream} instance.
*
* For, example, you could pump a file on disk to a http request body as follows:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example44}
* ----
*
* === Handling http responses
*
* You receive an instance of {@link io.vertx.core.http.HttpClientResponse} into the handler that you specify in of
* the request methods or by setting a handler directly on the {@link io.vertx.core.http.HttpClientRequest} object.
*
* You can query the status code and the status message of the response with {@link io.vertx.core.http.HttpClientResponse#statusCode}
* and {@link io.vertx.core.http.HttpClientResponse#statusMessage}.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example45}
* ----
*
* ==== Using the response as a stream
*
* The {@link io.vertx.core.http.HttpClientResponse} instance is also a {@link io.vertx.core.streams.ReadStream} which means
* you can pump it to any {@link io.vertx.core.streams.WriteStream} instance.
*
* ==== Response headers and trailers
*
* Http responses can contain headers. Use {@link io.vertx.core.http.HttpClientResponse#headers} to get the headers.
*
* The object returned is a {@link io.vertx.core.MultiMap} as HTTP headers can contain multiple values for single keys.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example46}
* ----
*
* Chunked HTTP responses can also contain trailers - these are sent in the last chunk of the response body.
*
* You use {@link io.vertx.core.http.HttpClientResponse#trailers} to get the trailers. Trailers are also a {@link io.vertx.core.MultiMap}.
*
* ==== Reading the request body
*
* The response handler is called when the headers of the response have been read from the wire.
*
* If the response has a body this might arrive in several pieces some time after the headers have been read. We
* don't wait for all the body to arrive before calling the response handler as the response could be very large and we
* might be waiting a long time, or run out of memory for large responses.
*
* As parts of the response body arrive, the {@link io.vertx.core.http.HttpClientResponse#handler} is called with
* a {@link io.vertx.core.buffer.Buffer} representing the piece of the body:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example47}
* ----
*
* If you know the response body is not very large and want to aggregate it all in memory before handling it, you can
* either aggregate it yourself:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example48}
* ----
*
* Or you can use the convenience {@link io.vertx.core.http.HttpClientResponse#bodyHandler(io.vertx.core.Handler)} which
* is called with the entire body when the response has been fully read:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example49}
* ----
*
* ==== Response end handler
*
* The response {@link io.vertx.core.http.HttpClientResponse#endHandler} is called when the entire response body has been read
* or immediately after the headers have been read and the response handler has been called if there is no body.
*
* ==== Reading cookies from the response
*
* You can retrieve the list of cookies from a response using {@link io.vertx.core.http.HttpClientResponse#cookies()}.
*
* Alternatively you can just parse the `Set-Cookie` headers yourself in the response.
*
*
* ==== 100-Continue handling
*
* According to the http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html[HTTP 1.1 specification] a client can set a
* header `Expect: 100-Continue` and send the request header before sending the rest of the request body.
*
* The server can then respond with an interim response status `Status: 100 (Continue)` to signify to the client that
* it is ok to send the rest of the body.
*
* The idea here is it allows the server to authorise and accept/reject the request before large amounts of data are sent.
* Sending large amounts of data if the request might not be accepted is a waste of bandwidth and ties up the server
* in reading data that it will just discard.
*
* Vert.x allows you to set a {@link io.vertx.core.http.HttpClientRequest#continueHandler(io.vertx.core.Handler)} on the
* client request object
*
* This will be called if the server sends back a `Status: 100 (Continue)` response to signify that it is ok to send
* the rest of the request.
*
* This is used in conjunction with {@link io.vertx.core.http.HttpClientRequest#sendHead()}to send the head of the request.
*
* Here's an example:
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example50}
* ----
*
* On the server side a Vert.x http server can be configured to automatically send back 100 Continue interim responses
* when it receives an `Expect: 100-Continue` header.
* This is done by setting the option {@link io.vertx.core.http.HttpServerOptions#setHandle100ContinueAutomatically(boolean)}.
*
* If you'd prefer to decide whether to send back continue responses manually, then this property should be set to
* `false` (the default), then you can inspect the headers and call {@link io.vertx.core.http.HttpServerResponse#writeContinue()}
* if you wish the client to continue sending the body or you can reject the request by sending back a failure status code
* if you don't want it to send the body. For example:
*
*
*
* === Enabling compression on the client
*
* The http client comes with support for HTTP Compression out of the box.
*
* This means the client can let the remote http server know that it supports compression, and will be able to handle
* compressed response bodies.
*
* An http server is free to either compress with one of the supported compression algorithms or to send the body back
* without compressing it at all. So this is only a hint for the Http server which it may ignore at will.
*
* To tell the http server which compression is supported by the client it will include an `Accept-Encoding` header with
* the supported compression algorithm as value. Multiple compression algorithms are supported. In case of Vert.x this
* will result in the following header added:
*
* Accept-Encoding: gzip, deflate
*
* The server will choose then from one of these. You can detect if a server ompressed the body by checking for the
* `Content-Encoding` header in the response sent back from it.
*
* If the body of the response was compressed via gzip it will include for example the following header:
*
* Content-Encoding: gzip
*
* To enable compression set {@link io.vertx.core.http.HttpClientOptions#setTryUseCompression(boolean)} on the options
* used when creating the client.
*
* By default compression is disabled.
*
* === Pooling and keep alive
*
* Http keep alive allows http connections to be used for more than one request. This can be a more efficient use of
* connections when you're making multiple requests to the same server.
*
* The http client supports pooling of connections, allowing you to reuse connections between requests.
*
* For pooling to work, keep alive must be true using {@link io.vertx.core.http.HttpClientOptions#setKeepAlive(boolean)}
* on the options used when configuring the client. The default value is true.
*
* When keep alive is enabled. Vert.x will add a `Connection: Keep-Alive` header to each HTTP request sent.
*
* The maximum number of connections to pool *for each server* is configured using {@link io.vertx.core.http.HttpClientOptions#setMaxPoolSize(int)}
*
* When making a request with pooling enabled, Vert.x will create a new connection if there are less than the maximum number of
* connections already created for that server, otherwise it will add the request to a queue.
*
* When a response returns, if there are pending requests for the server, then the connection will be reused, otherwise
* it will be closed.
*
* This gives the benefits of keep alive when the client is loaded but means we don't keep connections hanging around
* unnecessarily when there would be no benefits anyway.
*
* === Pipe-lining
*
* The client also supports pipe-lining of requests on a connection.
*
* Pipe-lining means another request is sent on the same connection before the response from the preceding one has
* returned. Pipe-lining is not appropriate for all requests.
*
* To enable pipe-lining, it must be enabled using {@link io.vertx.core.http.HttpClientOptions#setPipelining(boolean)}.
* By default pipe-lining is disabled.
*
* When pipe-lining is enabled requests will be written to connections without waiting for previous responses to return.
*
* When pipe-line responses return at the client, the connection will be automatically closed when all in-flight
* responses have returned and there are no outstanding pending requests to write.
*
* === Server sharing
*
* When several HTTP servers listen on the same port, vert.x orchestrates the request handling using a
* round-robin strategy.
*
* Let's take a verticle creating a HTTP server such as:
*
* .io.vertx.examples.http.sharing.HttpServerVerticle
* [source,$lang]
* ----
* {@link examples.HTTPExamples#serversharing(io.vertx.core.Vertx)}
* ----
*
* This service is listening on the port 8080. So, when this verticle is instantiated multiple times as with:
* `vertx run io.vertx.examples.http.sharing.HttpServerVerticle -instances 2`, what's happening ? If both
* verticles would bind to the same port, you would receive a socket exception. Fortunately, vert.x is handling
* this case for you. When you deploy another server on the same host and port as an existing server it doesn't
* actually try and create a new server listening on the same host/port. It binds only once to the socket. When
* receiving a request it calls the server handlers following a round robin strategy.
*
* Let's now imagine a client such as:
* [source,$lang]
* ----
* {@link examples.HTTPExamples#serversharingclient(io.vertx.core.Vertx)}
* ----
*
* Vert.x delegates the requests to one of the server sequentially:
*
* [source]
* ----
* Hello from i.v.e.h.s.HttpServerVerticle@1
* Hello from i.v.e.h.s.HttpServerVerticle@2
* Hello from i.v.e.h.s.HttpServerVerticle@1
* Hello from i.v.e.h.s.HttpServerVerticle@2
* ...
* ----
*
* Consequently the servers can scale over available cores while each Vert.x verticle instance remains strictly
* single threaded, and you don't have to do any special tricks like writing load-balancers in order to scale your
* server on your multi-core machine.
*
* === Using HTTPS with Vert.x
*
* Vert.x http servers and clients can be configured to use HTTPS in exactly the same way as net servers.
*
* Please see <<ssl, configuring net servers to use SSL>> for more information.
*
* === WebSockets
*
* http://en.wikipedia.org/wiki/WebSocket[WebSockets] are a web technology that allows a full duplex socket-like
* connection between HTTP servers and HTTP clients (typically browsers).
*
* Vert.x supports WebSockets on both the client and server-side.
*
* ==== WebSockets on the server
*
* There are two ways of handling WebSockets on the server side.
*
* ===== WebSocket handler
*
* The first way involves providing a {@link io.vertx.core.http.HttpServer#websocketHandler(io.vertx.core.Handler)}
* on the server instance.
*
* When a WebSocket connection is made to the server, the handler will be called, passing in an instance of
* {@link io.vertx.core.http.ServerWebSocket}.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example51}
* ----
*
* You can choose to reject the WebSocket by calling {@link io.vertx.core.http.ServerWebSocket#reject()}.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example52}
* ----
*
* ===== Upgrading to WebSocket
*
* The second way of handling WebSockets is to handle the HTTP Upgrade request that was sent from the client, and
* call {@link io.vertx.core.http.HttpServerRequest#upgrade()} on the server request.
*
* [source,$lang]
* ----
* {@link examples.HTTPExamples#example53}
* ----
*
* ===== The server WebSocket
*