== 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,java]
----
HttpServer server = vertx.createHttpServer();
----

=== Configuring an HTTP server

If you don't want the default, a server can be configured by passing in a `link:../../apidocs/io/vertx/core/http/HttpServerOptions.html[HttpServerOptions]`
instance when creating it:

[source,java]
----
HttpServerOptions options = new HttpServerOptions().setMaxWebsocketFrameSize(1000000);

HttpServer server = vertx.createHttpServer(options);
----

=== Start the Server Listening

To tell the server to listen for incoming requests you use one of the `link:../../apidocs/io/vertx/core/http/HttpServer.html#listen--[listen]`
alternatives.

To tell the server to listen at the host and port as specified in the options:

[source,java]
----
HttpServer server = vertx.createHttpServer();
server.listen();
----

Or to specify the host and port in the call to listen, ignoring what is configured in the options:

[source,java]
----
HttpServer server = vertx.createHttpServer();
server.listen(8080, "myhost.com");
----

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,java]
----
HttpServer server = vertx.createHttpServer();
server.listen(8080, "myhost.com", res -> {
  if (res.succeeded()) {
    System.out.println("Server is now listening!");
  } else {
    System.out.println("Failed to bind!");
  }
});
----

=== Getting notified of incoming requests

To be notified when a request arrives you need to set a `link:../../apidocs/io/vertx/core/http/HttpServer.html#requestHandler-io.vertx.core.Handler-[requestHandler]`:

[source,java]
----
HttpServer server = vertx.createHttpServer();
server.requestHandler(request -> {
  // Handle the request in here
});
----

=== Handling requests

When a request arrives, the request handler is called passing in an instance of `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html[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:../../apidocs/io/vertx/core/http/HttpServerRequest.html#uri--[uri]`,
`link:../../apidocs/io/vertx/core/http/HttpServerRequest.html#path--[path]`, `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html#params--[params]` and
`link:../../apidocs/io/vertx/core/http/HttpServerRequest.html#headers--[headers]`, amongst other things.

Each server request object is associated with one server response object. You use
`link:../../apidocs/io/vertx/core/http/HttpServerRequest.html#response--[response]` to get a reference to the `link:../../apidocs/io/vertx/core/http/HttpServerResponse.html[HttpServerResponse]`
object.

Here's a simple example of a server handling a request and replying with "hello world" to it.

[source,java]
----
vertx.createHttpServer().requestHandler(request -> {
  request.response().end("Hello world");
}).listen(8080);
----

==== Request version

The version of HTTP specified in the request can be retrieved with `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html#version--[version]`

==== Request method

Use `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html#method--[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:../../apidocs/io/vertx/core/http/HttpServerRequest.html#uri--[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:../../apidocs/io/vertx/core/http/HttpServerRequest.html#path--[path]` to return the path part of the URI

For example, if the request URI was:

 a/b/c/page.html?param1=abc&param2=xyz

Then the path would be

 /a/b/c/page.html

==== Request query

Use `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html#query--[query]` to return the query part of the URI

For example, if the request URI was:

 a/b/c/page.html?param1=abc&param2=xyz

Then the query would be

 param1=abc&param2=xyz

==== Request headers

Use `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html#headers--[headers]` to return the headers of the HTTP request.

This returns an instance of `link:../../apidocs/io/vertx/core/MultiMap.html[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,java]
----
MultiMap headers = request.headers();

// Get the User-Agent:
System.out.println("User agent is " + headers.get("user-agent"));

// You can also do this and get the same result:
System.out.println("User agent is " + headers.get("User-Agent"));
----

==== Request parameters

Use `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html#params--[params]` to return the parameters of the HTTP request.

Just like `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html#headers--[headers]` this returns an instance of `link:../../apidocs/io/vertx/core/MultiMap.html[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&param2=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:../../apidocs/io/vertx/core/http/HttpServerRequest.html#remoteAddress--[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:../../apidocs/io/vertx/core/http/HttpServerRequest.html#absoluteURI--[absoluteURI]`

==== End handler

The `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html#endHandler-io.vertx.core.Handler-[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:../../apidocs/io/vertx/core/http/HttpServerRequest.html#handler-io.vertx.core.Handler-[handler]`  on the request,
this will get called every time a chunk of the request body arrives. Here's an example:

[source,java]
----
request.handler(buffer -> {
  System.out.println("I have received a chunk of the body of length " + buffer.length());
});
----

The object passed into the handler is a `link:../../apidocs/io/vertx/core/buffer/Buffer.html[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,java]
----
Buffer totalBuffer = Buffer.buffer();

request.handler(buffer -> {
  System.out.println("I have received a chunk of the body of length " + buffer.length());
  totalBuffer.appendBuffer(buffer);
});

request.endHandler(v -> {
  System.out.println("Full body received, length = " + totalBuffer.length());
});
----

This is such a common case, that Vert.x provides a `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html#bodyHandler-io.vertx.core.Handler-[bodyHandler]` to do this
for you. The body handler is called once when all the body has been received:

[source,java]
----
request.bodyHandler(totalBuffer -> {
  System.out.println("Full body received, length = " + totalBuffer.length());
});
----

==== Pumping requests

The request object is a `link:../../apidocs/io/vertx/core/streams/ReadStream.html[ReadStream]` so you can pump the request body to any
`link:../../apidocs/io/vertx/core/streams/WriteStream.html[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:../../apidocs/io/vertx/core/http/HttpServerRequest.html#setExpectMultipart-boolean-[setExpectMultipart]`
with true, and then you should retrieve the actual attributes using `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html#formAttributes--[formAttributes]`
once the entire body has been read:

[source,java]
----
server.requestHandler(request -> {
  request.setExpectMultipart(true);
  request.endHandler(v -> {
    // The body has now been fully read, so retrieve the form attributes
    MultiMap formAttributes = request.formAttributes();
  });
});
----

==== 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:../../apidocs/io/vertx/core/http/HttpServerRequest.html#uploadHandler-io.vertx.core.Handler-[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:../../apidocs/io/vertx/core/http/HttpServerFileUpload.html[HttpServerFileUpload]` instance.

[source,java]
----
server.requestHandler(request -> {
  request.setExpectMultipart(true);
  request.uploadHandler(upload -> {
    System.out.println("Got a file upload " + upload.name());
  });
});
----

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,java]
----
request.uploadHandler(upload -> {
  upload.handler(chunk -> {
    System.out.println("Received a chunk of the upload of length " + chunk.length());
  });
});
----

The upload object is a `link:../../apidocs/io/vertx/core/streams/ReadStream.html[ReadStream]` so you can pump the request body to any
`link:../../apidocs/io/vertx/core/streams/WriteStream.html[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:../../apidocs/io/vertx/core/http/HttpServerFileUpload.html#streamToFileSystem-java.lang.String-[streamToFileSystem]`:

[source,java]
----
request.uploadHandler(upload -> {
  upload.streamToFileSystem("myuploads_directory/" + upload.filename());
});
----

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:../../apidocs/io/vertx/core/http/HttpServerResponse.html[HttpServerResponse]` and is obtained from the
request with `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html#response--[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:../../apidocs/io/vertx/core/http/HttpServerResponse.html#setStatusCode-int-[setStatusCode]` to set a different code.

You can also specify a custom status message with `link:../../apidocs/io/vertx/core/http/HttpServerResponse.html#setStatusMessage-java.lang.String-[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:../../apidocs/io/vertx/core/http/HttpServerResponse.html#write-io.vertx.core.buffer.Buffer-[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,java]
----
HttpServerResponse response = request.response();
response.write(buffer);
----

With a string. In this case the string will encoded using UTF-8 and the result written to the wire.

[source,java]
----
HttpServerResponse response = request.response();
response.write("hello world!");
----

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,java]
----
HttpServerResponse response = request.response();
response.write("hello world!", "UTF-16");
----

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:../../apidocs/io/vertx/core/http/HttpServerResponse.html#end-java.lang.String-[end]`

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:../../apidocs/io/vertx/core/http/HttpServerResponse.html#end-java.lang.String-[end]` it.

This can be done in several ways:

With no arguments, the response is simply ended.

[source,java]
----
HttpServerResponse response = request.response();
response.write("hello world!");
response.end();
----

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,java]
----
HttpServerResponse response = request.response();
response.end("hello world!");
----

==== Closing the underlying connection

You can close the underlying TCP connection with `link:../../apidocs/io/vertx/core/http/HttpServerResponse.html#close--[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:../../apidocs/io/vertx/core/http/HttpServerOptions.html#setIdleTimeout-int-[setIdleTimeout]`.

==== Setting response headers

HTTP response headers can be added to the response by adding them directly to the
`link:../../apidocs/io/vertx/core/http/HttpServerResponse.html#headers--[headers]`:

[source,java]
----
HttpServerResponse response = request.response();
MultiMap headers = response.headers();
headers.set("content-type", "text/html");
headers.set("other-header", "wibble");
----

Or you can use `link:../../apidocs/io/vertx/core/http/HttpServerResponse.html#putHeader-java.lang.String-java.lang.String-[putHeader]`

[source,java]
----
HttpServerResponse response = request.response();
response.putHeader("content-type", "text/html").putHeader("other-header", "wibble");
----

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,java]
----
HttpServerResponse response = request.response();
response.setChunked(true);
----

Default is non-chunked. When in chunked mode, each call to one of the `link:../../apidocs/io/vertx/core/http/HttpServerResponse.html#write-io.vertx.core.buffer.Buffer-[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:../../apidocs/io/vertx/core/http/HttpServerResponse.html#trailers--[trailers]`.

[source,java]
----
HttpServerResponse response = request.response();
response.setChunked(true);
MultiMap trailers = response.trailers();
trailers.set("X-wibble", "woobble").set("X-quux", "flooble");
----

Or use `link:../../apidocs/io/vertx/core/http/HttpServerResponse.html#putTrailer-java.lang.String-java.lang.String-[putTrailer]`.

[source,java]
----
HttpServerResponse response = request.response();
response.setChunked(true);
response.putTrailer("X-wibble", "woobble").putTrailer("X-quux", "flooble");
----

==== 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:../../apidocs/io/vertx/core/file/AsyncFile.html[AsyncFile]`
and pump it to the HTTP response.

Or you could load it it one go using `link:../../apidocs/io/vertx/core/file/FileSystem.html#readFile-java.lang.String-io.vertx.core.Handler-[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:../../apidocs/io/vertx/core/http/HttpServerResponse.html#sendFile-java.lang.String-[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,java]
----
vertx.createHttpServer().requestHandler(request -> {
  String file = "";
  if (request.path().equals("/")) {
    file = "index.html";
  } else if (!request.path().contains("..")) {
    file = request.path();
  }
  request.response().sendFile("web/" + file);
}).listen(8080);
----

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:../../apidocs/io/vertx/core/http/HttpServerResponse.html#sendFile-java.lang.String-io.vertx.core.Handler-[sendFile]`

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:../../apidocs/io/vertx/core/streams/WriteStream.html[WriteStream]` instance so you can pump to it from any
`link:../../apidocs/io/vertx/core/streams/ReadStream.html[ReadStream]`, e.g. `link:../../apidocs/io/vertx/core/file/AsyncFile.html[AsyncFile]`, `link:../../apidocs/io/vertx/core/net/NetSocket.html[NetSocket]`,
`link:../../apidocs/io/vertx/core/http/WebSocket.html[WebSocket]` or `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html[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,java]
----
vertx.createHttpServer().requestHandler(request -> {
  HttpServerResponse response = request.response();
  if (request.method() == HttpMethod.PUT) {
    response.setChunked(true);
    Pump.pump(request, response).start();
    request.endHandler(v -> response.end());
  } else {
    response.setStatusCode(400).end();
  }
}).listen(8080);
----

=== 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:../../apidocs/io/vertx/core/http/HttpServerOptions.html#setCompressionSupported-boolean-[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:../../apidocs/io/vertx/core/http/HttpClient.html[HttpClient]` instance with default options as follows:

[source,java]
----
HttpClient client = vertx.createHttpClient();
----

If you want to configure options for the client, you create it as follows:

[source,java]
----
HttpClientOptions options = new HttpClientOptions().setKeepAlive(false);
HttpClient client = vertx.createHttpClient(options);
----

=== 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,java]
----
HttpClientOptions options = new HttpClientOptions().setDefaultHost("wibble.com");
// Can also set default port if you want...
HttpClient client = vertx.createHttpClient(options);
client.getNow("/some-uri", response -> {
  System.out.println("Received response with status code " + response.statusCode());
});
----

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,java]
----
HttpClient client = vertx.createHttpClient();

// Specify both port and host name
client.getNow(8080, "myserver.mycompany.com", "/some-uri", response -> {
  System.out.println("Received response with status code " + response.statusCode());
});

// This time use the default port 80 but specify the host name
client.getNow("foo.othercompany.com", "/other-uri", response -> {
  System.out.println("Received response with status code " + response.statusCode());
});
----

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:../../apidocs/io/vertx/core/http/HttpClient.html#getNow-int-java.lang.String-java.lang.String-io.vertx.core.Handler-[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,java]
----
HttpClient client = vertx.createHttpClient();

// Send a GET request
client.getNow("/some-uri", response -> {
  System.out.println("Received response with status code " + response.statusCode());
});

// Send a GET request
client.headNow("/other-uri", response -> {
  System.out.println("Received response with status code " + response.statusCode());
});
----

==== 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:../../apidocs/io/vertx/core/http/HttpClient.html#request-io.vertx.core.http.HttpMethod-int-java.lang.String-java.lang.String-[request]` which allow you to specify
the HTTP method at run-time:

[source,java]
----
HttpClient client = vertx.createHttpClient();

client.request(HttpMethod.GET, "some-uri", response -> {
  System.out.println("Received response with status code " + response.statusCode());
}).end();

client.request(HttpMethod.POST, "foo-uri", response -> {
  System.out.println("Received response with status code " + response.statusCode());
}).end("some-data");
----

==== 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:../../apidocs/io/vertx/core/http/HttpClient.html#post-int-java.lang.String-java.lang.String-[post]` or
one of the general purpose request methods such as `link:../../apidocs/io/vertx/core/http/HttpClient.html#request-io.vertx.core.http.HttpMethod-int-java.lang.String-java.lang.String-[request]`.

These methods don't send the request immediately, but instead return an instance of `link:../../apidocs/io/vertx/core/http/HttpClientRequest.html[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,java]
----
HttpClient client = vertx.createHttpClient();

HttpClientRequest request = client.post("some-uri", response -> {
  System.out.println("Received response with status code " + response.statusCode());
});

// Now do stuff with the request
request.putHeader("content-length", "1000");
request.putHeader("content-type", "text/plain");
request.write(body);

// Make sure the request is ended when you're done with it
request.end();

// Or fluently:

client.post("some-uri", response -> {
  System.out.println("Received response with status code " + response.statusCode());
}).putHeader("content-length", "1000").putHeader("content-type", "text/plain").write(body).end();

// Or event more simply:

client.post("some-uri", response -> {
  System.out.println("Received response with status code " + response.statusCode());
}).putHeader("content-type", "text/plain").end(body);
----

Methods exist to write strings in UTF-8 encoding and in any specific encoding and to write buffers:

[source,java]
----
request.write("some data");

// Write string encoded in specific encoding
request.write("some other data", "UTF-16");

// Write a buffer
Buffer buffer = Buffer.buffer();
buffer.appendInt(123).appendLong(245l);
request.write(buffer);
----

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,java]
----
request.end("some simple data");

// Write buffer and end the request (send it) in a single call
Buffer buffer = Buffer.buffer().appendDouble(12.34d).appendLong(432l);
request.end(buffer);
----

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:../../apidocs/io/vertx/core/http/HttpClientRequest.html#headers--[headers]` multi-map as follows:

[source,java]
----
MultiMap headers = request.headers();
headers.set("content-type", "application/json").set("other-header", "foo");
----

The headers are an instance of `link:../../apidocs/io/vertx/core/MultiMap.html[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:../../apidocs/io/vertx/core/http/HttpClientRequest.html#putHeader-java.lang.String-java.lang.String-[putHeader]`

[source,java]
----
request.putHeader("content-type", "application/json").putHeader("other-header", "foo");
----

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:../../apidocs/io/vertx/core/http/HttpClientRequest.html#end-java.lang.String-[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,java]
----
request.end();
----

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,java]
----
request.end("some-data");

// End it with a buffer
Buffer buffer = Buffer.buffer().appendFloat(12.3f).appendInt(321);
request.end(buffer);
----

==== 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:../../apidocs/io/vertx/core/http/HttpClientRequest.html#setChunked-boolean-[setChunked]`.

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,java]
----
request.setChunked(true);

// Write some chunks
for (int i = 0; i < 10; i++) {
  request.write("this-is-chunk-" + i);
}

request.end();
----

==== Request timeouts

You can set a timeout for a specific http request using `link:../../apidocs/io/vertx/core/http/HttpClientRequest.html#setTimeout-long-[setTimeout]`.

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:../../apidocs/io/vertx/core/http/HttpClientRequest.html[HttpClientRequest]` instance:

[source,java]
----
HttpClientRequest request = client.post("some-uri", response -> {
  System.out.println("Received response with status code " + response.statusCode());
});
request.exceptionHandler(e -> {
  System.out.println("Received exception: " + e.getMessage());
  e.printStackTrace();
});
----

This does not handle non _2xx_ response that need to be handled in the
`link:../../apidocs/io/vertx/core/http/HttpClientResponse.html[HttpClientResponse]` code:

[source, java]
----
HttpClientRequest request = client.post("some-uri", response -> {
  if (response.statusCode() == 200) {
    System.out.println("Everything fine");
    return;
  }
  if (response.statusCode() == 500) {
    System.out.println("Unexpected behavior on the server side");
    return;
  }
});
request.end();
----

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:../../apidocs/io/vertx/core/http/HttpClientRequest.html#handler-io.vertx.core.Handler-[handler]`, for example:

[source,java]
----
HttpClientRequest request = client.post("some-uri");
request.handler(response -> {
  System.out.println("Received response with status code " + response.statusCode());
});
----

==== Using the request as a stream

The `link:../../apidocs/io/vertx/core/http/HttpClientRequest.html[HttpClientRequest]` instance is also a `link:../../apidocs/io/vertx/core/streams/WriteStream.html[WriteStream]` which means
you can pump to it from any `link:../../apidocs/io/vertx/core/streams/ReadStream.html[ReadStream]` instance.

For, example, you could pump a file on disk to a http request body as follows:

[source,java]
----
request.setChunked(true);
Pump pump = Pump.pump(file, request);
file.endHandler(v -> request.end());
pump.start();
----

=== Handling http responses

You receive an instance of `link:../../apidocs/io/vertx/core/http/HttpClientResponse.html[HttpClientResponse]` into the handler that you specify in of
the request methods or by setting a handler directly on the `link:../../apidocs/io/vertx/core/http/HttpClientRequest.html[HttpClientRequest]` object.

You can query the status code and the status message of the response with `link:../../apidocs/io/vertx/core/http/HttpClientResponse.html#statusCode--[statusCode]`
and `link:../../apidocs/io/vertx/core/http/HttpClientResponse.html#statusMessage--[statusMessage]`.

[source,java]
----
client.getNow("some-uri", response -> {
  // the status code - e.g. 200 or 404
  System.out.println("Status code is " + response.statusCode());

  // the status message e.g. "OK" or "Not Found".
  System.out.println("Status message is " + response.statusMessage());
});
----

==== Using the response as a stream

The `link:../../apidocs/io/vertx/core/http/HttpClientResponse.html[HttpClientResponse]` instance is also a `link:../../apidocs/io/vertx/core/streams/ReadStream.html[ReadStream]` which means
you can pump it to any `link:../../apidocs/io/vertx/core/streams/WriteStream.html[WriteStream]` instance.

==== Response headers and trailers

Http responses can contain headers. Use `link:../../apidocs/io/vertx/core/http/HttpClientResponse.html#headers--[headers]` to get the headers.

The object returned is a `link:../../apidocs/io/vertx/core/MultiMap.html[MultiMap]` as HTTP headers can contain multiple values for single keys.

[source,java]
----
String contentType = response.headers().get("content-type");
String contentLength = response.headers().get("content-lengh");
----

Chunked HTTP responses can also contain trailers - these are sent in the last chunk of the response body.

You use `link:../../apidocs/io/vertx/core/http/HttpClientResponse.html#trailers--[trailers]` to get the trailers. Trailers are also a `link:../../apidocs/io/vertx/core/MultiMap.html[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:../../apidocs/io/vertx/core/http/HttpClientResponse.html#handler-io.vertx.core.Handler-[handler]` is called with
a `link:../../apidocs/io/vertx/core/buffer/Buffer.html[Buffer]` representing the piece of the body:

[source,java]
----
client.getNow("some-uri", response -> {

  response.handler(buffer -> {
    System.out.println("Received a part of the response body: " + buffer);
  });
});
----

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,java]
----
client.getNow("some-uri", response -> {

  // Create an empty buffer
  Buffer totalBuffer = Buffer.buffer();

  response.handler(buffer -> {
    System.out.println("Received a part of the response body: " + buffer.length());

    totalBuffer.appendBuffer(buffer);
  });

  response.endHandler(v -> {
    // Now all the body has been read
    System.out.println("Total response body length is " + totalBuffer.length());
  });
});
----

Or you can use the convenience `link:../../apidocs/io/vertx/core/http/HttpClientResponse.html#bodyHandler-io.vertx.core.Handler-[bodyHandler]` which
is called with the entire body when the response has been fully read:

[source,java]
----
client.getNow("some-uri", response -> {

  response.bodyHandler(totalBuffer -> {
    // Now all the body has been read
    System.out.println("Total response body length is " + totalBuffer.length());
  });
});
----

==== Response end handler

The response `link:../../apidocs/io/vertx/core/http/HttpClientResponse.html#endHandler-io.vertx.core.Handler-[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:../../apidocs/io/vertx/core/http/HttpClientResponse.html#cookies--[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:../../apidocs/io/vertx/core/http/HttpClientRequest.html#continueHandler-io.vertx.core.Handler-[continueHandler]` 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:../../apidocs/io/vertx/core/http/HttpClientRequest.html#sendHead--[sendHead]`to send the head of the request.

Here's an example:

[source,java]
----
HttpClientRequest request = client.put("some-uri", response -> {
  System.out.println("Received response with status code " + response.statusCode());
});

request.putHeader("Expect", "100-Continue");

request.continueHandler(v -> {
  // OK to send rest of body
  request.write("Some data");
  request.write("Some more data");
  request.end();
});
----

=== 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:../../apidocs/io/vertx/core/http/HttpClientOptions.html#setTryUseCompression-boolean-[setTryUseCompression]` 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:../../apidocs/io/vertx/core/http/HttpClientOptions.html#setKeepAlive-boolean-[setKeepAlive]`
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:../../apidocs/io/vertx/core/http/HttpClientOptions.html#setMaxPoolSize-int-[setMaxPoolSize]`

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:../../apidocs/io/vertx/core/http/HttpClientOptions.html#setPipelining-boolean-[setPipelining]`.
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,java]
----
vertx.createHttpServer().requestHandler(request -> {
  request.response().end("Hello from server " + this);
}).listen(8080);
----

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,java]
----
vertx.setPeriodic(100, (l) -> {
  vertx.createHttpClient().getNow(8080, "localhost", "/", resp -> {
    resp.bodyHandler(body -> {
      System.out.println(body.toString("ISO-8859-1"));
    });
  });
});
----

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:../../apidocs/io/vertx/core/http/HttpServer.html#websocketHandler-io.vertx.core.Handler-[websocketHandler]`
on the server instance.

When a WebSocket connection is made to the server, the handler will be called, passing in an instance of
`link:../../apidocs/io/vertx/core/http/ServerWebSocket.html[ServerWebSocket]`.

[source,java]
----
server.websocketHandler(websocket -> {
  System.out.println("Connected!");
});
----

You can choose to reject the WebSocket by calling `link:../../apidocs/io/vertx/core/http/ServerWebSocket.html#reject--[reject]`.

[source,java]
----
server.websocketHandler(websocket -> {
  if (websocket.path().equals("/myapi")) {
    websocket.reject();
  } else {
    // Do something
  }
});
----

===== 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:../../apidocs/io/vertx/core/http/HttpServerRequest.html#upgrade--[upgrade]` on the server request.

[source,java]
----
server.requestHandler(request -> {
  if (request.path().equals("/myapi")) {

    ServerWebSocket websocket = request.upgrade();
    // Do something

  } else {
    // Reject
    request.response().setStatusCode(400).end();
  }
});
----

===== The server WebSocket

The `link:../../apidocs/io/vertx/core/http/ServerWebSocket.html[ServerWebSocket]` instance enables you to retrieve the `link:../../apidocs/io/vertx/core/http/ServerWebSocket.html#headers--[headers]`,
`link:../../apidocs/io/vertx/core/http/ServerWebSocket.html#path--[path]` path}, `link:../../apidocs/io/vertx/core/http/ServerWebSocket.html#query--[query]` and
`link:../../apidocs/io/vertx/core/http/ServerWebSocket.html#uri--[uri]` URI} of the HTTP request of the WebSocket handshake.

==== WebSockets on the client

The Vert.x `link:../../apidocs/io/vertx/core/http/HttpClient.html[HttpClient]` supports WebSockets.

You can connect a WebSocket to a server using one of the `link:../../apidocs/io/vertx/core/http/HttpClient.html#websocket-int-java.lang.String-java.lang.String-io.vertx.core.Handler-[websocket]` operations and
providing a handler.

The handler will be called with an instance of `link:../../apidocs/io/vertx/core/http/WebSocket.html[WebSocket]` when the connection has been made:

[source,java]
----
client.websocket("/some-uri", websocket -> {
  System.out.println("Connected!");
});
----

==== Writing messages to WebSockets

If you wish to write a single binary WebSocket message to the WebSocket you can do this with
`link:../../apidocs/io/vertx/core/http/WebSocket.html#writeBinaryMessage-io.vertx.core.buffer.Buffer-[writeBinaryMessage]`:

[source,java]
----
Buffer buffer = Buffer.buffer().appendInt(123).appendFloat(1.23f);

websocket.writeBinaryMessage(buffer);
----

If the WebSocket message is larger than the maximum websocket frame size as configured with
`link:../../apidocs/io/vertx/core/http/HttpClientOptions.html#setMaxWebsocketFrameSize-int-[setMaxWebsocketFrameSize]`
then Vert.x will split it into multiple WebSocket frames before sending it on the wire.

==== Writing frames to WebSockets

A WebSocket message can be composed of multiple frames. In this case the first frame is either a _binary_ or _text_ frame
followed by zero or more _continuation_ frames.

The last frame in the message is marked as _final_.

To send a message consisting of multiple frames you create frames using
`link:../../apidocs/io/vertx/core/http/WebSocketFrame.html#binaryFrame-io.vertx.core.buffer.Buffer-boolean-[WebSocketFrame.binaryFrame]`
, `link:../../apidocs/io/vertx/core/http/WebSocketFrame.html#textFrame-java.lang.String-boolean-[WebSocketFrame.textFrame]` or
`link:../../apidocs/io/vertx/core/http/WebSocketFrame.html#continuationFrame-io.vertx.core.buffer.Buffer-boolean-[WebSocketFrame.continuationFrame]` and write them
to the WebSocket using `link:../../apidocs/io/vertx/core/http/WebSocket.html#writeFrame-io.vertx.core.http.WebSocketFrame-[writeFrame]`.

Here's an example for binary frames:

[source,java]
----
WebSocketFrame frame1 = WebSocketFrame.binaryFrame(buffer1, false);
websocket.writeFrame(frame1);

WebSocketFrame frame2 = WebSocketFrame.continuationFrame(buffer2, false);
websocket.writeFrame(frame2);

// Write the final frame
WebSocketFrame frame3 = WebSocketFrame.continuationFrame(buffer2, true);
websocket.writeFrame(frame3);
----

In many cases you just want to send a websocket message that consists of a single final frame, so we provide a couple
of shortcut methods to do that with `link:../../apidocs/io/vertx/core/http/WebSocket.html#writeFinalBinaryFrame-io.vertx.core.buffer.Buffer-[writeFinalBinaryFrame]`
and `link:../../apidocs/io/vertx/core/http/WebSocket.html#writeFinalTextFrame-java.lang.String-[writeFinalTextFrame]`.

Here's an example:

[source,java]
----
websocket.writeFinalTextFrame("Geronimo!");

// Send a websocket messages consisting of a single final binary frame:

Buffer buff = Buffer.buffer().appendInt(12).appendString("foo");

websocket.writeFinalBinaryFrame(buff);
----

==== Reading frames from WebSockets

To read frames from a WebSocket you use the `link:../../apidocs/io/vertx/core/http/WebSocket.html#frameHandler-io.vertx.core.Handler-[frameHandler]`.

The frame handler will be called with instances of `link:../../apidocs/io/vertx/core/http/WebSocketFrame.html[WebSocketFrame]` when a frame arrives,
for example:

[source,java]
----
websocket.frameHandler(frame -> {
  System.out.println("Received a frame of size!");
});
----

==== Closing WebSockets

Use `link:../../apidocs/io/vertx/core/http/WebSocketBase.html#close--[close]` to close the WebSocket connection when you have finished with it.

==== Streaming WebSockets

The `link:../../apidocs/io/vertx/core/http/WebSocket.html[WebSocket]` instance is also a `link:../../apidocs/io/vertx/core/streams/ReadStream.html[ReadStream]` and a
`link:../../apidocs/io/vertx/core/streams/WriteStream.html[WriteStream]` so it can be used with pumps.

When using a WebSocket as a write stream or a read stream it can only be used with WebSockets connections that are
used with binary frames that are no split over multiple frames.

=== Automatic clean-up in verticles

If you're creating http servers and clients from inside verticles, those servers and clients will be automatically closed
when the verticle is undeployed.