= Vert.x-Web
:toc: left

Vert.x-Web is a set of building blocks for building web applications with Vert.x. Think of it as a Swiss Army Knife for
building modern, scalable, web apps.

Vert.x core provides a fairly low level set of functionality for handling HTTP, and for some applications
that will be sufficient.

Vert.x-Web builds on Vert.x core to provide a richer set of functionality for building real web applications, more
easily.

It's the successor to http://pmlopes.github.io/yoke/[Yoke] in Vert.x 2.x, and takes inspiration from projects such
as http://expressjs.com/[Express] in the Node.js world and http://www.sinatrarb.com/[Sinatra] in the Ruby world.

Vert.x-Web is designed to be powerful, un-opionated and fully embeddable. You just use the parts you want and nothing more.
Vert.x-Web is not a container.

You can use Vert.x-Web to create classic server-side web applications, RESTful web applications, 'real-time' (server push)
web applications, or any other kind of web application you can think of. Vert.x-Web doesn't care. It's up to you to chose
the type of app you prefer, not Vert.x-Web.

Vert.x-Web is a great fit for writing RESTful HTTP micro-services**, but we don't force** you to write apps like that.

Some of the key features of Vert.x-Web include:

* Routing (based on method, path, etc)
* Regular expression pattern matching for paths
* Extraction of parameters from paths
* Content negotiation
* Request body handling
* Body size limits
* Multipart forms
* Multipart file uploads
* Sub routers
* Session support - both local (for sticky sessions) and clustered (for non sticky)
* CORS (Cross Origin Resource Sharing) support
* Error page handler
* HTTP Basic/Digest Authentication
* Redirect based authentication
* Authorization handlers
* JWT/OAuth2 based authorization
* User/role/permission authorization
* Favicon handling
* Template support for server side rendering, including support for the following template engines out of the box:
** Handlebars
** Jade,
** MVEL
** Thymeleaf
** Apache FreeMarker
** Pebble
** Rocker
* Response time handler
* Static file serving, including caching logic and directory listing.
* Request timeout support
* SockJS support
* Event-bus bridge
* CSRF Cross Site Request Forgery
* VirtualHost

Most features in Vert.x-Web are implemented as handlers so you can always write your own. We envisage many more being
written over time.

We'll discuss all these features in this manual.

== Using Vert.x Web

To use vert.x web, add the following dependency to the _dependencies_ section of your build descriptor:

* Maven (in your `pom.xml`):

[source,xml,subs="+attributes"]
----
<dependency>
 <groupId>io.vertx</groupId>
 <artifactId>vertx-web</artifactId>
 <version>4.3.5</version>
</dependency>
----

* Gradle (in your `build.gradle` file):

[source,groovy,subs="+attributes"]
----
dependencies {
 compile 'io.vertx:vertx-web:4.3.5'
}
----

=== Development mode

Vert.x Web by default operates in production mode.
You can switch the development mode by assigning the `dev` value to either:

* the `VERTXWEB_ENVIRONMENT` environment variable, or
* the `vertxweb.environment` system property

In development mode:

* template engine caches are disabled
* the `ErrorHandler` does not display exception details
* the `StaticHandler` does not handle cache headers
* the GraphiQL development tool is disabled

== Re-cap on Vert.x core HTTP servers

Vert.x-Web uses and exposes the API from Vert.x core, so it's well worth getting familiar with the basic concepts of writing
HTTP servers using Vert.x core, if you're not already.

The Vert.x core HTTP documentation goes into a lot of detail on this.

Here's a hello world web server written using Vert.x core. At this point there is no Vert.x-Web involved:

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

server.requestHandler(request -> {

  // This handler gets called for each request that arrives on the server
  HttpServerResponse response = request.response();
  response.putHeader("content-type", "text/plain");

  // Write to the response and end it
  response.end("Hello World!");
});

server.listen(8080);
----

We create an HTTP server instance, and we set a request handler on it. The request handler will be called whenever
a request arrives on the server.

When that happens we are just going to set the content type to `text/plain`, and write `Hello World!` and end the
response.

We then tell the server to listen at port `8080` (default host is `localhost`).

You can run this, and point your browser at `http://localhost:8080` to verify that it works as expected.

== Basic Vert.x-Web concepts

Here's the 10000 foot view:

A `link:../../apidocs/io/vertx/ext/web/Router.html[Router]` is one of the core concepts of Vert.x-Web. It's an object which maintains zero or more
`link:../../apidocs/io/vertx/ext/web/Route.html[Routes]`.

A router will pause the incoming `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html[HttpServerRequest]`, to ensure that the request body or any
protocol upgrades are not lost. Second, it will find the first matching route for that request, and passes the request
to that route.

The route can have a _handler_ associated with it, which then receives the request. You then _do something_ with the
request, and then, either end it or pass it to the next matching handler.

Here's a simple router example:

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

Router router = Router.router(vertx);

router.route().handler(ctx -> {

  // This handler will be called for every request
  HttpServerResponse response = ctx.response();
  response.putHeader("content-type", "text/plain");

  // Write to the response and end it
  response.end("Hello World from Vert.x-Web!");
});

server.requestHandler(router).listen(8080);
----

It basically does the same thing as the Vert.x Core HTTP server hello world example from the previous section,
but this time using Vert.x-Web.

We create an HTTP server as before, then we create a router. Once we've done that we create a simple route with
no matching criteria so it will match _all_ requests that arrive on the server.

We then specify a handler for that route. That handler will be called for all requests that arrive on the server.

The object that gets passed into the handler is a `link:../../apidocs/io/vertx/ext/web/RoutingContext.html[RoutingContext]` - this contains
the standard Vert.x `link:../../apidocs/io/vertx/core/http/HttpServerRequest.html[HttpServerRequest]` and `link:../../apidocs/io/vertx/core/http/HttpServerResponse.html[HttpServerResponse]`
but also various other useful stuff that makes working with Vert.x-Web simpler.

For every request that is routed there is a unique routing context instance, and the same instance is passed to
all handlers for that request.

Once we've set up the handler, we set the request handler of the HTTP server to pass all incoming requests
to `link:../../apidocs/io/vertx/core/Handler.html#handle-java.lang.Object-[handle]`.

So, that's the basics. Now we'll look at things in more detail:

== Handling requests and calling the next handler

When Vert.x-Web decides to route a request to a matching route, it calls the handler of the route passing in an instance
of `link:../../apidocs/io/vertx/ext/web/RoutingContext.html[RoutingContext]`. A route can have different handlers, that you can append using
`link:../../apidocs/io/vertx/ext/web/Route.html#handler-io.vertx.core.Handler-[handler]`

If you don't end the response in your handler, you should call `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#next--[next]` so another
matching route can handle the request (if any).

You don't have to call `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#next--[next]` before the handler has finished executing.
You can do this some time later, if you want:

[source,java]
----
Route route = router.route("/some/path/");
route.handler(ctx -> {

  HttpServerResponse response = ctx.response();
  // enable chunked responses because we will be adding data as
  // we execute over other handlers. This is only required once and
  // only if several handlers do output.
  response.setChunked(true);

  response.write("route1\n");

  // Call the next matching route after a 5 second delay
  ctx.vertx().setTimer(5000, tid -> ctx.next());
});

route.handler(ctx -> {

  HttpServerResponse response = ctx.response();
  response.write("route2\n");

  // Call the next matching route after a 5 second delay
  ctx.vertx().setTimer(5000, tid -> ctx.next());
});

route.handler(ctx -> {

  HttpServerResponse response = ctx.response();
  response.write("route3");

  // Now end the response
  ctx.response().end();
});
----

In the above example `route1` is written to the response, then 5 seconds later `route2` is written to the response,
then 5 seconds later `route3` is written to the response and the response is ended.

Note, all this happens without any thread blocking.

== Simple responses

Handlers are quite powerful as they allow you to build quite complex applications. For simple responses, for example,
returning an asynchronous response from a vert.x API directly, the router includes a shortcut to a handler that ensures
that:

1. The response is returned in JSON.
2. If there is an error processing the handler, a proper error is returned.
3. If there is an error serializing the response to JSON, a proper error is returned.

[source,java]
----
router
  .get("/some/path")
  // this handler will ensure that the response is serialized to json
  // the content type is set to "application/json"
  .respond(
    ctx -> Future.succeededFuture(new JsonObject().put("hello", "world")));

router
  .get("/some/path")
  // this handler will ensure that the Pojo is serialized to json
  // the content type is set to "application/json"
  .respond(
    ctx -> Future.succeededFuture(new Pojo()));
----

However you can also use it for non JSON responses if the function supplied calls either `write` or `end`:

[source,java]
----
router
  .get("/some/path")
  .respond(
    ctx -> ctx
      .response()
      .putHeader("Content-Type", "text/plain")
      .end("hello world!"));

router
  .get("/some/path")
  // in this case, the handler ensures that the connection is ended
  .respond(
    ctx -> ctx
      .response()
      .setChunked(true)
      .write("Write some text..."));
----

== Using blocking handlers

Sometimes, you might have to do something in a handler that might block the event loop for some time, e.g. call
a legacy blocking API or do some intensive calculation.

You can't do that in a normal handler, so we provide the ability to set blocking handlers on a route.

A blocking handler looks just like a normal handler but it's called by Vert.x using a thread from the worker pool
not using an event loop.

You set a blocking handler on a route with `link:../../apidocs/io/vertx/ext/web/Route.html#blockingHandler-io.vertx.core.Handler-[blockingHandler]`.
Here's an example:

[source,java]
----
router.route().blockingHandler(ctx -> {

  // Do something that might take some time synchronously
  service.doSomethingThatBlocks();

  // Now call the next handler
  ctx.next();

});
----

By default, any blocking handlers executed on the same context (e.g. the same verticle instance) are _ordered_ - this
means the next one won't be executed until the previous one has completed. If you don't care about orderering and
don't mind your blocking handlers executing in parallel you can set the blocking handler specifying `ordered` as
false using `link:../../apidocs/io/vertx/ext/web/Route.html#blockingHandler-io.vertx.core.Handler-boolean-[blockingHandler]`.

Note, if you need to process multipart form data from a blocking handler, you MUST use a non-blocking handler
     FIRST in order to call `setExpectMultipart(true)`. Here is an example:

[source,java]
----
router.post("/some/endpoint").handler(ctx -> {
  ctx.request().setExpectMultipart(true);
  ctx.next();
}).blockingHandler(ctx -> {
  // ... Do some blocking operation
});
----

== Routing by exact path

A route can be set-up to match the path from the request URI. In this case it will match any request which has a path
that's the same as the specified path.

In the following example the handler will be called for a request `/some/path/`. We also ignore trailing slashes
so it will be called for paths `/some/path` and `/some/path//` too:

[source,java]
----
Route route = router.route().path("/some/path/");

route.handler(ctx -> {
  // This handler will be called for the following request paths:

  // `/some/path/`
  // `/some/path//`
  //
  // but not:
  // `/some/path` the end slash in the path makes it strict
  // `/some/path/subdir`
});

// paths that do not end with slash are not strict
// this means that the trailing slash is optional
// and they match regardless
Route route2 = router.route().path("/some/path");

route2.handler(ctx -> {
  // This handler will be called for the following request paths:

  // `/some/path`
  // `/some/path/`
  // `/some/path//`
  //
  // but not:
  // `/some/path/subdir`
});
----

== Routing by paths that begin with something

Often you want to route all requests that begin with a certain path. You could use a regex to do this, but a simply
way is to use an asterisk `*` at the end of the path when declaring the route path.

In the following example the handler will be called for any request with a URI path that starts with
`/some/path/`.

For example `/some/path/foo.html` and `/some/path/otherdir/blah.css` would both match.

[source,java]
----
Route route = router.route().path("/some/path/*");

route.handler(ctx -> {
  // This handler will be called for any path that starts with
  // `/some/path/`, e.g.

  // `/some/path/`
  // `/some/path/subdir`
  // `/some/path/subdir/blah.html`
  //
  // but **ALSO**:
  // `/some/path` the final slash is always optional with a wildcard to preserve
  //              compatibility with many client libraries.
  // but **NOT**:
  // `/some/patha`
  // `/some/patha/`
  // etc...
});
----

With any path it can also be specified when creating the route:

[source,java]
----
Route route = router.route("/some/path/*");

route.handler(ctx -> {
  // This handler will be called same as previous example
});
----

== Capturing path parameters

It's possible to match paths using placeholders for parameters which are then available in the context
`link:../../apidocs/io/vertx/ext/web/RoutingContext.html#pathParam-java.lang.String-[pathParam]`.

Here's an example

[source,java]
----
router
  .route(HttpMethod.POST, "/catalogue/products/:productType/:productID/")
  .handler(ctx -> {

    String productType = ctx.pathParam("productType");
    String productID = ctx.pathParam("productID");

    // Do something with them...
  });
----

The placeholders consist of `:` followed by the parameter name. Parameter names consist of any alphabetic character,
numeric character or underscore. In certain cases this is a bit limited, so users may switch to an extended name rule
which includes 2 extra characters `-` and `$`. The extended param rule is enabled as a system property:

----
-Dio.vertx.web.route.param.extended-pattern=true
----

In the above example, if a POST request is made to path: `/catalogue/products/tools/drill123/` then the route will match
and `productType` will receive the value `tools` and `productID` will receive the value `drill123`.

A parameter is not required to be a path segment. For example path parameters like the following ones are valid too:

[source,java]
----
router
  .route(HttpMethod.GET, "/flights/:from-:to")
  .handler(ctx -> {
    // when handling requests to /flights/AMS-SFO will set:
    String from = ctx.pathParam("from"); // AMS
    String to = ctx.pathParam("to"); // SFO
    // remember that this will not work as expected when the parameter
    // naming pattern in use is not the "extended" one. That is because in
    // that case "-" is considered to be part of the variable name and
    // not a separator.
  });
----

Note: You can also capture `*` as path param `*`.

== Routing with regular expressions

Regular expressions can also be used to match URI paths in routes.

[source,java]
----
Route route = router.route().pathRegex(".*foo");

route.handler(ctx -> {

  // This handler will be called for:

  // /some/path/foo
  // /foo
  // /foo/bar/wibble/foo
  // /bar/foo

  // But not:
  // /bar/wibble
});
----

Alternatively the regex can be specified when creating the route:

[source,java]
----
Route route = router.routeWithRegex(".*foo");

route.handler(ctx -> {

  // This handler will be called same as previous example

});
----

== Capturing path parameters with regular expressions

You can also capture path parameters when using regular expressions, here's an example:

[source,java]
----
Route route = router.routeWithRegex(".*foo");

// This regular expression matches paths that start with something like:
// "/foo/bar" - where the "foo" is captured into param0 and the "bar" is
// captured into param1
route.pathRegex("\\/([^\\/]+)\\/([^\\/]+)").handler(ctx -> {

  String productType = ctx.pathParam("param0");
  String productID = ctx.pathParam("param1");

  // Do something with them...
});
----

In the above example, if a request is made to path: `/tools/drill123/` then the route will match
and `productType` will receive the value `tools` and `productID` will receive the value `drill123`.

Captures are denoted in regular expressions with capture groups (i.e. surrounding the capture with round brackets)

== Using named capture groups

Using int index param names might be troublesome in some cases.
It's possible to use named capture groups in the regex path.

[source,java]
----
router
  .routeWithRegex("\\/(?<productType>[^\\/]+)\\/(?<productID>[^\\/]+)")
  .handler(ctx -> {

    String productType = ctx.pathParam("productType");
    String productID = ctx.pathParam("productID");

    // Do something with them...
  });
----

In the example above, named capture groups are mapped to path parameters of the same name as the group.

Additionally, you can still access group parameters as you would with normal groups (i.e. `params0, params1...`)

== Routing by HTTP method

By default a route will match all HTTP methods.

If you want a route to only match for a specific HTTP method you can use `link:../../apidocs/io/vertx/ext/web/Route.html#method-io.vertx.core.http.HttpMethod-[method]`

[source,java]
----
Route route = router.route().method(HttpMethod.POST);

route.handler(ctx -> {

  // This handler will be called for any POST request

});
----

Or you can specify this with a path when creating the route:

[source,java]
----
Route route = router.route(HttpMethod.POST, "/some/path/");

route.handler(ctx -> {
  // This handler will be called for any POST request
  // to a URI path starting with /some/path/
});
----

If you want to route for a specific HTTP method you can also use the methods such as `link:../../apidocs/io/vertx/ext/web/Router.html#get--[get]`,
`link:../../apidocs/io/vertx/ext/web/Router.html#post--[post]` and `link:../../apidocs/io/vertx/ext/web/Router.html#put--[put]` named after the HTTP
method name. For example:

[source,java]
----
router.get().handler(ctx -> {

  // Will be called for any GET request

});

router.get("/some/path/").handler(ctx -> {

  // Will be called for any GET request to a path
  // starting with /some/path

});

router.getWithRegex(".*foo").handler(ctx -> {

  // Will be called for any GET request to a path
  // ending with `foo`

});
----

If you want to specify a route will match for more than HTTP method you can call `link:../../apidocs/io/vertx/ext/web/Route.html#method-io.vertx.core.http.HttpMethod-[method]`
multiple times:

[source,java]
----
Route route = router.route().method(HttpMethod.POST).method(HttpMethod.PUT);

route.handler(ctx -> {

  // This handler will be called for any POST or PUT request

});
----

If you are creating an application that require custom HTTP verbs, for example, an `WebDav` server, then you can specify
custom verbs like:

[source,java]
----
Route route = router.route()
  .method(HttpMethod.valueOf("MKCOL"))
  .handler(ctx -> {
    // This handler will be called for any MKCOL request
  });
----

NOTE: It is important to notice that features such as rerouting will not accept custom http methods and inspecting the
route verbs will yield the enumeration value `OTHER` instead of the custom name.

== Route order

By default routes are matched in the order they are added to the router.

When a request arrives the router will step through each route and check if it matches, if it matches then
the handler for that route will be called.

If the handler subsequently calls `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#next--[next]` the handler for the next
matching route (if any) will be called. And so on.

Here's an example to illustrate this:

[source,java]
----
router
  .route("/some/path/")
  .handler(ctx -> {

    HttpServerResponse response = ctx.response();
    // enable chunked responses because we will be adding data as
    // we execute over other handlers. This is only required once and
    // only if several handlers do output.
    response.setChunked(true);

    response.write("route1\n");

    // Now call the next matching route
    ctx.next();
  });

router
  .route("/some/path/")
  .handler(ctx -> {

    HttpServerResponse response = ctx.response();
    response.write("route2\n");

    // Now call the next matching route
    ctx.next();
  });

router
  .route("/some/path/")
  .handler(ctx -> {

    HttpServerResponse response = ctx.response();
    response.write("route3");

    // Now end the response
    ctx.response().end();
  });
----

In the above example the response will contain:

----
route1
route2
route3
----

As the routes have been called in that order for any request that starts with `/some/path`.

If you want to override the default ordering for routes, you can do so using `link:../../apidocs/io/vertx/ext/web/Route.html#order-int-[order]`,
specifying an integer value.

Routes are assigned an order at creation time corresponding to the order in which they were added to the router, with
the first route numbered `0`, the second route numbered `1`, and so on.

By specifying an order for the route you can override the default ordering. Order can also be negative, e.g. if you
want to ensure a route is evaluated before route number `0`.

Let's change the ordering of route2 so it runs before route1:

[source,java]
----
router
  .route("/some/path/")
  .order(1)
  .handler(ctx -> {

    HttpServerResponse response = ctx.response();
    response.write("route1\n");

    // Now call the next matching route
    ctx.next();
  });

router
  .route("/some/path/")
  .order(0)
  .handler(ctx -> {

    HttpServerResponse response = ctx.response();
    // enable chunked responses because we will be adding data as
    // we execute over other handlers. This is only required once and
    // only if several handlers do output.
    response.setChunked(true);

    response.write("route2\n");

    // Now call the next matching route
    ctx.next();
  });

router
  .route("/some/path/")
  .order(2)
  .handler(ctx -> {

    HttpServerResponse response = ctx.response();
    response.write("route3");

    // Now end the response
    ctx.response().end();
  });
----

then the response will now contain:

----
route2
route1
route3
----

If two matching routes have the same value of order, then they will be called in the order they were added.

You can also specify that a route is handled last, with `link:../../apidocs/io/vertx/ext/web/Route.html#last--[last]`

Note: Route order can be specified only before you configure an handler!

== Routing based on MIME type of request

You can specify that a route will match against matching request MIME types using `link:../../apidocs/io/vertx/ext/web/Route.html#consumes-java.lang.String-[consumes]`.

In this case, the request will contain a `content-type` header specifying the MIME type of the request body.
This will be matched against the value specified in `link:../../apidocs/io/vertx/ext/web/Route.html#consumes-java.lang.String-[consumes]`.

Basically, `consumes` is describing which MIME types the handler can _consume_.

Matching can be done on exact MIME type matches:

[source,java]
----
router.route()
  .consumes("text/html")
  .handler(ctx -> {

    // This handler will be called for any request with
    // content-type header set to `text/html`

  });
----

Multiple exact matches can also be specified:

[source,java]
----
router.route()
  .consumes("text/html")
  .consumes("text/plain")
  .handler(ctx -> {

    // This handler will be called for any request with
    // content-type header set to `text/html` or `text/plain`.

  });
----

Matching on wildcards for the sub-type is supported:

[source,java]
----
router.route()
  .consumes("text/*")
  .handler(ctx -> {

    // This handler will be called for any request
    // with top level type `text` e.g. content-type
    // header set to `text/html` or `text/plain`
    // will both match

  });
----

And you can also match on the top level type

[source,java]
----
router.route()
  .consumes("*/json")
  .handler(ctx -> {

    // This handler will be called for any request with sub-type json
    // e.g. content-type header set to `text/json` or
    // `application/json` will both match

  });
----

If you don't specify a `/` in the consumers, it will assume you meant the sub-type.

== Routing based on MIME types acceptable by the client

The HTTP `accept` header is used to signify which MIME types of the response are acceptable to the client.

An `accept` header can have multiple MIME types separated by '`,`'.

MIME types can also have a `q` value appended to them* which signifies a weighting to apply if more than one
response MIME type is available matching the accept header. The q value is a number between 0 and 1.0.
If omitted it defaults to 1.0.

For example, the following `accept` header signifies the client will accept a MIME type of only `text/plain`:

Accept: text/plain

With the following the client will accept `text/plain` or `text/html` with no preference.

Accept: text/plain, text/html

With the following the client will accept `text/plain` or `text/html` but prefers `text/html` as it has a higher
`q` value (the default value is q=1.0)

Accept: text/plain; q=0.9, text/html

If the server can provide both text/plain and text/html it should provide the text/html in this case.

By using `link:../../apidocs/io/vertx/ext/web/Route.html#produces-java.lang.String-[produces]` you define which MIME type(s) the route produces, e.g. the
following handler produces a response with MIME type `application/json`.

[source,java]
----
router.route()
  .produces("application/json")
  .handler(ctx -> {

    HttpServerResponse response = ctx.response();
    response.putHeader("content-type", "application/json");
    response.end(someJSON);

  });
----

In this case the route will match with any request with an `accept` header that matches `application/json`.

Here are some examples of `accept` headers that will match:

Accept: application/json
Accept: application/*
Accept: application/json, text/html
Accept: application/json;q=0.7, text/html;q=0.8, text/plain

You can also mark your route as producing more than one MIME type. If this is the case, then you use
`link:../../apidocs/io/vertx/ext/web/RoutingContext.html#getAcceptableContentType--[getAcceptableContentType]` to find out the actual MIME type that
was accepted.

[source,java]
----
router.route()
  .produces("application/json")
  .produces("text/html")
  .handler(ctx -> {

    HttpServerResponse response = ctx.response();

    // Get the actual MIME type acceptable
    String acceptableContentType = ctx.getAcceptableContentType();

    response.putHeader("content-type", acceptableContentType);
    response.end(whatever);
  });
----

In the above example, if you sent a request with the following `accept` header:

Accept: application/json; q=0.7, text/html

Then the route would match and `acceptableContentType` would contain `text/html` as both are
acceptable but that has a higher `q` value.

== Routing based on VirtualHost

You can configure that a `Route` will match against the request hostname.

Request are checked against the `Host` header to a match and patterns allow the usage of `*` wildcards, as for
example `*.vertx.io` or fully domain names as `www.vertx.io`.

[source,java]
----
router.route().virtualHost("*.vertx.io").handler(ctx -> {
  // do something if the request is for *.vertx.io
});
----

== Combining routing criteria

You can combine all the above routing criteria in many different ways, for example:

[source,java]
----
router.route(HttpMethod.PUT, "myapi/orders")
  .consumes("application/json")
  .produces("application/json")
  .handler(ctx -> {

    // This would be match for any PUT method to paths starting
    // with "myapi/orders" with a content-type of "application/json"
    // and an accept header matching "application/json"

  });
----

== Enabling and disabling routes

You can disable a route with `link:../../apidocs/io/vertx/ext/web/Route.html#disable--[disable]`. A disabled route will be ignored when matching.

You can re-enable a disabled route with `link:../../apidocs/io/vertx/ext/web/Route.html#enable--[enable]`

== Forward Support

Your application may be behind a proxy server, `HAProxy` for example. When working under this setup accessing the
client connection details will not properly return the expected results. For example the client host ip address will
be the proxy server ip address, not the client's one.

In order to get the right connection information, a special header `Forward` has been standardized to include the right
information. However this standard is not very old, so many proxies out there have been using other headers that usually
start with the prefix: `X-Forward`. Vert.x web allows the usage and parsing of these headers but not by default.

The reason why these headers are disabled by default is to prevent malicious applications to forge their origin and hide
where they are really coming from.

As previously mentioned forward is disabled by default, to enable you should use:

[source,java]
----
router.allowForward(AllowForwardHeaders.FORWARD);

// we can now allow forward header parsing
// and in this case only the "X-Forward" headers will be considered
router.allowForward(AllowForwardHeaders.X_FORWARD);

// we can now allow forward header parsing
// and in this case both the "Forward" header and "X-Forward" headers
// will be considered, yet the values from "Forward" take precedence
// this means if case of a conflict (2 headers for the same value)
// the "Forward" value will be taken and the "X-Forward" ignored.
router.allowForward(AllowForwardHeaders.ALL);
----

Same rule applies to explicitly disable the parsing of the headers:

[source,java]
----
router.allowForward(AllowForwardHeaders.NONE);
----

To read more about the format of the header format, please consult:

* https://tools.ietf.org/html/rfc7239#section-4
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded

Behind the scenes, what this feature does is changing the following values of your connection (either HTTP or WebSocket):

* protocol
* host name
* host port

== Context data

You can use the context data in the `link:../../apidocs/io/vertx/ext/web/RoutingContext.html[RoutingContext]` to maintain any data that you
want to share between handlers for the lifetime of the request.

Here's an example where one handler sets some data in the context data and a subsequent handler retrieves it:

You can use the `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#put-java.lang.String-java.lang.Object-[put]` to put any object, and
`link:../../apidocs/io/vertx/ext/web/RoutingContext.html#get-java.lang.String-[get]` to retrieve any object from the context data.

A request sent to path `/some/path/other` will match both routes.

[source,java]
----
router.get("/some/path").handler(ctx -> {

  ctx.put("foo", "bar");
  ctx.next();

});

router.get("/some/path/other").handler(ctx -> {

  String bar = ctx.get("foo");
  // Do something with bar
  ctx.response().end();

});
----

Alternatively you can access the entire context data map with `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#data--[data]`.

== Metadata

While the context allows you to store data during the request-response lifecycle, there are times it is important to
have runtime metadata available. For example, to build API documentation, or to hold specific configuration for a given
route.

The metadata functionality works similarly to the context data. You can either access the holding `Map` or use the
dedicated getter and setter defined both on the `Router` and `Route` interfaces:

[source,java]
----
router
  .route("/metadata/route")
  .putMetadata("metadata-key", "123")
  .handler(ctx -> {
    Route route = ctx.currentRoute();
    String value = route.getMetadata("metadata-key"); // 123
    // will end the request with the value 123
    ctx.end(value);
  });
----


== Helper functions

While the routing context will allow you to access the underlying request and response objects, sometimes it will be
more productive if a few shortcuts would be present to help with common tasks. A few helpers are present in the context
to facilitate with this task.

Serve an "attachment", an attachment is a response that will trigger the browser to open the response on the OS
application configured to handle a specific mime type. Imagine you're generating a PDF:

[source,java]
----
ctx
  .attachment("weekly-report.pdf")
  .end(pdfBuffer);
----

Perform a redirect to a different page or host. One example is to redirect to an HTTPS variant of the application:

[source,java]
----
ctx.redirect("https://securesite.com/");

// there is a special handling for the target "back".
// In this case the redirect would send the user to the
// referrer url or "/" if there's no referrer.

ctx.redirect("back");
----

Send a JSON response to the client:

[source,java]
----
ctx.json(new JsonObject().put("hello", "vert.x"));
// also applies to arrays
ctx.json(new JsonArray().add("vertx").add("web"));
// or any object that will be converted according
// to the json encoder available at runtime.
ctx.json(someObject);
----

Simple content type check:

[source,java]
----
ctx.is("html"); // => true
ctx.is("text/html"); // => true

// When Content-Type is application/json
ctx.is("application/json"); // => true
ctx.is("html"); // => false
----

Verify if a request is "fresh" with respect to the cache headers and the current values of last modified/ etag.

[source,java]
----
ctx.lastModified("Wed, 13 Jul 2011 18:30:00 GMT");
// this will now be used to verify the freshness of the request
if (ctx.isFresh()) {
  // client cache value is fresh perhaps we
  // can stop and return 304?
}
----

And a few other simple self explanatory shortcuts:

[source,java]
----
ctx.etag("W/123456789");

// set the last modified value
ctx.lastModified("Wed, 13 Jul 2011 18:30:00 GMT");

// quickly end
ctx.end();
ctx.end("body");
ctx.end(buffer);
----


== Reroute

Until now all routing mechanism allow you to handle your requests in a sequential way, however there might be times
where you will want to go back. Since the context does not expose any information about the previous or next handler,
mostly because this information is dynamic there is a way to restart the whole routing from the start of the current
Router.

[source,java]
----
router.get("/some/path").handler(ctx -> {

  ctx.put("foo", "bar");
  ctx.next();

});

router
  .get("/some/path/B")
  .handler(ctx -> ctx.response().end());

router
  .get("/some/path")
  .handler(ctx -> ctx.reroute("/some/path/B"));
----

So from the code you can see that if a request arrives at `/some/path` if first add a value to the context, then
moves to the next handler that re routes the request to `/some/path/B` which terminates the request.

You can reroute based on a new path or based on a new path and method. Note however that rerouting based on method
might introduce security issues since for example a usually safe GET request can become a DELETE.

Reroute is also allowed on the failure handler, however due to the nature of re router when called the current status
code and failure reason are reset. In order the rerouted handler should generate the correct status code if needed,
for example:

[source,java]
----
router.get("/my-pretty-notfound-handler").handler(ctx -> ctx.response()
  .setStatusCode(404)
  .end("NOT FOUND fancy html here!!!"));

router.get().failureHandler(ctx -> {
  if (ctx.statusCode() == 404) {
    ctx.reroute("/my-pretty-notfound-handler");
  } else {
    ctx.next();
  }
});
----

It should be clear that reroute works on `paths`, so if you need to preserve and or add state across reroutes, one
should use the `RoutingContext` object. For example you want to reroute to a new path with a extra parameter:

[source,java]
----
router.get("/final-target").handler(ctx -> {
  // continue from here...
});

// (Will reroute to /final-target including the query string)
router.get().handler(ctx -> ctx.reroute("/final-target?variable=value"));

// A safer way would be to add the variable to the context
router.get().handler(ctx -> ctx
  .put("variable", "value")
  .reroute("/final-target"));
----

Reroute will re-parse the query params too. Be aware that previously query params will be discarded. The method
will also silently discard and ignore any html fragment from the path. This is to keep the semantics of reroute
consistent between a regular request and a re route.

If more information is required to be passed to the new request, it should use the context that is preserved all the
lifetime of the HTTP transaction.


== Sub-routers

Sometimes if you have a lot of handlers it can make sense to split them up into multiple routers. This is also useful
if you want to reuse a set of handlers in a different application, rooted at a different path root.

To do this you can mount a router at a _mount point_ in another router. The router that is mounted is called a
_sub-router_. Sub routers can mount other sub routers so you can have several levels of sub-routers if you like.

Let's look at a simple example of a sub-router mounted with another router.

This sub-router will maintain the set of handlers that corresponds to a simple fictional REST API. We will mount that on another
router. The full implementation of the REST API is not shown.

Here's the sub-router:

[source,java]
----
Router restAPI = Router.router(vertx);

restAPI.get("/products/:productID").handler(ctx -> {

  // TODO Handle the lookup of the product....
  ctx.response().write(productJSON);

});

restAPI.put("/products/:productID").handler(ctx -> {

  // TODO Add a new product...
  ctx.response().end();

});

restAPI.delete("/products/:productID").handler(ctx -> {

  // TODO delete the product...
  ctx.response().end();

});
----

If this router was used as a top level router, then GET/PUT/DELETE requests to urls like `/products/product1234`
would invoke the  API.

However, let's say we already have a web-site as described by another router:

[source,java]
----
Router mainRouter = Router.router(vertx);

// Handle static resources
mainRouter.route("/static/*").handler(myStaticHandler);

mainRouter.route(".*\\.templ").handler(myTemplateHandler);
----

We can now mount the sub router on the main router, against a mount point, in this case `/productsAPI`

[source,java]
----
mainRouter.route("/productsAPI/*")
  .subRouter(restAPI);
----

This means the REST API is now accessible via paths like: `/productsAPI/products/product1234`.

There are a couple of rules that must be fulfilled before sub routers can be used:

* The route path must end with a wild card
* Parameters are allowed but full regex patterns not
* Only 1 handler can be registered before or after this call (but they can on a new route object for the same path)
* Only 1 router per path object

Validation happens at the time the router is added to the http server. This means that you cannot get any validation
error during the build time because of the dynamic nature of sub routers. They depend on the context to be validated.

== Localization

Vert.x Web parses the `Accept-Language` header and provides some helper methods to identify which is the preferred
locale for a client or the sorted list of preferred locales by quality.

[source,java]
----
Route route = router.get("/localized").handler(ctx -> {
  // although it might seem strange by running a loop with a switch we
  // make sure that the locale order of preference is preserved when
  // replying in the users language.
  for (LanguageHeader language : ctx.acceptableLanguages()) {
    switch (language.tag()) {
      case "en":
        ctx.response().end("Hello!");
        return;
      case "fr":
        ctx.response().end("Bonjour!");
        return;
      case "pt":
        ctx.response().end("Olá!");
        return;
      case "es":
        ctx.response().end("Hola!");
        return;
    }
  }
  // we do not know the user language so lets just inform that back:
  ctx.response().end("Sorry we don't speak: " + ctx.preferredLanguage());
});
----

The main method `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#acceptableLanguages--[acceptableLanguages]` will return the ordered list of locales the
user understands, if you're only interested in the user prefered locale then the helper:
`link:../../apidocs/io/vertx/ext/web/RoutingContext.html#preferredLanguage--[preferredLanguage]` will return the 1st element of the list or `null` if no
locale was provided by the user.

== Route match failures

If no routes match for any particular request, Vert.x-Web will signal an error depending on match failure:

* 404 If no route matches the path
* 405 If a route matches the path but don't match the HTTP Method
* 406 If a route matches the path and the method but It can't provide a response with a content type matching `Accept` header
* 415 If a route matches the path and the method but It can't accept the `Content-type`
* 400 If a route matches the path and the method but It can't accept an empty body

You can manually manage those failures using `link:../../apidocs/io/vertx/ext/web/Router.html#errorHandler-int-io.vertx.core.Handler-[errorHandler]`

== Error handling

As well as setting handlers to handle requests you can also set handlers to handle failures in routing.

Failure handlers are used with the exact same route matching criteria that you use with normal handlers.

For example you can provide a failure handler that will only handle failures on certain paths, or for certain HTTP methods.

This allows you to set different failure handlers for different parts of your application.

Here's an example failure handler that will only be called for failure that occur when routing to GET requests
to paths that start with `/somepath/`:

[source,java]
----
Route route = router.get("/somepath/*");

route.failureHandler(ctx -> {

  // This will be called for failures that occur
  // when routing requests to paths starting with
  // '/somepath/'

});
----

Failure routing will occur if a handler throws an exception, or if a handler calls
`link:../../apidocs/io/vertx/ext/web/RoutingContext.html#fail-int-[fail]` specifying an HTTP status code to deliberately signal a failure.

If an exception is caught from a handler this will result in a failure with status code `500` being signalled.

When handling the failure, the failure handler is passed the routing context which also allows the failure or failure code
to be retrieved so the failure handler can use that to generate a failure response.

[source,java]
----
Route route1 = router.get("/somepath/path1/");

route1.handler(ctx -> {

  // Let's say this throws a RuntimeException
  throw new RuntimeException("something happened!");

});

Route route2 = router.get("/somepath/path2");

route2.handler(ctx -> {

  // This one deliberately fails the request passing in the status code
  // E.g. 403 - Forbidden
  ctx.fail(403);

});

// Define a failure handler
// This will get called for any failures in the above handlers
Route route3 = router.get("/somepath/*");

route3.failureHandler(failureRoutingContext -> {

  int statusCode = failureRoutingContext.statusCode();

  // Status code will be 500 for the RuntimeException
  // or 403 for the other failure
  HttpServerResponse response = failureRoutingContext.response();
  response.setStatusCode(statusCode).end("Sorry! Not today");

});
----

For the eventuality that an error occurs when running the error handler related usage of not allowed characters in
status message header, then the original status message will be changed to the default message from the error code.
This is a tradeoff to keep the semantics of the HTTP protocol working instead of abruptly creash and close the socket
without properly completing the protocol.

== Request body handling

The `link:../../apidocs/io/vertx/ext/web/handler/BodyHandler.html[BodyHandler]` allows you to retrieve request bodies, limit body sizes and handle
file uploads.

You should make sure a body handler is on a matching route for any requests that require this functionality.

The usage of this handler requires that it is installed as soon as possible. The handler will resume the
`link:../../apidocs/io/vertx/core/http/HttpServerRequest.html[HttpServerRequest]` processing, since it installs handlers to consume the HTTP request body.

[source,java]
----
router.route().handler(BodyHandler.create());
----

NOTE: Uploads can be a source of DDoS attacks, in order to reduce the attack surface, it is recommended to
set sensible limits on `link:../../apidocs/io/vertx/ext/web/handler/BodyHandler.html#setBodyLimit-long-[setBodyLimit]` (e.g.: 10mb for general uploads or
100kb for JSON).

=== Getting the request body

If you know the request body is JSON, then you can use `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#getBodyAsJson-int-[getBodyAsJson]`,
if you know it's a string you can use `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#getBodyAsString--[getBodyAsString]`, or to
retrieve it as a buffer use `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#getBody--[getBody]`.

=== Limiting body size

To limit the size of a request body, create the body handler then use `link:../../apidocs/io/vertx/ext/web/handler/BodyHandler.html#setBodyLimit-long-[setBodyLimit]`
to specifying the maximum body size, in bytes. This is useful to avoid running out of memory with very large bodies.

If an attempt to send a body greater than the maximum size is made, an HTTP status code of 413 - `Request Entity Too Large`,
will be sent.

There is no body limit by default.

=== Merging form attributes

By default, the body handler will merge any form attributes into the request parameters. If you don't want this behaviour
you can use disable it with `link:../../apidocs/io/vertx/ext/web/handler/BodyHandler.html#setMergeFormAttributes-boolean-[setMergeFormAttributes]`.

=== Handling file uploads

Body handler is also used to handle multi-part file uploads.

If a body handler is on a matching route for the request, any file uploads will be automatically streamed to the
uploads directory, which is `file-uploads` by default.

Each file will be given an automatically generated file name, and the file uploads will be available on the routing
context with `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#fileUploads--[fileUploads]`.

Here's an example:

[source,java]
----
router.route().handler(BodyHandler.create());

router.post("/some/path/uploads").handler(ctx -> {

  List<FileUpload> uploads = ctx.fileUploads();
  // Do something with uploads....

});
----

Each file upload is described by a `link:../../apidocs/io/vertx/ext/web/FileUpload.html[FileUpload]` instance, which allows various properties
such as the name, file-name and size to be accessed.

== Handling cookies

Vert.x-Web has out of the box cookies support.

=== Manipulating cookies

You use `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#getCookie-java.lang.String-[getCookie]` to retrieve
a cookie by name, or use `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#cookieMap--[cookieMap]` to retrieve the entire set.

To remove a cookie, use `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#removeCookie-java.lang.String-[removeCookie]`.

To add a cookie use `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#addCookie-io.vertx.core.http.Cookie-[addCookie]`.

The set of cookies will be written back in the response automatically when the response headers are written so the
browser can store them.

Cookies are described by instances of `link:../../apidocs/io/vertx/core/http/Cookie.html[Cookie]`. This allows you to retrieve the name,
value, domain, path and other normal cookie properties.

Here's an example of querying and adding cookies:

[source,java]
----
Cookie someCookie = ctx.request().getCookie("mycookie");
String cookieValue = someCookie.getValue();

// Do something with cookie...

// Add a cookie - this will get written back in the response automatically
ctx.response().addCookie(Cookie.cookie("othercookie", "somevalue"));
----

== Handling sessions

Vert.x-Web provides out of the box support for sessions.

Sessions last between HTTP requests for the length of a browser session and give you a place where you can add
session-scope information, such as a shopping basket.

Vert.x-Web uses session cookies to identify a session. The session cookie is temporary and will be deleted by your browser
when it's closed.

We don't put the actual data of your session in the session cookie - the cookie simply uses an identifier to look-up
the actual session on the server. The identifier is a random UUID generated using a secure random, so it should
be effectively unguessable.

Cookies are passed across the wire in HTTP requests and responses so it's always wise to make sure you are using
HTTPS when sessions are being used. Vert.x will warn you if you attempt to use sessions over straight HTTP.

To enable sessions in your application you must have a `link:../../apidocs/io/vertx/ext/web/handler/SessionHandler.html[SessionHandler]`
on a matching route before your application logic.

The session handler handles the creation of session cookies and the lookup of the session, so you don't have to do
that yourself.

Sessions data is saved to a session store automatically after the response headers have been sent to the client.
But note that, with this mechanism, there is no guarantee the data is fully persisted before the client receives the response.
There are occasions though when this guarantee is needed.
In this case you can force a flush.
This will disable the automatic saving process, unless the flushing operation failed.
This allows to control the state before completing the response like:

[source,java]
----
ChainAuthHandler chain =
  ChainAuthHandler.any()
    .add(authNHandlerA)
    .add(ChainAuthHandler.all()
      .add(authNHandlerB)
      .add(authNHandlerC));

// secure your route
router.route("/secure/resource").handler(chain);
// your app
router.route("/secure/resource").handler(ctx -> {
  // do something...
});
----

Vert.x Session Handler state by default uses a cookie to store session ID. Session ID is a unique string, used to
recognize individual visitor between visits. But, if client's web browser doesn't support cookies or visitor has
disabled cookies in web browser's settings, we can't store session id on client's machine. In this case, new session
will be created for every request. This behavior is useless because we can't remember information for certain visitor
between two requests. We can say that, by default, sessions can't work if browser doesn't support cookies.

Vert.x Web supports sessions without cookies, known as "cookieless" sessions. As an alternative, Vert.x Web can embed
session id inside of page URL. On this way, all page links will contain session id string. When visitor clicks on some
of these links, it will read session id from page URL, so we don't need cookies support to have functional sessions.

To enable cookieless sessions:

[source,java]
----
router.route()
  .handler(SessionHandler.create(store).setCookieless(true));
----

It is important to know that in this mode the session ID should be passed by the application to the end user, usually by
rendering it on the HTML page or script. There are some important rules. The session id is identified by the following
pattern on the path `/optional/path/prefix/'('sessionId')'/path/suffix`.

As an example, given the path: `http://localhost:2677/WebSite1/(S(3abhbgwjg33aqrt3uat2kh4d))/api/` the session Id will
be: `3abhbgwjg33aqrt3uat2kh4d`.

Main security problem when working with sessions is a possibility that malicious user will find out others' session id.
If two users share same session id, they share same session variables too and website is considering them as one
visitor. This could be a security risk if session is used for any private or sensitive data, or to allow access to
restricted areas of web site. When cookies are used, session id can be protected using SSL and by marking a cookie as
secure. But, in case of cookieless session, session id is part of URL and is much more vulnerable.


=== Session stores

To create a session handler you need to have a session store instance. The session store is the object that
holds the actual sessions for your application.

The session store is responsible for holding a secure pseudo random number generator in order to guarantee secure session
ids. This PRNG is independent of the store which means that given a session id from store A one cannot derive the
session id of store B since they have different seeds and states.

By default this PRNG uses a mixed mode, blocking for seeding, non blocking for generating. The PRNG will also reseed
every 5 minutes with 64bits of new entropy. However this can all be configured using the system properties:

* io.vertx.ext.auth.prng.algorithm e.g.: SHA1PRNG
* io.vertx.ext.auth.prng.seed.interval e.g.: 1000 (every second)
* io.vertx.ext.auth.prng.seed.bits e.g.: 128

Most users should not need to configure these values unless if you notice that the performance of your application is
being affected by the PRNG algorithm.

Vert.x-Web comes with two session store implementations out of the box, and you can also write your own if you prefer.

The implementations are expected to follow the `ServiceLoader` conventions and all stores that are available at runtime
from the classpath will be exposed. When more than 1 implementations are available the first one that can be
instantiated and configured with success becomes the default. If none is available, then the default depends on the mode
Vert.x was created. If cluster mode is available the the clustered session store is the default otherwise the local
storage is the default.

==== Local session store

With this store, sessions are stored locally in memory and only available in this instance.

This store is appropriate if you have just a single Vert.x instance of you are using sticky sessions in your application
and have configured your load balancer to always route HTTP requests to the same Vert.x instance.

If you can't ensure your requests will all terminate on the same server then don't use this store as your
requests might end up on a server which doesn't know about your session.

Local session stores are implemented by using a shared local map, and have a reaper which clears out expired sessions.

The reaper interval can be configured with a json message with the key: `reaperInterval`.

Here are some examples of creating a local `link:../../apidocs/io/vertx/ext/web/sstore/SessionStore.html[SessionStore]`

[source,java]
----
SessionStore store1 = LocalSessionStore.create(vertx);

// Create a local session store specifying the local shared map name to use
// This might be useful if you have more than one application in the same
// Vert.x instance and want to use different maps for different applications
SessionStore store2 = LocalSessionStore.create(
  vertx,
  "myapp3.sessionmap");

// Create a local session store specifying the local shared map name to use and
// setting the reaper interval for expired sessions to 10 seconds
SessionStore store3 = LocalSessionStore.create(
  vertx,
  "myapp3.sessionmap",
  10000);
----

==== Clustered session store

With this store, sessions are stored in a distributed map which is accessible across the Vert.x cluster.

This store is appropriate if you're _not_ using sticky sessions, i.e. your load balancer is distributing different
requests from the same browser to different servers.

Your session is accessible from any node in the cluster using this store.

To you use a clustered session store you should make sure your Vert.x instance is clustered.

Here are some examples of creating a clustered `link:../../apidocs/io/vertx/ext/web/sstore/SessionStore.html[SessionStore]`

[source,java]
----
Vertx.clusteredVertx(new VertxOptions(), res -> {

  Vertx vertx = res.result();

  // Create a clustered session store using defaults
  SessionStore store1 = ClusteredSessionStore.create(vertx);

  // Create a clustered session store specifying the distributed map name to use
  // This might be useful if you have more than one application in the cluster
  // and want to use different maps for different applications
  SessionStore store2 = ClusteredSessionStore.create(
    vertx,
    "myclusteredapp3.sessionmap");
});
----

==== Other stores

Other stores are also available, these stores can be used by importing the correct jar
to the project. One example of such stores is the cookie store. This store has the advantage
that it requires no backend or server side state, which can be useful it some situations
**BUT** all session data will be sent back to the client in the Cookie, so if you need to store
private information this should not be used.

This store is appropriate if you're using sticky sessions, i.e. your load balancer is
distributing different requests from the same browser to different servers.

As the session is stored in the Cookie, this means sessions survive server crashes too.

A second known implementation is the Redis session store. This store works just like the normal cluster store, however
just like its name suggests, it uses a redis backend to keep the session data centralized.

Also, there is the Infinispan session store (details below).

These stores are available with the coordinates:

* groupId: `io.vertx`
* artifactId: `vertx-web-sstore-{cookie|redis|infinispan}`

include::web-sstore-infinispan.adoc[leveloffset=+4]

=== Creating the session handler

Once you've created a session store you can create a session handler, and add it to a route. You should make sure
your session handler is routed to before your application handlers.

Here's an example:

[source,java]
----
Router router = Router.router(vertx);

// Create a clustered session store using defaults
SessionStore store = ClusteredSessionStore.create(vertx);

SessionHandler sessionHandler = SessionHandler.create(store);

// the session handler controls the cookie used for the session
// this includes configuring, for example, the same site policy
// like this, for strict same site policy.
sessionHandler.setCookieSameSite(CookieSameSite.STRICT);

// Make sure all requests are routed through the session handler too
router.route().handler(sessionHandler);

// Now your application handlers
router.route("/somepath/blah/").handler(ctx -> {

  Session session = ctx.session();
  session.put("foo", "bar");
  // etc

});
----

The session handler will ensure that your session is automatically looked up (or created if no session exists)
from the session store and set on the routing context before it gets to your application handlers.

By default, the session handler will always add a session cookie to the HTTP response, even if the session has not been
accessed by your application. To create the session cookie only when the session has been used, use
`sessionHandler.setLazySession(true)`.

=== Using the session

In your handlers you can access the session instance with `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#session--[session]`.

You put data into the session with `link:../../apidocs/io/vertx/ext/web/Session.html#put-java.lang.String-java.lang.Object-[put]`,
you get data from the session with `link:../../apidocs/io/vertx/ext/web/Session.html#get-java.lang.String-[get]`, and you remove
data from the session with `link:../../apidocs/io/vertx/ext/web/Session.html#remove-java.lang.String-[remove]`.

The keys for items in the session are always strings. The values can be any type for a local session store, and for
a clustered session store they can be any basic type, or `link:../../apidocs/io/vertx/core/buffer/Buffer.html[Buffer]`, `link:../../apidocs/io/vertx/core/json/JsonObject.html[JsonObject]`,
`link:../../apidocs/io/vertx/core/json/JsonArray.html[JsonArray]` or a serializable object, as the values have to serialized across the cluster.

Here's an example of manipulating session data:

[source,java]
----
router.route().handler(sessionHandler);

// Now your application handlers
router.route("/somepath/blah").handler(ctx -> {

  Session session = ctx.session();

  // Put some data from the session
  session.put("foo", "bar");

  // Retrieve some data from a session
  int age = session.get("age");

  // Remove some data from a session
  JsonObject obj = session.remove("myobj");

});
----

Sessions are automatically written back to the store after responses are complete.

You can manually destroy a session using `link:../../apidocs/io/vertx/ext/web/Session.html#destroy--[destroy]`. This will remove the session
from the context and the session store. Note that if there is no session a new one will be automatically created
for the next request from the browser that's routed through the session handler.

=== Session timeout

Sessions will be automatically timed out if they are not accessed for a time greater than the timeout period. When
a session is timed out, it is removed from the store.

Sessions are automatically marked as accessed when a request arrives and the session is looked up and and when the
response is complete and the session is stored back in the store.

You can also use `link:../../apidocs/io/vertx/ext/web/Session.html#setAccessed--[setAccessed]` to manually mark a session as accessed.

The session timeout can be configured when creating the session handler. Default timeout is 30 minutes.

== Authentication / authorization

Vert.x comes with some out-of-the-box handlers for handling both authentication and authorization. In vert.x web
the meanings for the 2 words are:

* *Authentication* - Tells who the user is
* *Authorization* - Tells what the user is allowed to do

While *Authentication* is tightened to a well known protocol, e.g.:

* HTTP Basic Authentication
* HTTP Digest Authentication
* OAuth2 Authentication
* ...

*Authorization* in vert.x is quite generic and can be used regardless of the prior. Yet it is also possible and a valid
use case to use the same provider module for both cases.

=== Creating an Authentication handler

To create an auth handler you need an instance of `link:../../apidocs/io/vertx/ext/auth/authentication/AuthenticationProvider.html[AuthenticationProvider]`.
Authentication provider is used for authentication of users. Vert.x provides several authentication provider instances
out of the box in the vertx-auth project. For full information on auth providers and how to use and configure them
please consult the auth documentation.

Here's a simple example of creating a basic auth handler given an auth provider.

[source,java]
----
router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)));

AuthenticationHandler basicAuthHandler = BasicAuthHandler.create(authProvider);
----

=== Handling authentication in your application

Let's say you want all requests to paths that start with `/private/` to be subject to authentication. To do that you
make sure your authentication handler is before your application handlers on those paths:

[source,java]
----
router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)));

AuthenticationHandler basicAuthHandler = BasicAuthHandler.create(authProvider);

// All requests to paths starting with '/private/' will be protected
router.route("/private/*").handler(basicAuthHandler);

router.route("/someotherpath").handler(ctx -> {

  // This will be public access - no login required

});

router.route("/private/somepath").handler(ctx -> {

  // This will require a login

  // This will have the value true
  boolean isAuthenticated = ctx.user() != null;

});
----

If the authentication handler has successfully authenticated the user it will inject a `link:../../apidocs/io/vertx/ext/auth/User.html[User]`
object into the `link:../../apidocs/io/vertx/ext/web/RoutingContext.html[RoutingContext]` so it's available in your handlers with:
`link:../../apidocs/io/vertx/ext/web/RoutingContext.html#user--[user]`.

If you want your User object to be stored in the session so it's available between requests so you don't have to
authenticate on each request, then you should make sure you have a session handler before the authentication handler.

Once you have your user object you can also programmatically use the methods on it to authorize the user.

If you want to cause the user to be logged out you can call `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#clearUser--[clearUser]`
on the routing context.

=== HTTP Basic Authentication

http://en.wikipedia.org/wiki/Basic_access_authentication[HTTP Basic Authentication] is a simple means of authentication
that can be appropriate for simple applications.

With basic authentication, credentials are sent unencrypted across the wire in HTTP headers so it's essential that you
serve your application using HTTPS not HTTP.

With basic authentication, if a user requests a resource that requires authentication, the basic auth handler will send
back a `401` response with the header `WWW-Authenticate` set. This prompts the browser to show a log-in dialogue and
prompt the user to enter their username and password.

The request is made to the resource again, this time with the `Authorization` header set, containing the username
and password encoded in Base64.

When the basic auth handler receives this information, it calls the configured `link:../../apidocs/io/vertx/ext/auth/authentication/AuthenticationProvider.html[AuthenticationProvider]`
with the username and password to authenticate the user. If the authentication is successful then the routing of the
request is allowed to continue to the application handlers, otherwise a `403` response is returned to signify that
access is denied.

=== Redirect authentication handler

With redirect authentication handling the user is redirected to towards a login page in the case they are trying to
access a protected resource and they are not logged in.

The user then fills in the login form and submits it. This is handled by the server which authenticates
the user and, if authenticated redirects the user back to the original resource.

To use redirect auth you configure an instance of `link:../../apidocs/io/vertx/ext/web/handler/RedirectAuthHandler.html[RedirectAuthHandler]` instead of a
basic authentication handler.

You will also need to setup handlers to serve your actual login page, and a handler to handle the actual login itself.
To handle the login we provide a prebuilt handler `link:../../apidocs/io/vertx/ext/web/handler/FormLoginHandler.html[FormLoginHandler]` for the purpose.

Here's an example of a simple app, using a redirect auth handler on the default redirect url `/loginpage`.

[source,java]
----
router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)));

// All requests to paths starting with '/private/' will be protected
router
  .route("/private/*")
  .handler(RedirectAuthHandler.create(authProvider));

// Handle the actual login
// One of your pages must POST form login data
router.post("/login").handler(FormLoginHandler.create(authProvider));

// Set a static server to serve static resources, e.g. the login page
router.route().handler(StaticHandler.create());

router
  .route("/someotherpath")
  .handler(ctx -> {
    // This will be public access - no login required
  });

router
  .route("/private/somepath")
  .handler(ctx -> {

    // This will require a login

    // This will have the value true
    boolean isAuthenticated = ctx.user() != null;

  });
----

=== JWT authentication

With JWT authentication resources can be protected by means of permissions and users without enough rights are denied
access. You need to add the `io.vertx:vertx-auth-jwt:4.3.5` dependency to use `JWTAuthProvider`

To use this handler there are 2 steps involved:

* Setup an handler to issue tokens (or rely on a 3rd party)
* Setup the handler to filter the requests

Please note that these 2 handlers should be only available on HTTPS, not doing so allows sniffing the tokens in
transit which leads to session hijacking attacks.

Here's an example on how to issue tokens:

[source,java]
----
Router router = Router.router(vertx);

JWTAuthOptions authConfig = new JWTAuthOptions()
  .setKeyStore(new KeyStoreOptions()
    .setType("jceks")
    .setPath("keystore.jceks")
    .setPassword("secret"));

JWTAuth jwt = JWTAuth.create(vertx, authConfig);

router.route("/login").handler(ctx -> {
  // this is an example, authentication should be done with another provider...
  if (
    "paulo".equals(ctx.request().getParam("username")) &&
      "secret".equals(ctx.request().getParam("password"))) {
    ctx.response()
      .end(jwt.generateToken(new JsonObject().put("sub", "paulo")));
  } else {
    ctx.fail(401);
  }
});
----

Now that your client has a token all it is required is that *for all* consequent request the HTTP header
`Authorization` is filled with: `Bearer <token>` e.g.:

[source,java]
----
Router router = Router.router(vertx);

JWTAuthOptions authConfig = new JWTAuthOptions()
  .setKeyStore(new KeyStoreOptions()
    .setType("jceks")
    .setPath("keystore.jceks")
    .setPassword("secret"));

JWTAuth authProvider = JWTAuth.create(vertx, authConfig);

router.route("/protected/*").handler(JWTAuthHandler.create(authProvider));

router.route("/protected/somepage").handler(ctx -> {
  // some handle code...
});
----

JWT allows you to add any information you like to the token itself. By doing this there is no state in the server
which allows you to scale your applications without need for clustered session data. In order to add data to the
token, during the creation of the token just add data to the JsonObject parameter:

[source,java]
----
JWTAuthOptions authConfig = new JWTAuthOptions()
  .setKeyStore(new KeyStoreOptions()
    .setType("jceks")
    .setPath("keystore.jceks")
    .setPassword("secret"));

JWTAuth authProvider = JWTAuth.create(vertx, authConfig);

authProvider
  .generateToken(
    new JsonObject()
      .put("sub", "paulo")
      .put("someKey", "some value"),
    new JWTOptions());
----

And the same when consuming:

[source,java]
----
Handler<RoutingContext> handler = ctx -> {
  String theSubject = ctx.user().principal().getString("sub");
  String someKey = ctx.user().principal().getString("someKey");
};
----

=== Configuring authorization

Until now all examples were covering authentication. Authorization is the next logical step when dealing with user.
While authentication was really specific to the protocol, *authorization* is independent, all information is extracted
from the `User` object.

Before this is possible there is a need to load the authorizations to this same object. In order to do this the
`link:../../apidocs/io/vertx/ext/web/handler/AuthorizationHandler.html[AuthorizationHandler]` should be used. An authorization handler will load all known
authorizations from a given `link:../../apidocs/io/vertx/ext/auth/authorization/AuthorizationProvider.html[AuthorizationProvider]`.

[source,java]
----
router.route().handler(
  // create the handler that will perform the attestation
  AuthorizationHandler.create(
      // what to attest
      PermissionBasedAuthorization.create("can-do-work"))
    // where to lookup the authorizations for the user
    .addAuthorizationProvider(authProvider));
----

The lookup can be performed on more than 1 source, just keep adding `addAuthorizationProvider(provider)` to the handler.

Here's an example of configuring an app so that different authorities are required for different parts of the
app. Note that the meaning of the authorities is determined by the underlying auth provider that you use. E.g. some
may support a role/permission based model but others might use another model.

[source,java]
----
router.route("/listproducts/*").handler(
  // create the handler that will perform the attestation
  AuthorizationHandler.create(
      // what to attest
      PermissionBasedAuthorization.create("list_products"))
    // where to lookup the authorizations for the user
    .addAuthorizationProvider(authProvider));

// Only "admin" has access to /private/settings
router.route("/private/settings/*").handler(
  // create the handler that will perform the attestation
  AuthorizationHandler.create(
      // what to attest
      RoleBasedAuthorization.create("admin"))
    .addAuthorizationProvider(authProvider));
----

=== Chaining multiple authentication handlers

There are times when you want to support multiple authentication mechanisms in a single application. For this you can
use the `link:../../apidocs/io/vertx/ext/web/handler/ChainAuthHandler.html[ChainAuthHandler]`. The chain auth handler will attempt to perform
authentication on a chain of handlers.

It is important to know that some handlers require specific providers, for example:

* The `link:../../apidocs/io/vertx/ext/web/handler/JWTAuthHandler.html[JWTAuthHandler]` requires `link:../../apidocs/io/vertx/ext/auth/jwt/JWTAuth.html[JWTAuth]`.
* The `link:../../apidocs/io/vertx/ext/web/handler/DigestAuthHandler.html[DigestAuthHandler]` requires `link:../../apidocs/io/vertx/ext/auth/htdigest/HtdigestAuth.html[HtdigestAuth]`.
* The `link:../../apidocs/io/vertx/ext/web/handler/OAuth2AuthHandler.html[OAuth2AuthHandler]` requires `link:../../apidocs/io/vertx/ext/auth/oauth2/OAuth2Auth.html[OAuth2Auth]`.
* The `link:../../apidocs/io/vertx/ext/web/handler/WebAuthnHandler.html[WebAuthnHandler]` requires `link:../../apidocs/io/vertx/ext/auth/webauthn/WebAuthn.html[WebAuthn]`.

So it is not expected that the providers will be shared across all handlers. There are cases where one can share the
provider across handlers, for example:

* The `link:../../apidocs/io/vertx/ext/web/handler/BasicAuthHandler.html[BasicAuthHandler]` can take any provider.
* The `link:../../apidocs/io/vertx/ext/web/handler/RedirectAuthHandler.html[RedirectAuthHandler]` can take any provider.

So say that you want to create an application that accepts both `HTTP Basic Authentication` and `Form Redirect`. You
would start configuring your chain as:

[source,java]
----
ChainAuthHandler chain = ChainAuthHandler.any();

// add http basic auth handler to the chain
chain.add(BasicAuthHandler.create(provider));
// add form redirect auth handler to the chain
chain.add(RedirectAuthHandler.create(provider));

// secure your route
router.route("/secure/resource").handler(chain);
// your app
router.route("/secure/resource").handler(ctx -> {
  // do something...
});
----

So when a user makes a request without a `Authorization` header, this means that the chain will fail to authenticate
with the basic auth handler and will attempt to authenticate with the redirect handler. Since the redirect handler
always redirects you will be sent to the login form that you configured in that handler.

Like the normal routing in vertx-web, auth chaning is a sequence, so if you would prefer to fallback to your browser
asking for the user credentials using HTTP Basic authentication instead of the redirect all you need to to is reverse
the order of appending to the chain.

Now assume that you make a request where you provide the header `Authorization` with the value `Basic [token]`. In
this case the basic auth handler will attempt to authenticate and if it is sucessful the chain will stop and
vertx-web will continue to process your handlers. If the token is not valid, for example bad username/password, then
the chain will continue to the following entry. In this specific case the redirect auth handler.

Complex chaining is also possible, for example, building logic sequences such as: `HandlerA` OR (`HandlerB` AND `HandlerC`).

[source,java]
----
ChainAuthHandler chain =
  ChainAuthHandler.any()
    .add(authNHandlerA)
    .add(ChainAuthHandler.all()
      .add(authNHandlerB)
      .add(authNHandlerC));

// secure your route
router.route("/secure/resource").handler(chain);
// your app
router.route("/secure/resource").handler(ctx -> {
  // do something...
});
----

== Serving static resources

Vert.x-Web comes with an out of the box handler for serving static web resources so you can write static web servers
very easily.

To serve static resources such as `.html`, `.css`, `.js` or any other static resource, you use an instance of
`link:../../apidocs/io/vertx/ext/web/handler/StaticHandler.html[StaticHandler]`.

Any requests to paths handled by the static handler will result in files being served from a directory on the file system
or from the classpath. The default static file directory is `webroot` but this can be configured.

In the following example all requests to paths starting with `/static/` will get served from the directory `webroot`:

[source,java]
----
router.route("/static/*").handler(StaticHandler.create());
----

For example, if there was a request with path `/static/css/mystyles.css` the static serve will look for a file in the
directory `webroot/css/mystyle.css`.

It will also look for a file on the classpath called `webroot/css/mystyle.css`. This means you can package up all your
static resources into a jar file (or fatjar) and distribute them like that.

When Vert.x finds a resource on the classpath for the first time it extracts it and caches it in a temporary directory
on disk so it doesn't have to do this each time.

The handler will handle range aware requests. When a client makes a request to a static resource, the handler will
notify that it can handle range aware request by stating the unit on the `Accept-Ranges` header. Further requests
that contain the `Range` header with the correct unit and start and end indexes will then receive partial responses
with the correct `Content-Range` header.

=== Configuring caching

By default the static handler will set cache headers to enable browsers to effectively cache files.

Vert.x-Web sets the headers `cache-control`,`last-modified`, and `date`.

`cache-control` is set to `max-age=86400` by default. This corresponds to one day. This can be configured with
`link:../../apidocs/io/vertx/ext/web/handler/StaticHandler.html#setMaxAgeSeconds-long-[setMaxAgeSeconds]` if required.

If a browser sends a GET or a HEAD request with an `if-modified-since` header and the resource has not been modified
since that date, a `304` status is returned which tells the browser to use its locally cached resource.

If handling of cache headers is not required, it can be disabled with `link:../../apidocs/io/vertx/ext/web/handler/StaticHandler.html#setCachingEnabled-boolean-[setCachingEnabled]`.

When cache handling is enabled Vert.x-Web will cache the last modified date of resources in memory, this avoids a disk hit
to check the actual last modified date every time.

Entries in the cache have an expiry time, and after that time, the file on disk will be checked again and the cache
entry updated.

If you know that your files never change on disk, then the cache entry will effectively never expire. This is the
default.

If you know that your files might change on disk when the server is running then you can set files read only to false with
`link:../../apidocs/io/vertx/ext/web/handler/StaticHandler.html#setFilesReadOnly-boolean-[setFilesReadOnly]`.

To enable the maximum number of entries that can be cached in memory at any one time you can use
`link:../../apidocs/io/vertx/ext/web/handler/StaticHandler.html#setMaxCacheSize-int-[setMaxCacheSize]`.

To configure the expiry time of cache entries you can use `link:../../apidocs/io/vertx/ext/web/handler/StaticHandler.html#setCacheEntryTimeout-long-[setCacheEntryTimeout]`.

=== Configuring the index page

Any requests to the root path `/` will cause the index page to be served. By default the index page is `index.html`.
This can be configured with `link:../../apidocs/io/vertx/ext/web/handler/StaticHandler.html#setIndexPage-java.lang.String-[setIndexPage]`.

=== Changing the web root

By default static resources will be served from the directory `webroot`. To configure this use
`link:../../apidocs/io/vertx/ext/web/handler/StaticHandler.html#setWebRoot-java.lang.String-[setWebRoot]`.

=== Serving hidden files

By default the serve will serve hidden files (files starting with `.`).

If you do not want hidden files to be served you can configure it with `link:../../apidocs/io/vertx/ext/web/handler/StaticHandler.html#setIncludeHidden-boolean-[setIncludeHidden]`.

=== Directory listing

The server can also perform directory listing. By default directory listing is disabled. To enabled it use
`link:../../apidocs/io/vertx/ext/web/handler/StaticHandler.html#setDirectoryListing-boolean-[setDirectoryListing]`.

When directory listing is enabled the content returned depends on the content type in the `accept` header.

For `text/html` directory listing, the template used to render the directory listing page can be configured with
`link:../../apidocs/io/vertx/ext/web/handler/StaticHandler.html#setDirectoryTemplate-java.lang.String-[setDirectoryTemplate]`.

=== Disabling file caching on disk

By default, Vert.x will cache files that are served from the classpath into a file on disk in a sub-directory of a
directory called `.vertx` in the current working directory. This is mainly useful when deploying services as
fatjars in production where serving a file from the classpath every time can be slow.

In development this can cause a problem, as if you update your static content while the server is running, the
cached file will be served not the updated file.

To disable file caching you can provide your vert.x options the property `fileResolverCachingEnabled` to `false`. For
backwards compatibility it will also default that value to the system property `vertx.disableFileCaching`. E.g. you
could set up a run configuration in your IDE to set this when running your main class.


== CORS handling

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing[Cross Origin Resource Sharing] is a safe mechanism for
allowing resources to be requested from one domain and served from another.

Vert.x-Web includes a handler `link:../../apidocs/io/vertx/ext/web/handler/CorsHandler.html[CorsHandler]` that handles the CORS protocol for you.

Here's an example:

[source,java]
----
router.route()
  .handler(
    CorsHandler.create("vertx\\.io")
      .allowedMethod(HttpMethod.GET));

router.route().handler(ctx -> {

  // Your app handlers

});
----

////
TODO more CORS docs
////

== Multi Tenant

There are cases where your application needs to handle more than just 1 tenant. In this case a helper handler is
provided that simplifies setting up the application.

In the case the tenant is identified by a HTTP header, say for example `X-Tenant`, then creating the handler is as
simple as:

[source,java]
----
router.route().handler(MultiTenantHandler.create("X-Tenant"));
----

You now should register what handler should be executed for the given tenant:

[source,java]
----
MultiTenantHandler.create("X-Tenant")
  .addTenantHandler("tenant-A", ctx -> {
    // do something for tenant A...
  })
  .addTenantHandler("tenant-B", ctx -> {
    // do something for tenant B...
  })
  // optionally
  .addDefaultHandler(ctx -> {
    // do something when no tenant matches...
  });
----

This is useful for security situations:

[source,java]
----
OAuth2Auth gitHubAuthProvider = GithubAuth
  .create(vertx, "CLIENT_ID", "CLIENT_SECRET");

// create a oauth2 handler on our running server
// the second argument is the full url to the callback
// as you entered in your provider management console.
OAuth2AuthHandler githubOAuth2 = OAuth2AuthHandler.create(
  vertx,
  gitHubAuthProvider,
  "https://myserver.com/github-callback");

// setup the callback handler for receiving the GitHub callback
githubOAuth2.setupCallback(router.route("/github-callback"));

// create an OAuth2 provider, clientID and clientSecret
// should be requested to Google
OAuth2Auth googleAuthProvider = OAuth2Auth.create(vertx, new OAuth2Options()
  .setClientId("CLIENT_ID")
  .setClientSecret("CLIENT_SECRET")
  .setSite("https://accounts.google.com")
  .setTokenPath("https://www.googleapis.com/oauth2/v3/token")
  .setAuthorizationPath("/o/oauth2/auth"));

// create a oauth2 handler on our domain: "http://localhost:8080"
OAuth2AuthHandler googleOAuth2 = OAuth2AuthHandler.create(
  vertx,
  googleAuthProvider,
  "https://myserver.com/google-callback");

// setup the callback handler for receiving the Google callback
googleOAuth2.setupCallback(router.route("/google-callback"));

// At this point the 2 callbacks endpoints are registered:

// /github-callback -> handle github Oauth2 callbacks
// /google-callback -> handle google Oauth2 callbacks

// As the callbacks are made by the IdPs there's no header
// to identify the source, hence the need of custom URLs

// However for out Application we can control it so later
// we can add the right handler for the right tenant

router.route().handler(
  MultiTenantHandler.create("X-Tenant")
    // tenants using github should go this way:
    .addTenantHandler("github", githubOAuth2)
    // tenants using google should go this way:
    .addTenantHandler("google", googleOAuth2)
    // all other should be forbidden
    .addDefaultHandler(ctx -> ctx.fail(401)));
----

The tenant id can be read at any moment from the context, for example to decide which resource to load, or which
database to connect to:

[source,java]
----
router.route().handler(ctx -> {
  // the default key is "tenant" as defined in
  // MultiTenantHandler.TENANT but this value can be
  // modified at creation time in the factory method
  String tenant = ctx.get(MultiTenantHandler.TENANT);

  switch (tenant) {
    case "google":
      // do something for google users
      break;
    case "github":
      // so something for github users
      break;
  }
});
----

Multi tenant is a powerful handler that will allow applications to live side by side, however it provides no sandboxing
for execution. It should not be used as isolation as wrongly written applications may leak state across tenants.

== Templates

Vert.x-Web includes dynamic page generation capabilities by including out of the box support for several popular template
engines. You can also easily add your own.

Template engines are described by `link:../../apidocs/io/vertx/ext/web/common/template/TemplateEngine.html[TemplateEngine]`. In order to render a template
`link:../../apidocs/io/vertx/ext/web/common/template/TemplateEngine.html#render-io.vertx.core.json.JsonObject-java.lang.String-io.vertx.core.Handler-[render]` is used.

The simplest way to use templates is not to call the template engine directly but to use the
`link:../../apidocs/io/vertx/ext/web/handler/TemplateHandler.html[TemplateHandler]`.
This handler calls the template engine for you based on the path in the HTTP request.

By default the template handler will look for templates in a directory called `templates`. This can be configured.

The handler will return the results of rendering with a content type of `text/html` by default. This can also be configured.

When you create the template handler you pass in an instance of the template engine you want. Template engines are
not embedded in vertx-web so, you need to configure your project to access them. Configuration is provided for
each template engine.

Here are some examples:

////
These examples are not using the traditional "transcoding" as they use an API providing in another project.
////

[source, java]
----
TemplateEngine engine = HandlebarsTemplateEngine.create();
TemplateHandler handler = TemplateHandler.create(engine);

// This will route all GET requests starting with /dynamic/ to the template handler
// E.g. /dynamic/graph.hbs will look for a template in /templates/graph.hbs
router.get("/dynamic/*").handler(handler);

// Route all GET requests for resource ending in .hbs to the template handler
router.getWithRegex(".+\\.hbs").handler(handler);
----








=== MVEL template engine

To use MVEL, you need to add the following _dependency_ to your project:
`io.vertx:vertx-web-templ-mvel:4.3.5`. Create an instance of the MVEL template engine using:
`io.vertx.ext.web.templ.mvel.MVELTemplateEngine#create(io.vertx.core.Vertx)`

When using the MVEL template engine, it will by default look for
templates with the `.templ` extension if no extension is specified in the file name.

The routing context `link:../../apidocs/io/vertx/ext/web/RoutingContext.html[RoutingContext]` is available
in the MVEL template as the `context` variable, this means you can render the template based on anything in the context
including the request, response, session or context data.

Here are some examples:

----
The request path is @{context.request().path()}

The variable 'foo' from the session is @{context.session().get('foo')}

The value 'bar' from the context data is @{context.get('bar')}
----

Please consult the http://mvel.documentnode.com/#mvel-2.0-templating-guide[MVEL templates documentation] for how to write
MVEL templates.

=== Jade template engine

To use the Jade template engine, you need to add the following _dependency_ to your project:
`io.vertx:vertx-web-templ-jade:4.3.5`. Create an instance of the Jade template engine using:
`io.vertx.ext.web.templ.jade.JadeTemplateEngine#create(io.vertx.core.Vertx)`.

When using the Jade template engine, it will by default look for
templates with the `.jade` extension if no extension is specified in the file name.

The routing context `link:../../apidocs/io/vertx/ext/web/RoutingContext.html[RoutingContext]` is available
in the Jade template as the `context` variable, this means you can render the template based on anything in the context
including the request, response, session or context data.

Here are some examples:

----
!!! 5
html
 head
   title= context.get('foo') + context.request().path()
 body
----

Please consult the https://github.com/neuland/jade4j[Jade4j documentation] for how to write
Jade templates.

=== Handlebars template engine

To use Handlebars, you need to add the following _dependency_ to your project:
`io.vertx:vertx-web-templ-handlebars:4.3.5`. Create an instance of the Handlebars template engine
using: `io.vertx.ext.web.templ.handlebars.HandlebarsTemplateEngine#create(io.vertx.core.Vertx)`.

When using the Handlebars template engine, it will by default look for
templates with the `.hbs` extension if no extension is specified in the file name.

Handlebars templates are not able to call arbitrary methods in objects so we can't just pass the routing context
into the template and let the template introspect it like we can with other template engines.

Instead, the context `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#data--[data]` is available in the template.

If you want to have access to other data like the request path, request params or session data you should
add it the context data in a handler before the template handler. For example:

[source,java]
----
TemplateHandler handler = TemplateHandler.create(engine);

router.get("/dynamic").handler(ctx -> {

  ctx.put("request_path", ctx.request().path());
  ctx.put("session_data", ctx.session().data());

  ctx.next();
});

router.get("/dynamic/").handler(handler);
----

Please consult the https://github.com/jknack/handlebars.java[Handlebars Java port documentation] for how to write
handlebars templates.

=== Thymeleaf template engine

To use Thymeleaf, you need to add the following _dependency_ to your project:
`io.vertx:vertx-web-templ-thymeleaf:4.3.5`. Create an instance of the Thymeleaf template engine
using: `io.vertx.ext.web.templ.thymeleaf.ThymeleafTemplateEngine#create(io.vertx.core.Vertx)`.

When using the Thymeleaf template engine, it will by default look for
templates with the `.html` extension if no extension is specified in the file name.

The routing context `link:../../apidocs/io/vertx/ext/web/RoutingContext.html[RoutingContext]` is available
in the Thymeleaf template as the `context` variable, this means you can render the template based on anything in the context
including the request, response, session or context data.

Here are some examples:

----
[snip]
<p th:text="${context.get('foo')}"></p>
<p th:text="${context.get('bar')}"></p>
<p th:text="${context.normalizedPath()}"></p>
<p th:text="${context.request().params().get('param1')}"></p>
<p th:text="${context.request().params().get('param2')}"></p>
[snip]
----

Please consult the http://www.thymeleaf.org/[Thymeleaf documentation] for how to write
Thymeleaf templates.

=== Apache FreeMarker template engine

To use Apache FreeMarker, you need to add the following _dependency_ to your project:
`io.vertx:vertx-web-templ-freemarker:4.3.5`. Create an instance of the Apache FreeMarker template engine
using: `io.vertx.ext.web.templ.Engine#create()`.

When using the Apache FreeMarker template engine, it will by default look for
templates with the `.ftl` extension if no extension is specified in the file name.

The routing context `link:../../apidocs/io/vertx/ext/web/RoutingContext.html[RoutingContext]` is available
in the Apache FreeMarker template as the `context` variable, this means you can render the template based on anything in the context
including the request, response, session or context data.

Here are some examples:

----
[snip]
<p th:text="${context.foo}"></p>
<p th:text="${context.bar}"></p>
<p th:text="${context.normalizedPath()}"></p>
<p th:text="${context.request().params().param1}"></p>
<p th:text="${context.request().params().param2}"></p>
[snip]
----

Please consult the http://www.freemarker.org/[Apache FreeMarker documentation] for how to write
Apache FreeMarker templates.

=== Pebble template engine

To use Pebble, you need to add the following _dependency_ to your project:
`io.vertx:vertx-web-templ-pebble:4.3.5`. Create an instance of the Pebble template engine
using: `io.vertx.ext.web.templ.pebble.PebbleTemplateEngine#create(vertx)`.

When using the Pebble template engine, it will by default look for
templates with the `.peb` extension if no extension is specified in the file name.

The routing context `link:../../apidocs/io/vertx/ext/web/RoutingContext.html[RoutingContext]` is available
in the Pebble template as the `context` variable, this means you can render the template based on anything in the context
including the request, response, session or context data.

Here are some examples:

----
[snip]
<p th:text="{{context.foo}}"></p>
<p th:text="{{context.bar}}"></p>
<p th:text="{{context.normalizedPath()}}"></p>
<p th:text="{{context.request().params().param1}}"></p>
<p th:text="{{context.request().params().param2}}"></p>
[snip]
----

Please consult the http://www.mitchellbosecke.com/pebble/home/[Pebble documentation] for how to write
Pebble templates.

=== Rocker template engine

To use Rocker, then add `io.vertx:vertx-web-templ-rocker:4.3.5` as a dependency to your project.
You can then create a Rocker template engine instance with `io.vertx.ext.web.templ.rocker#create()`.

The values of the JSON context object passed to the `render` method are then exposed as template parameters.
Given:

----
[snip]
final JsonObject context = new JsonObject()
 .put("foo", "badger")
 .put("bar", "fox")
 .put("context", new JsonObject().put("path", "/foo/bar"));

engine.render(context, "somedir/TestRockerTemplate2", render -> {
 // (...)
});
[snip]
----

then the template can be as the following `somedir/TestRockerTemplate2.rocker.html` resource file:

----
@import io.vertx.core.json.JsonObject
@args (JsonObject context, String foo, String bar)
Hello @foo and @bar
Request path is @context.getString("path")
----

=== HTTL template engine

To use HTTL, you need to add the following _dependency_ to your project:
`io.vertx:vertx-web-templ-httl:4.3.5`. Create an instance of the HTTL template engine
using: `io.vertx.ext.web.templ.httl.HTTLTemplateEngine#create(io.vertx.core.Vertx)`.

When using the HTTL template engine, it will by default look for
templates with the `.httl` extension if no extension is specified in the file name.

The values of the JSON context object passed to the `render` method are then exposed as template parameters.
Given:

----
[snip]
TemplateEngine engine = HTTLTemplateEngine.create(vertx);
final JsonObject context = new JsonObject()
 .put("foo", "badger")
 .put("bar", "fox");

engine.render(context, "somedir/test-httl-template1.httl", render -> {
 // (...)
});
[snip]
----

then the template can be as the following `somedir/test-httl-template1.httl` resource file:

----
<!-- #set(String foo, String bar) -->
Hello ${foo} and ${bar}

----

Please consult the https://httl.github.io/en/[HTTL documentation] for how to write
HTTL templates.

=== Rythm template engine

To use Rythm, you need to add the following _dependency_ to your project:
`io.vertx:vertx-web-templ-rythm:4.3.5`. Create an instance of the Rythm template engine
using: `io.vertx.ext.web.templ.rythm.RythmTemplateEngine#create(io.vertx.core.Vertx)`.

When using the Rythm template engine, it will by default look for
templates with the `.html` extension if no extension is specified in the file name.

The values of the JSON context object passed to the `render` method are then exposed as template parameters.
Given:

----
[snip]
TemplateEngine engine = RythmTemplateEngine.create(vertx);
final JsonObject context = new JsonObject()
 .put("foo", "badger")
 .put("bar", "fox");

engine.render(context, "somedir/test-rythm-template1.html", render -> {
 // (...)
});
[snip]
----

then the template can be as the following `somedir/test-rythm-template1.httl` resource file:

----
<!-- #set(String foo, String bar) -->
Hello @foo and @bar
----

Please consult the http://www.rythmengine.org/[RythmEngine documentation] for how to write templates.

=== Caching

Many of the engines support caching of the compiled templates. The cache is stored inside a vert.x shared data local map
which allows the engines to share the same cache across several verticles in a efficient and safe way.

==== Disabling caching

During development you might want to disable template caching so that the template gets reevaluated on each request.
In order to do this you need to set the system property: `vertxweb.environment` or environment variable
`VERTXWEB_ENVIRONMENT` to `dev` or `development`. By default caching is always enabled.

== Error handler

You can render your own errors using a template handler or otherwise but Vert.x-Web also includes an out of the boxy
"pretty" error handler that can render error pages for you.

The handler is `link:../../apidocs/io/vertx/ext/web/handler/ErrorHandler.html[ErrorHandler]`. To use the error handler just set it as a
failure handler for any paths that you want covered.

== Request logger

Vert.x-Web includes a handler `link:../../apidocs/io/vertx/ext/web/handler/LoggerHandler.html[LoggerHandler]` that you can use to log HTTP requests.
You should mount this handler before any handler that could fail the `RoutingContext`

By default requests are logged to the Vert.x logger which can be configured to use JUL logging, log4j or SLF4J.

See `link:../../apidocs/io/vertx/ext/web/handler/LoggerFormat.html[LoggerFormat]`.

== Serving favicons

Vert.x-Web includes the handler `link:../../apidocs/io/vertx/ext/web/handler/FaviconHandler.html[FaviconHandler]` especially for serving favicons.

Favicons can be specified using a path to the filesystem, or by default Vert.x-Web will look for a file on the classpath
with the name `favicon.ico`. This means you bundle the favicon in the jar of your application.

== Timeout handler

Vert.x-Web includes a timeout handler that you can use to timeout requests if they take too long to process.

This is configured using an instance of `link:../../apidocs/io/vertx/ext/web/handler/TimeoutHandler.html[TimeoutHandler]`.

If a request times out before the response is written a `503` response will be returned to the client.

Here's an example of using a timeout handler which will timeout all requests to paths starting with `/foo` after 5
seconds:

[source,java]
----
router.route("/foo/").handler(TimeoutHandler.create(5000));
----

== Response time handler

This handler sets the header `x-response-time` response header containing the time from when the request was received
to when the response headers were written, in ms., e.g.:

x-response-time: 1456ms

== Content type handler

The `ResponseContentTypeHandler` can set the `Content-Type` header automatically.
Suppose we are building a RESTful web application. We need to set the content type in all our handlers:

[source,java]
----
router
  .get("/api/books")
  .produces("application/json")
  .handler(ctx -> findBooks()
    .onSuccess(books -> ctx.response()
      .putHeader("Content-Type", "application/json")
      .end(toJson(books))).onFailure(ctx::fail));
----

If the API surface becomes pretty large, setting the content type can become cumbersome.
To avoid this situation, add the `ResponseContentTypeHandler` to the corresponding routes:

[source,java]
----
router.route("/api/*").handler(ResponseContentTypeHandler.create());
router
  .get("/api/books")
  .produces("application/json")
  .handler(ctx -> findBooks()
    .onSuccess(books -> ctx.response()
      .end(toJson(books))).onFailure(ctx::fail));
----

The handler gets the approriate content type from `link:../../apidocs/io/vertx/ext/web/RoutingContext.html#getAcceptableContentType--[getAcceptableContentType]`.
As a consequence, you can easily share the same handler to produce data of different types:

[source,java]
----
router.route("/api/*").handler(ResponseContentTypeHandler.create());

router
  .get("/api/books")
  .produces("text/xml")
  .produces("application/json")
  .handler(ctx -> findBooks()
    .onSuccess(books -> {
      if (ctx.getAcceptableContentType().equals("text/xml")) {
        ctx.response().end(toXML(books));
      } else {
        ctx.response().end(toJson(books));
      }
    })
    .onFailure(ctx::fail));
----

== SockJS

SockJS is a client side JavaScript library and protocol which provides a simple WebSocket-like interface allowing you
to make connections to SockJS servers irrespective of whether the actual browser or network will allow real WebSockets.

It does this by supporting various different transports between browser and server, and choosing one at run-time
according to browser and network capabilities.

All this is transparent to you - you are simply presented with the WebSocket-like interface which _just works_.

Please see the https://github.com/sockjs/sockjs-client[SockJS website] for more information on SockJS.

=== SockJS handler

Vert.x provides an out of the box handler called `link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSHandler.html[SockJSHandler]` for
using SockJS in your Vert.x-Web applications.

You should create one handler per SockJS application using `link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSHandler.html#create-io.vertx.core.Vertx-[SockJSHandler.create]`.
You can also specify configuration options when creating the instance. The configuration options are described with
an instance of `link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSHandlerOptions.html[SockJSHandlerOptions]`.

[source,java]
----
Router router = Router.router(vertx);

SockJSHandlerOptions options = new SockJSHandlerOptions()
  .setHeartbeatInterval(2000);

SockJSHandler sockJSHandler = SockJSHandler.create(vertx, options);
----

=== Handling SockJS sockets

On the server-side you set a handler on the SockJS handler, and
this will be called every time a SockJS connection is made from a client:

The object passed into the handler is a `link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSSocket.html[SockJSSocket]`. This has a familiar
socket-like interface which you can read and write to similarly to a `link:../../apidocs/io/vertx/core/net/NetSocket.html[NetSocket]` or
a `link:../../apidocs/io/vertx/core/http/WebSocket.html[WebSocket]`. It also implements `link:../../apidocs/io/vertx/core/streams/ReadStream.html[ReadStream]` and
`link:../../apidocs/io/vertx/core/streams/WriteStream.html[WriteStream]` so you can pump it to and from other read and write streams. The
`link:../../apidocs/io/vertx/ext/web/RoutingContext.html[RoutingContext]` is accessible for manual session management while the SockJS connection
is loaded using `link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSSocket.html#routingContext--[routingContext]`. With this you can manage
the users and sessions accessible through `link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSSocket.html#webSession--[webSession]`
and `link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSSocket.html#webUser--[webUser]`.

Here's an example of a simple SockJS handler that simply echoes back any back any data that it reads:

[source,java]
----
Router router = Router.router(vertx);

SockJSHandlerOptions options = new SockJSHandlerOptions()
  .setHeartbeatInterval(2000);

SockJSHandler sockJSHandler = SockJSHandler.create(vertx, options);

router.route("/myapp/*")
  .subRouter(sockJSHandler.socketHandler(sockJSSocket -> {

    // Just echo the data back
    sockJSSocket.handler(sockJSSocket::write);

  }));
----

=== The client side

In client side JavaScript you use the SockJS client side library to make connections. For convenience the package is
available on https://www.npmjs.com/package/sockjs-client[https://www.npmjs.com/package/sockjs-client].

This means you can refer to it from bundlers or build tools. If however you want to get a `CDN` version to use directly
on your `HTML` document, first you need to refer to the sockjs dependency:

[source,html]
----
<html>
<head>
 <script src="https://unpkg.io/sockjs-client@1.5.0/dist/sockjs.min.js"></script>
</head>
<body>
 ...
</body>
</html>
----

Full details for using the SockJS JavaScript client are on the https://github.com/sockjs/sockjs-client[SockJS website],
but in summary you use it something like this:

[source,js]
----
var sock = new SockJS('http://mydomain.com/myapp');

sock.onopen = function() {
 console.log('open');
};

sock.onmessage = function(e) {
 console.log('message', e.data);
};

sock.onevent = function(event, message) {
 console.log('event: %o, message:%o', event, message);
 return true; // in order to signal that the message has been processed
};

sock.onunhandled = function(json) {
 console.log('this message has no address:', json);
};

sock.onclose = function() {
 console.log('close');
};

sock.send('test');

sock.close();
----

=== Configuring the SockJS handler

The handler can be configured with various options using `link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSHandlerOptions.html[SockJSHandlerOptions]`.

NOTE: By default, the configuration does not include a default `Origin` property. To prevent Cross-Site WebSocket
Hijacking attacks from web browsers, it is recommended to set this property to the internet facing origin of the
application. This will enforce a check that web sockets origin is from this application. This check is important because
WebSockets are not restrained by the same-origin policy, an attacker can easily initiate a WebSocket request from a
malicious webpage targeting the `ws://` or `wss://` endpoint URL of the sockJS bridge.

=== Writing to a SockJS socket over the event bus

When a `link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSSocket.html[SockJSSocket]` is created, it can register an event handler with the event bus.
The address of that handler is given by `link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSSocket.html#writeHandlerID--[writeHandlerID]`.

By default, the event handler is not registered.
It must enabled in `link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSHandlerOptions.html[SockJSHandlerOptions]`.

[source,java]
----
Router router = Router.router(vertx);

SockJSHandlerOptions options = new SockJSHandlerOptions()
  .setRegisterWriteHandler(true);

SockJSHandler sockJSHandler = SockJSHandler.create(vertx, options);

router.route("/myapp/*")
  .subRouter(sockJSHandler.socketHandler(sockJSSocket -> {

    // Retrieve the writeHandlerID and store it (e.g. in a local map)
    String writeHandlerID = sockJSSocket.writeHandlerID();

  }));
----

NOTE: By default, the handler is registered only locally.
It can be made cluster-wide with `link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSHandlerOptions.html#setLocalWriteHandler-boolean-[setLocalWriteHandler]`.

Then you can write `link:../../apidocs/io/vertx/core/buffer/Buffer.html[Buffer]`s to the SockJS socket over the event bus.

[source,java]
----
eventBus.send(writeHandlerID, Buffer.buffer("foo"));
----

== SockJS event bus bridge

Vert.x-Web comes with a built-in SockJS socket handler called the event bus bridge which effectively extends the server-side
Vert.x event bus into client side JavaScript.

This creates a distributed event bus which not only spans multiple Vert.x instances on the server side, but includes
client side JavaScript running in browsers.

We can therefore create a huge distributed bus encompassing many browsers and servers. The browsers don't have to
be connected to the same server as long as the servers are connected.

This is done by providing a simple client side JavaScript library called `vertx-eventbus.js` which provides an API
very similar to the server-side Vert.x event-bus API, which allows you to send and publish messages to the event bus
and register handlers to receive messages.

This JavaScript library uses the JavaScript SockJS client to tunnel the event bus traffic over SockJS connections
terminating at at a `link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSHandler.html[SockJSHandler]` on the server-side.

A special SockJS socket handler is then installed on the `link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSHandler.html[SockJSHandler]` which
handles the SockJS data and bridges it to and from the server side event bus.

To activate the bridge you simply call
`link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSHandler.html#bridge-io.vertx.ext.web.handler.sockjs.SockJSBridgeOptions-[bridge]` on the
SockJS handler.

[source,java]
----
Router router = Router.router(vertx);

SockJSHandler sockJSHandler = SockJSHandler.create(vertx);
SockJSBridgeOptions options = new SockJSBridgeOptions();
// mount the bridge on the router
router
  .route("/eventbus/*")
  .subRouter(sockJSHandler.bridge(options));
----

In client side JavaScript you use the http://npmjs.com/package/@vertx/eventbus-bridge-client.js[@vertx/eventbus-bridge-client.js]
library to create connections to the event bus and to send and receive messages. The library is available on http://npmjs.com/package/@vertx/eventbus-bridge-client.js[NPM]
so it can easily be used with bundlers or build tools, but in can easily be used from a CDN (like the sockJS example
before):

[source,html]
----
<script src="https://unpkg.io/sockjs-client@1.5.0/dist/sockjs.min.js"></script>
<script src='https://unpkg.io/@vertx/eventbus-bridge-client.js@1.0.0-1/vertx-eventbus.js'></script>

<script>

var eb = new EventBus('http://localhost:8080/eventbus');

eb.onopen = () => {

 // set a handler to receive a message
 eb.registerHandler('some-address', (error, message) => {
   console.log('received a message: ' + JSON.stringify(message));
 });

 // send a message
 eb.send('some-address', {name: 'tim', age: 587});

}

</script>
----

The first thing the example does is to create a instance of the event bus

[source,javascript]
----
var eb = new EventBus('http://localhost:8080/eventbus');
----

The parameter to the constructor is the URI where to connect to the event bus. Since we create our bridge with
the prefix `eventbus` we will connect there.

You can't actually do anything with the connection until it is opened. When it is open the `onopen` handler will be called.

The bridge supports automatic reconnection, with configurable delay and backoff options.

[source,javascript]
----
var eb = new EventBus('http://localhost:8080/eventbus');
eb.enableReconnect(true);
eb.onopen = function() {}; // Set up handlers here, will be called on initial connection and all reconnections
eb.onreconnect = function() {}; // Optional, will only be called on reconnections

// Alternatively, pass in an options object
var options = {
   vertxbus_reconnect_attempts_max: Infinity, // Max reconnect attempts
   vertxbus_reconnect_delay_min: 1000, // Initial delay (in ms) before first reconnect attempt
   vertxbus_reconnect_delay_max: 5000, // Max delay (in ms) between reconnect attempts
   vertxbus_reconnect_exponent: 2, // Exponential backoff factor
   vertxbus_randomization_factor: 0.5 // Randomization factor between 0 and 1
};

var eb2 = new EventBus('http://localhost:8080/eventbus', options);
eb2.enableReconnect(true);
// Set up handlers...
----

=== Securing the Bridge

If you started a bridge like in the above example without securing it, and attempted to send messages through
it you'd find that the messages mysteriously disappeared. What happened to them?

For most applications you probably don't want client side JavaScript being able to send just any message to any
handlers on the server side or to all other browsers.

For example, you may have a service on the event bus which allows data to be accessed or deleted. We don't want
badly behaved or malicious clients being able to delete all the data in your database!

Also, we don't necessarily want any client to be able to listen in on any event bus address.

To deal with this, a SockJS bridge will by default refuse to let through any messages. It's up to you to tell the
bridge what messages are ok for it to pass through. (There is an exception for reply messages which are always allowed through).

In other words the bridge acts like a kind of firewall which has a default _deny-all_ policy.

Configuring the bridge to tell it what messages it should pass through is easy.

You can specify which _matches_ you want to allow for inbound and outbound traffic using the
`link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSBridgeOptions.html[SockJSBridgeOptions]` that you pass in when calling bridge.

Each match is a `link:../../apidocs/io/vertx/ext/bridge/PermittedOptions.html[PermittedOptions]` object:

`link:../../apidocs/io/vertx/ext/bridge/PermittedOptions.html#setAddress-java.lang.String-[setAddress]`:: This represents the exact address the message is being sent to. If you want to allow messages based on
an exact address you use this field.
`link:../../apidocs/io/vertx/ext/bridge/PermittedOptions.html#setAddressRegex-java.lang.String-[setAddressRegex]`:: This is a regular expression that will be matched against the address. If you want to allow messages
based on a regular expression you use this field. If the `address` field is specified this field will be ignored.
`link:../../apidocs/io/vertx/ext/bridge/PermittedOptions.html#setMatch-io.vertx.core.json.JsonObject-[setMatch]`:: This allows you to allow messages based on their structure. Any fields in the match must exist in the
message with the same values for them to be allowed. This currently only works with JSON messages.

If a message is _in-bound_ (i.e. being sent from client side JavaScript to the server) when it is received Vert.x-Web
will look through any inbound permitted matches. If any match, it will be allowed through.

If a message is _out-bound_ (i.e. being sent from the server to client side JavaScript) before it is sent to the client
Vert.x-Web will look through any outbound permitted matches. If any match, it will be allowed through.

The actual matching works as follows:

If an `address` field has been specified then the `address` must match _exactly_ with the address of the message
for it to be considered matched.

If an `address` field has not been specified and an `addressRegex` field has been specified then the regular expression
in `address_re` must match with the address of the message for it to be considered matched.

If a `match` field has been specified, then also the structure of the message must match. Structuring matching works
by looking at all the fields and values in the match object and checking they all exist in the actual message body.

Here's an example:

[source,java]
----
Router router = Router.router(vertx);

SockJSHandler sockJSHandler = SockJSHandler.create(vertx);


// Let through any messages sent to 'demo.orderMgr' from the client
PermittedOptions inboundPermitted1 = new PermittedOptions()
  .setAddress("demo.orderMgr");

// Allow calls to the address 'demo.persistor' from the client as
// long as the messages have an action field with value 'find'
// and a collection field with value 'albums'
PermittedOptions inboundPermitted2 = new PermittedOptions()
  .setAddress("demo.persistor")
  .setMatch(new JsonObject().put("action", "find")
    .put("collection", "albums"));

// Allow through any message with a field `wibble` with value `foo`.
PermittedOptions inboundPermitted3 = new PermittedOptions()
  .setMatch(new JsonObject().put("wibble", "foo"));

// First let's define what we're going to allow from server -> client

// Let through any messages coming from address 'ticker.mystock'
PermittedOptions outboundPermitted1 = new PermittedOptions()
  .setAddress("ticker.mystock");

// Let through any messages from addresses starting with "news."
// (e.g. news.europe, news.usa, etc)
PermittedOptions outboundPermitted2 = new PermittedOptions()
  .setAddressRegex("news\\..+");

// Let's define what we're going to allow from client -> server
SockJSBridgeOptions options = new SockJSBridgeOptions().
  addInboundPermitted(inboundPermitted1).
  addInboundPermitted(inboundPermitted1).
  addInboundPermitted(inboundPermitted3).
  addOutboundPermitted(outboundPermitted1).
  addOutboundPermitted(outboundPermitted2);

// mount the bridge on the router
router
  .route("/eventbus/*")
  .subRouter(sockJSHandler.bridge(options));
----

=== Requiring authorization for messages

The event bus bridge can also be configured to use the Vert.x-Web authorization functionality to require
authorization for messages, either in-bound or out-bound on the bridge.

To do this, you can add extra fields to the match described in the previous section that determine what authority is
required for the match.

To declare that a specific authority for the logged-in user is required in order to access allow the messages you use the
`link:../../apidocs/io/vertx/ext/bridge/PermittedOptions.html#setRequiredAuthority-java.lang.String-[setRequiredAuthority]` field.

Here's an example:

[source,java]
----
PermittedOptions inboundPermitted = new PermittedOptions()
  .setAddress("demo.orderService");

// But only if the user is logged in and has the authority "place_orders"
inboundPermitted.setRequiredAuthority("place_orders");

SockJSBridgeOptions options = new SockJSBridgeOptions()
  .addInboundPermitted(inboundPermitted);
----

For the user to be authorised they must be first logged in and secondly have the required authority.

To handle the login and actually auth you can configure the normal Vert.x auth handlers. For example:

[source,java]
----
Router router = Router.router(vertx);

// Let through any messages sent to 'demo.orderService' from the client
PermittedOptions inboundPermitted = new PermittedOptions()
  .setAddress("demo.orderService");

// But only if the user is logged in and has the authority "place_orders"
inboundPermitted.setRequiredAuthority("place_orders");

SockJSHandler sockJSHandler = SockJSHandler.create(vertx);

// Now set up some basic auth handling:

router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)));

AuthenticationHandler basicAuthHandler = BasicAuthHandler.create(authProvider);

router.route("/eventbus/*").handler(basicAuthHandler);

// mount the bridge on the router
router
  .route("/eventbus/*")
  .subRouter(sockJSHandler.bridge(new SockJSBridgeOptions()
    .addInboundPermitted(inboundPermitted)));
----

=== Handling event bus bridge events

If you want to be notified when an event occurs on the bridge you can provide a handler when calling
`link:../../apidocs/io/vertx/ext/web/handler/sockjs/SockJSHandler.html#bridge-io.vertx.ext.web.handler.sockjs.SockJSBridgeOptions-io.vertx.core.Handler-[bridge]`.

Whenever an event occurs on the bridge it will be passed to the handler. The event is described by an instance of
`link:../../apidocs/io/vertx/ext/web/handler/sockjs/BridgeEvent.html[BridgeEvent]`.

The event can be one of the following types:

SOCKET_CREATED:: This event will occur when a new SockJS socket is created.
SOCKET_IDLE:: This event will occur when SockJS socket is on idle for longer period of time than initially configured.
SOCKET_PING:: This event will occur when the last ping timestamp is updated for the SockJS socket.
SOCKET_CLOSED:: This event will occur when a SockJS socket is closed.
SOCKET_ERROR:: This event will occur when an underlying transport errors.
SEND:: This event will occur when a message is attempted to be sent from the client to the server.
PUBLISH:: This event will occur when a message is attempted to be published from the client to the server.
RECEIVE:: This event will occur when a message is attempted to be delivered from the server to the client.
REGISTER:: This event will occur when a client attempts to register a handler.
UNREGISTER:: This event will occur when a client attempts to unregister a handler.

The event enables you to retrieve the type using `link:../../apidocs/io/vertx/ext/bridge/BaseBridgeEvent.html#type--[type]` and
inspect the raw message of the event using `link:../../apidocs/io/vertx/ext/bridge/BaseBridgeEvent.html#getRawMessage--[getRawMessage]`.

The raw message is a JSON object with the following structure:

----
{
 "type": "send"|"publish"|"receive"|"register"|"unregister",
 "address": the event bus address being sent/published/registered/unregistered
 "body": the body of the message
}
----

NOTE: `SOCKET_ERROR` events may include a message. In this case inspecting the type property, may introduce a new kind
of message. A `err` message. This is a synthetic message generated when there is a socket exception. The message will
follow the bridge wire protocol and look like this:

----
{
 "type": "err",
 "failureType": "socketException",
 "message": "optionally a message from the exception being raised"
}
----

The event is also an instance of `link:../../apidocs/io/vertx/core/Promise.html[Promise]`. When you are finished handling the event you can
complete the promise with `true` to enable further processing.

If you don't want the event to be processed you can complete the promise with `false`. This is a useful feature that
enables you to do your own filtering on messages passing through the bridge, or perhaps apply some fine grained
authorization or metrics.

Here's an example where we reject all messages flowing through the bridge if they contain the word "Armadillos".

[source,java]
----
Router router = Router.router(vertx);

// Let through any messages sent to 'demo.orderMgr' from the client
PermittedOptions inboundPermitted = new PermittedOptions()
  .setAddress("demo.someService");

SockJSHandler sockJSHandler = SockJSHandler.create(vertx);
SockJSBridgeOptions options = new SockJSBridgeOptions()
  .addInboundPermitted(inboundPermitted);

// mount the bridge on the router
router
  .route("/eventbus/*")
  .subRouter(sockJSHandler
    .bridge(options, be -> {
      if (be.type() == BridgeEventType.PUBLISH ||
        be.type() == BridgeEventType.RECEIVE) {

          if (be.getRawMessage().getString("body").equals("armadillos")) {
            // Reject it
            be.complete(false);
            return;
          }
        }
        be.complete(true);
      }));
----

Here's an example how to configure and handle SOCKET_IDLE bridge event type.
Notice `setPingTimeout(5000)` which says that if ping message doesn't arrive from client within 5 seconds
then the SOCKET_IDLE bridge event would be triggered.

[source,java]
----
Router router = Router.router(vertx);

// Initialize SockJSHandler handler
SockJSHandler sockJSHandler = SockJSHandler.create(vertx);
SockJSBridgeOptions options = new SockJSBridgeOptions()
  .addInboundPermitted(inboundPermitted)
  .setPingTimeout(5000);

// mount the bridge on the router
router
  .route("/eventbus/*")
  .subRouter(sockJSHandler.bridge(options, be -> {
    if (be.type() == BridgeEventType.SOCKET_IDLE) {
      // Do some custom handling...
    }

      be.complete(true);
    }));
----

In client side JavaScript you use the 'vertx-eventbus.js` library to create connections to the event bus and to send and receive messages:

[source,html]
----
<script src="https://unpkg.io/sockjs-client@1.5.0/dist/sockjs.min.js"></script>
<script src='https://unpkg.io/@vertx/eventbus-bridge-client.js@1.0.0-1/vertx-eventbus.js'></script>

<script>

var eb = new EventBus('http://localhost:8080/eventbus', {"vertxbus_ping_interval": 300000}); // sends ping every 5 minutes.

eb.onopen = function() {

// set a handler to receive a message
eb.registerHandler('some-address', function(error, message) {
  console.log('received a message: ' + JSON.stringify(message));
});

// send a message
eb.send('some-address', {name: 'tim', age: 587});
}

</script>
----

The first thing the example does is to create a instance of the event bus

[source,javascript]
----
var eb = new EventBus('http://localhost:8080/eventbus', {"vertxbus_ping_interval": 300000});
----

The 2nd parameter to the constructor tells the sockjs library to send ping message every 5 minutes. since the server
was configured to expect ping every 5 seconds -> `SOCKET_IDLE` would be triggered on the server.


You can also amend the raw message, e.g. change the body. For messages that are flowing in from the client you can
also add headers to the message, here's an example:

[source,java]
----
Router router = Router.router(vertx);

// Let through any messages sent to 'demo.orderService' from the client
PermittedOptions inboundPermitted = new PermittedOptions()
  .setAddress("demo.orderService");

SockJSHandler sockJSHandler = SockJSHandler.create(vertx);
SockJSBridgeOptions options = new SockJSBridgeOptions()
  .addInboundPermitted(inboundPermitted);

// mount the bridge on the router
router
  .route("/eventbus/*")
  .subRouter(sockJSHandler.bridge(options, be -> {
    if (
      be.type() == BridgeEventType.PUBLISH ||
        be.type() == BridgeEventType.SEND) {

        // Add some headers
        JsonObject headers = new JsonObject()
          .put("header1", "val")
          .put("header2", "val2");

        JsonObject rawMessage = be.getRawMessage();
        rawMessage.put("headers", headers);
        be.setRawMessage(rawMessage);
      }
      be.complete(true);
    }));
----

== CSRF Cross Site Request Forgery

CSRF or sometimes also known as XSRF is a technique by which an unauthorized site can gain your user's private data.
Vert.x-Web includes a handler `link:../../apidocs/io/vertx/ext/web/handler/CSRFHandler.html[CSRFHandler]` that you can use to prevent cross site
request forgery requests.

On each get request under this handler a cookie is added to the response with a unique token. Clients are then
expected to return this token back in a header. Since cookies are sent it is required that the cookie handler is also
present on the router.

When developing non single page applications that rely on the User-Agent to perform the `POST` action, Headers cannot
be specified on HTML Forms. In order to solve this problem the header value will also be checked if and only if no
header was present in the Form attributes under the same name as the header, e.g.:

[source,html]
----
<form action="/submit" method="POST">
<input type="hidden" name="X-XSRF-TOKEN" value="abracadabra">
</form>
----

It is the responsibility of the user to fill in the right value for the form field. Users who prefer to use an HTML
only solution can fill this value by fetching the the token value from the routing context under the key `X-XSRF-TOKEN`
or the header name they have chosen during the instantiation of the `CSRFHandler` object.

[source,java]
----
router.route().handler(CSRFHandler.create(vertx, "abracadabra"));
router.route().handler(ctx -> {

});
----

Note that this handler is session aware. If there is a session available the form parameter or header might be omited
during the `POST` action as it will be read from the session. This also implies that tokens will only be regenerated
on session upgrades.

Note, for extra security users are advised to rotate the key that signs the tokens. This can be done online by replacing
the handler, or by restarting the application with a new configuration. Clickjacking could still affect applications. If
this is a critical application consider setting the header: `X-Frame-Options` as described in:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options

=== Using AJAX

When accessing protected routes via ajax both the csrf token will need to be passed in the request. Typically this is
done using a request header, as adding a request header can typically be done at a central location easily without
payload modification.

The CSRF token is obtained from the server side context under the key `X-XSRF-TOKEN` (unless you specified a different
name). This token needs to be exposed to the client-side, typically by including it in the initial page content. One
possibility is to store it in an HTML <meta> tag, where value can then be retrieved at the time of the request by
JavaScript.

The following can be included in your view (handlebar example below):

[source,html]
----
<meta name="csrf-token" content="${X-XSRF-TOKEN}">
----

The following is an example of using the Fetch API to post to the /process route with the CSRF token from the <meta>
tag on the page:

[source,js]
----
// Read the CSRF token from the <meta> tag
var token = document.querySelector('meta[name="csrf-token"]').getAttribute('content')

// Make a request using the Fetch API
fetch('/process', {
 credentials: 'same-origin', // <-- includes cookies in the request
 headers: {
   'X-XSRF-TOKEN': token // <-- is the csrf token as a header
 },
 method: 'POST',
 body: {
   key: 'value'
 }
})
----

== HSTS Handler

HTTP Strict Transport Security (HSTS) is a web security policy mechanism that helps to protect websites against
man-in-the-middle attacks such as protocol downgrade attacks and cookie hijacking. It allows web servers to declare that
web browsers (or other complying user agents) should automatically interact with it using only HTTPS connections, which
provide Transport Layer Security (TLS/SSL), unlike the insecure HTTP used alone. HSTS is an IETF standards track
protocol and is specified in RFC 6797.

This handler will configure the correct header for your application in a single step:

[source,java]
----
router.route().handler(HSTSHandler.create());
----

== CSP Handler

Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of
attacks, including Cross Site Scripting (XSS) and data injection attacks. These attacks are used for everything from
data theft to site defacement to distribution of malware.

CSP is designed to be fully backward compatible. Browsers that don't support it still work with servers that
implement it, and vice-versa: browsers that don't support CSP simply ignore it, functioning as usual, defaulting to
the standard same-origin policy for web content. If the site doesn't offer the CSP header, browsers likewise use the
standard same-origin policy.

[source,java]
----
router.route().handler(
  CSPHandler.create()
    .addDirective("default-src", "*.trusted.com"));
----

== XFrame Handler

The `X-Frame-Options` HTTP response header can be used to indicate whether or not a browser should be allowed to render
a page in a `frame`, `iframe`, `embed` or `object`. Sites can use this to avoid click-jacking attacks, by ensuring that
their content is not embedded into other sites.

The added security is provided only if the user accessing the document is using a browser that supports
`X-Frame-Options`.

If you specify `DENY`, not only will attempts to load the page in a frame fail when loaded from other sites, attempts to
do so will fail when loaded from the same site. On the other hand, if you specify `SAMEORIGIN`, you can still use the
page in a frame as long as the site including it in a frame is the same as the one serving the page.

This handler will configure the correct header for your application in a single step:

[source,java]
----
router.route().handler(XFrameHandler.create(XFrameHandler.DENY));
----

== OAuth2AuthHandler Handler

The `OAuth2AuthHandler` allows quick setup of secure routes using the OAuth2 protocol. This handler simplifies the
authCode flow. An example of using it to protect some resource and authenticate with GitHub can be implemented as:

[source,java]
----
OAuth2Auth authProvider = GithubAuth
  .create(vertx, "CLIENT_ID", "CLIENT_SECRET");

// create a oauth2 handler on our running server
// the second argument is the full url to the
// callback as you entered in your provider management console.
OAuth2AuthHandler oauth2 = OAuth2AuthHandler
  .create(vertx, authProvider, "https://myserver.com/callback");

// setup the callback handler for receiving the GitHub callback
oauth2.setupCallback(router.route("/callback"));

// protect everything under /protected
router.route("/protected/*").handler(oauth2);
// mount some handler under the protected zone
router
  .route("/protected/somepage")
  .handler(ctx -> ctx.response().end("Welcome to the protected resource!"));

// welcome page
router
  .get("/")
  .handler(ctx -> ctx.response()
    .putHeader("content-type", "text/html")
    .end("Hello<br><a href=\"/protected/somepage\">Protected by Github</a>"));
----

The OAuth2AuthHandler will setup a proper callback OAuth2 handler so the user does not need to deal with validation
of the authority server response. It is quite important to know that authority server responses are only valid once,
this means that if a client issues a reload of the callback URL it will be asserted as a invalid request since the
validation will fail.

A rule of thumb is once a valid callback is executed issue a client side redirect to a protected resource. This
redirect should also create a session cookie (or other session mechanism) so the user is not required to authenticate
for every request.

Due to the nature of OAuth2 spec there are slight changes required in order to use other OAuth2 providers but
vertx-auth provides you with many out of the box implementations:


* Azure Active Directory `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/AzureADAuth.html[AzureADAuth]`
* Box.com `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/BoxAuth.html[BoxAuth]`
* Dropbox `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/DropboxAuth.html[DropboxAuth]`
* Facebook `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/FacebookAuth.html[FacebookAuth]`
* Foursquare `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/FoursquareAuth.html[FoursquareAuth]`
* Github `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/GithubAuth.html[GithubAuth]`
* Google `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/GoogleAuth.html[GoogleAuth]`
* Instagram `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/InstagramAuth.html[InstagramAuth]`
* Keycloak `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/KeycloakAuth.html[KeycloakAuth]`
* LinkedIn `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/LinkedInAuth.html[LinkedInAuth]`
* Mailchimp `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/MailchimpAuth.html[MailchimpAuth]`
* Salesforce `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/SalesforceAuth.html[SalesforceAuth]`
* Shopify `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/ShopifyAuth.html[ShopifyAuth]`
* Soundcloud `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/SoundcloudAuth.html[SoundcloudAuth]`
* Stripe `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/StripeAuth.html[StripeAuth]`
* Twitter `link:../../apidocs/io/vertx/ext/auth/oauth2/providers/TwitterAuth.html[TwitterAuth]`

However if you're using an unlisted provider you can still do it using the base API like this:

[source,java]
----
OAuth2Auth authProvider = OAuth2Auth.create(vertx, new OAuth2Options()
  .setClientId("CLIENT_ID")
  .setClientSecret("CLIENT_SECRET")
  .setSite("https://accounts.google.com")
  .setTokenPath("https://www.googleapis.com/oauth2/v3/token")
  .setAuthorizationPath("/o/oauth2/auth"));

// create a oauth2 handler on our domain: "http://localhost:8080"
OAuth2AuthHandler oauth2 = OAuth2AuthHandler
  .create(vertx, authProvider, "http://localhost:8080");

// these are the scopes
oauth2.withScope("profile");

// setup the callback handler for receiving the Google callback
oauth2.setupCallback(router.get("/callback"));

// protect everything under /protected
router.route("/protected/*").handler(oauth2);
// mount some handler under the protected zone
router
  .route("/protected/somepage")
  .handler(ctx -> ctx.response().end("Welcome to the protected resource!"));

// welcome page
router
  .get("/")
  .handler(ctx -> ctx.response()
    .putHeader("content-type", "text/html")
    .end("Hello<br><a href=\"/protected/somepage\">Protected by Google</a>"));
----

You will need to provide all the details of your provider manually but the end result is the same.

The handler will pin your application the the configured callback url. The usage is simple as providing the handler
a route instance and all setup will be done for you. In a typical use case your provider will ask you what is the
callback url to your application, your then enter a url like: `https://myserver.com/callback`. This is the second
argument to the handler now you just need to set it up. To make it easier to the end user all you need to do is call
the setupCallback method.

This is how you pin your handler to the server `https://myserver.com:8447/callback`. Note that the port number is not
mandatory for the default values, 80 for http, 443 for https.

[source,java]
----
OAuth2AuthHandler oauth2 = OAuth2AuthHandler
  .create(vertx, provider, "https://myserver.com:8447/callback");

// now allow the handler to setup the callback url for you
oauth2.setupCallback(router.route("/callback"));
----

In the example the route object is created inline by `Router.route()` however if you want to have full control of the
order the handler is called (for example you want it to be called as soon as possible in the chain) you can always
create the route object before and pass it as a reference to this method.

=== A real world example

Up to now you have learned how to use the Oauth2 Handler however you will notice that for each request you will need
to authenticate. This is because the handler has no state and there was no state management applied in the examples.

Although having no state is recommended for API facing endpoints, for example, using JWT (we will cover those later)
for user facing endpoinst we can keep the authentication result stored in the session. For this to work we would
need an application like the following snippet:

[source,java]
----
OAuth2Auth authProvider =
  GithubAuth
    .create(vertx, "CLIENTID", "CLIENT SECRET");
// We need a user session handler too to make sure
// the user is stored in the session between requests
router.route()
  .handler(SessionHandler.create(LocalSessionStore.create(vertx)));
// we now protect the resource under the path "/protected"
router.route("/protected").handler(
  OAuth2AuthHandler.create(
      vertx,
      authProvider,
      "http://localhost:8080/callback")
    // we now configure the oauth2 handler, it will
    // setup the callback handler
    // as expected by your oauth2 provider.
    .setupCallback(router.route("/callback"))
    // for this resource we require that users have
    // the authority to retrieve the user emails
    .withScope("user:email")
);
// Entry point to the application, this will render
// a custom template.
router.get("/").handler(ctx -> ctx.response()
  .putHeader("Content-Type", "text/html")
  .end(
    "<html>\n" +
      "  <body>\n" +
      "    <p>\n" +
      "      Well, hello there!\n" +
      "    </p>\n" +
      "    <p>\n" +
      "      We're going to the protected resource, if there is no\n" +
      "      user in the session we will talk to the GitHub API. Ready?\n" +
      "      <a href=\"/protected\">Click here</a> to begin!</a>\n" +
      "    </p>\n" +
      "    <p>\n" +
      "      <b>If that link doesn't work</b>, remember to provide your\n" +
      "      own <a href=\"https://github.com/settings/applications/new\">\n" +
      "      Client ID</a>!\n" +
      "    </p>\n" +
      "  </body>\n" +
      "</html>"));
// The protected resource
router.get("/protected").handler(ctx -> {
  // at this moment your user object should contain the info
  // from the Oauth2 response, since this is a protected resource
  // as specified above in the handler config the user object is never null
  User user = ctx.user();
  // just dump it to the client for demo purposes
  ctx.response().end(user.toString());
});
----

=== Mixing OAuth2 and JWT

Some providers use JWT tokens as access tokens, this is a feature of https://tools.ietf.org/html/rfc6750[RFC6750]
and can be quite useful when one wants to mix client based authentication and API authorization. For example say that
you have a application that provides some protected HTML documents but you also want it to be available for API's to
consume. In this case an API cannot easily perform the redirect handshake required by OAuth2 but can use a Token
provided before hand.

This is handled automatically by the handler as long as the provider is configured to support JWTs.

In real life this means that your API's can access your protected resources using the header `Authorization` with the
value `Bearer BASE64_ACCESS_TOKEN`.

=== WebAuthn

Our online existence relies on an outdated and fragile idea of passwords. The password is what lies between a malicious
user and your bank account or social media accounts. Passwords are hard to maintain; it's hard to store them on the
server (passwords get stolen). They're hard to memorize, or not tell to others (phishing attacks).

But there's a better way! A passwordless world, and it is a standard by W3C and FIDO Alliance running on your browser.

WebAuthn is an API that allows servers to register and authenticate users using public-key cryptography instead of a
password, an API that uses cryptography in a user-accessible way with the help of an authentication device, for example
a yubikey token, or your mobile phone.

The protocol requires at least the first callback to be mounted on the router:

1. `/webauthn/response` the callback used to perform all the validations
2. `/webauthn/login` the endpoint to allow users to start the login flow (optional, but without it it won't be able to login)
3. `/webauthn/register` the endpoint to allow users to register a new identificator (optional, if the data is already stored this endpoint is not needed)

An example of a protected application is:

[source,java]
----
WebAuthn webAuthn = WebAuthn.create(
    vertx,
    new WebAuthnOptions()
      .setRelyingParty(new RelyingParty().setName("Vert.x WebAuthN Demo"))
      // What kind of authentication do you want? do you care?
      // # security keys
      .setAuthenticatorAttachment(AuthenticatorAttachment.CROSS_PLATFORM)
      // # fingerprint
      .setAuthenticatorAttachment(AuthenticatorAttachment.PLATFORM)
      .setUserVerification(UserVerification.REQUIRED))
  // where to load the credentials from?
  .authenticatorFetcher(fetcher)
  // update the state of an authenticator
  .authenticatorUpdater(updater);

// parse the BODY
router.post()
  .handler(BodyHandler.create());
// add a session handler
router.route()
  .handler(SessionHandler
    .create(LocalSessionStore.create(vertx)));

// security handler
WebAuthnHandler webAuthNHandler = WebAuthnHandler.create(webAuthn)
  .setOrigin("https://192.168.178.74.xip.io:8443")
  // required callback
  .setupCallback(router.post("/webauthn/response"))
  // optional register callback
  .setupCredentialsCreateCallback(router.post("/webauthn/register"))
  // optional login callback
  .setupCredentialsGetCallback(router.post("/webauthn/login"));

// secure the remaining routes
router.route().handler(webAuthNHandler);
----

The application is not secure on the backend side but there is some code needed to be performed on the client side. A bit
of boilerplate is required, take these 2 functions:

[source,javascript]
----
/**
* Converts PublicKeyCredential into serialised JSON
* @param  {Object} pubKeyCred
* @return {Object}            - JSON encoded publicKeyCredential
*/
var publicKeyCredentialToJSON = (pubKeyCred) => {
 if (pubKeyCred instanceof Array) {
   let arr = [];
   for (let i of pubKeyCred) { arr.push(publicKeyCredentialToJSON(i)) }

   return arr
 }

 if (pubKeyCred instanceof ArrayBuffer) {
   return base64url.encode(pubKeyCred)
 }

 if (pubKeyCred instanceof Object) {
   let obj = {};

   for (let key in pubKeyCred) {
     obj[key] = publicKeyCredentialToJSON(pubKeyCred[key])
   }

   return obj
 }

 return pubKeyCred
};

/**
* Generate secure random buffer
* @param  {Number} len - Length of the buffer (default 32 bytes)
* @return {Uint8Array} - random string
*/
var generateRandomBuffer = (len) => {
 len = len || 32;

 let randomBuffer = new Uint8Array(len);
 window.crypto.getRandomValues(randomBuffer);

 return randomBuffer
};

/**
* Decodes arrayBuffer required fields.
*/
var preformatMakeCredReq = (makeCredReq) => {
 makeCredReq.challenge = base64url.decode(makeCredReq.challenge);
 makeCredReq.user.id = base64url.decode(makeCredReq.user.id);

 return makeCredReq
};

/**
* Decodes arrayBuffer required fields.
*/
var preformatGetAssertReq = (getAssert) => {
 getAssert.challenge = base64url.decode(getAssert.challenge);

 for (let allowCred of getAssert.allowCredentials) {
   allowCred.id = base64url.decode(allowCred.id)
 }

 return getAssert
};
----

These functions will help you with the interaction with the server. Nothing more. Let's start by login in a user:

[source,javascript]
----
// using the functions defined before...
getGetAssertionChallenge({name: 'your-user-name'})
.then((response) => {
 // base64 must be decoded to a JavaScript Buffer
 let publicKey = preformatGetAssertReq(response);
 // the response is then passed to the browser
 // to generate an assertion by interacting with your token/phone/etc...
 return navigator.credentials.get({publicKey})
})
.then((response) => {
 // convert response buffers to base64 and json
 let getAssertionResponse = publicKeyCredentialToJSON(response);
 // send information to server
 return sendWebAuthnResponse(getAssertionResponse)
})
.then((response) => {
 // success!
 alert('Login success')
})
.catch((error) => alert(error));

// utility functions

let sendWebAuthnResponse = (body) => {
 return fetch('/webauthn/response', {
   method: 'POST',
   credentials: 'include',
   headers: {
     'Content-Type': 'application/json'
   },
   body: JSON.stringify(body)
 })
   .then(response => {
     if (!response.ok) {
       throw new Error(`Server responded with error: ${response.statusText}`);
     }
     return response;
   })
};

let getGetAssertionChallenge = (formBody) => {
 return fetch('/webauthn/login', {
   method: 'POST',
   credentials: 'include',
   headers: {
     'Content-Type': 'application/json'
   },
   body: JSON.stringify(formBody)
 })
   .then(response => {
     if (!response.ok) {
       throw new Error(`Server responded with error: ${response.statusText}`);
     }
     return response;
   })
   .then((response) => response.json())
};
----

The example above already covered 66% of the API, 2 out fo 3 endpoints where covered. The final endpoint is the user
registration. User registration is the process of enrolling a new key into the server credential store and map to a user,
and of course on the client side a private key was created and associated with the server but this key never left the
hardware token or your phone security chip.

To register a user and reusing most of the functions already defined above:

[source,javascript]
----
/* Handle for register form submission */
getMakeCredentialsChallenge({name: 'myalias', displayName: 'Paulo Lopes'})
.then((response) => {
 // convert challenge & id to buffer and perform register
 let publicKey = preformatMakeCredReq(response);
 // create a new secure key pair
 return navigator.credentials.create({publicKey})
})
.then((response) => {
 // convert response from buffer to json
 let makeCredResponse = window.publicKeyCredentialToJSON(response);
 // send to server to confirm the user
 return sendWebAuthnResponse(makeCredResponse)
})
.then((response) => {
 alert('Registration completed')
})
.catch((error) => alert(error));

// utility functions

let getMakeCredentialsChallenge = (formBody) => {
 return fetch('/webauthn/register', {
   method: 'POST',
   credentials: 'include',
   headers: {
     'Content-Type': 'application/json'
   },
   body: JSON.stringify(formBody)
 })
   .then(response => {
     if (!response.ok) {
       throw new Error(`Server responded with error: ${response.statusText}`);
     }
     return response;
   })
   .then((response) => response.json())
};
----

WARNING: Due to the secure nature of the API browsers will not allow you to use this API on plain text HTTP. All requests
must go over HTTPS.

WARNING: WebAuthN requires HTTPS with a working TLS certificate, you can use self signed certiticates too during
development.

=== One Time Password (Multi-Factor Authentication)

Vert.x also supports multi factor authentication. There are two options to work with MFA:

* `HOTP` - Hash Based One Time Password
* `TOTP` - Time Based One Time Password

The usage is the same across providers, for this reason a single handler is present that allows you to select the
desired mode at the constructor level.

The behavior of this handler can be seen as:

If there is no `link:../../apidocs/io/vertx/ext/auth/User.html[User]` in the current request, then it is assumed that no previous authentication has been
performed. This implies that the request will be immediately terminated with status code 401.

If a user is present and the object lacks the property `mfa` with a matching type (`hotp`/`totp`), the request will
be redirected to the verification url (if provided), otherwise it will be terminated. Such url should provide a way
to enter the code, for example:

[source,html]
----
<html>
<head>
 <meta charset="UTF-8">
 <title>OTP Authenticator Verification Example Page</title>
</head>
<body>
<form action="/otp/verify" method="post" enctype="multipart/form-data">
 <div>
   <label>Code:</label>
   <input type="text" name="code"/><br/>
 </div>
 <div>
   <input type="submit" value="Submit"/>
 </div>
</form>
</body>
</html>

----

After the user enters the valid code, the request redirects to the initial url or to `/` if no original url is known.

Of course this flow assumes that authenticator applications or devices have been already configured. In order to
configure a new application/device, an example HTML page could be:

[source,html]
----
<html>
<head>
 <title>OTP Authenticator Registration Example Page</title>
</head>
<body>
 <p>Scan this QR Code in Google Authenticator</p>
 <img id="qrcode">
 <p>- or enter this key manually -</p>
 <span id="url"></span>

 <script>
 const key = document.getElementById('url');
 const qrcode = document.getElementById('qrcode');

 fetch(
   '/otp/register',
   {
     method: 'POST',
     headers: {
       'Accept': 'application/json'
     }
   })
   .then(res => {
     if (res.status === 200) {
       return res;
     }
     throw new Error(res.statusText);
   })
   .catch(err => console.error(err))
   .then(res => res.json())
   .then(json => {
     key.innerText = json.url;
     qrcode.src =
       'https://chart.googleapis.com/chart?chs=166x166&chld=L|0&cht=qr&chl=' +
       encodeURIComponent(json.url);
   });
 </script>
</body>
</html>
----

The important bit in this example is that the script makes a `POST` request to the configured registration callback.
Again this callback will return status code 401 if there is no user already authenticated in the request. On success a
JSON document is returned with a url, and a few extra metadata. This url should be used to configure the authenticator,
either by manually entering it on the application or by rendering a QR code. Rendering of QR codes can be done both on
the backend or on the frontend. For the sake of simplicity, this example makes use of the google charts API to render
it on the browser.

Finally, this is how you would use the handler in your vert.x application:

[source,java]
----
router.post()
  .handler(BodyHandler.create());
// add a session handler (OTP requires state)
router.route()
  .handler(SessionHandler
    .create(LocalSessionStore.create(vertx))
    .setCookieSameSite(CookieSameSite.STRICT));

// add the first authentication mode, for example HTTP Basic Authentication
router.route()
  .handler(basicAuthHandler);

final OtpAuthHandler otp = OtpAuthHandler
  .create(TotpAuth.create()
    .authenticatorFetcher(authr -> {
      // fetch authenticators from a database
      // ...
      return Future.succeededFuture(new io.vertx.ext.auth.otp.Authenticator());
    })
    .authenticatorUpdater(authr -> {
      // update or insert authenticators from a database
      // ...
      return Future.succeededFuture();
    }));

otp
  // the issuer for the application
  .issuer("Vert.x Demo")
  // handle code verification responses
  .verifyUrl("/verify-otp.html")
  // handle registration of authenticators
  .setupRegisterCallback(router.post("/otp/register"))
  // handle verification of authenticators
  .setupCallback(router.post("/otp/verify"));

// secure the rest of the routes
router.route()
  .handler(otp);

// To view protected details, user must be authenticated and
// using 2nd factor authentication
router.get("/protected")
  .handler(ctx -> ctx.end("Super secret content"));
----

=== Handling HTTP Method overriding

Many companies and other services impose limitations to the REST HTTP methods they allow to the outside world. Some are lax by allowing any method, most are restricted by allowing only a small-but-decent set and some only allow GET and POST. The reasons for such restritions varies: browser or client limitations or a really strict corporate firewalls. Web services with only GET and POST does not express well the REST ideology. PUT, DELETE, OPTIONS, among others are quite useful to specify what do to to a resource. To deal with it, it was created the X-HTTP-METHOD-OVERRIDE HTTP header as a workaround.

By sending a request with GET/POST and which method the request should truly process inside the X-HTTP-METHOD-OVERRIDE HTTP header, the server should recognize the header and redirect to the appropriate method.

Vert.x allows one to do so, simply by:

[source,java]
----
router.route().handler(MethodOverrideHandler.create());

router.route(HttpMethod.GET, "/").handler(ctx -> {
  // do GET stuff...
});

router.route(HttpMethod.POST, "/").handler(ctx -> {
  // do POST stuff...
});
----

Since it will redirect the request, it is wise to avoid firing request handlers unnecessarily, so it is better to add the MethodOverrideHandler as the first handler.

Also, a word of caution: THIS MIGHT BECOME AN ATTACK VECTOR FOR ILL-INTENTIONED PEOPLE!

To mitigate such a problem, the MethodOverrideHandler comes with a Safe-Downgrade Policy by default. This policy says that the method contained in X-HTTP-METHOD-OVERRIDE can override the original one if:

* the overriding method is idempotent; or
* the overriding method is safe and the method to be overrided is NOT idempotent; or
* the method to be overrided is not safe.

Although we do NOT recommend, Vert.x will not force you to anything. If it is your desire to allow any overriding, then:

[source,java]
----
router.route().handler(MethodOverrideHandler.create(false));

router.route(HttpMethod.GET, "/").handler(ctx -> {
  // do GET stuff...
});

router.route(HttpMethod.POST, "/").handler(ctx -> {
  // do POST stuff...
});
----