host • Akka HTTP (original) (raw)

Filter requests matching conditions against the hostname part of the Host header value in the request.

Signature

def host(hostNames: String*): Directive0
def host(predicate: String => Boolean): Directive0
def host(regex: Regex): Directive1[String]

Description

The def host(hostNames: String*) overload rejects all requests with a hostname different from the given ones.

The def host(predicate: String => Boolean) overload rejects all requests for which the hostname does not satisfy the given predicate.

There are a few variants:

The def host(regex: Regex) overloadregular expression matching works a little bit different: it rejects all requests with a hostname that doesn’t have a prefix matching the given regular expression and also extracts a String to its inner route following this rules:

Example

Matching a list of hosts:

Scala

source`val route = host("api.company.com", "rest.company.com") { complete("Ok") }

// tests: Get() ~> Host("rest.company.com") ~> route ~> check { status shouldEqual OK responseAs[String] shouldEqual "Ok" }

Get() ~> Host("notallowed.company.com") ~> route ~> check { handled shouldBe false }`

Java

source`import static akka.http.javadsl.server.Directives.complete; import static akka.http.javadsl.server.Directives.host;

final Route matchListOfHosts = host( Arrays.asList("api.company.com", "rest.company.com"), () -> complete(StatusCodes.OK));

testRoute(matchListOfHosts).run(HttpRequest.GET("/").addHeader(Host.create("api.company.com"))) .assertStatusCode(StatusCodes.OK);`

Making sure the host satisfies the given predicate

Scala

source`val shortOnly: String => Boolean = (hostname) => hostname.length < 10

val route = host(shortOnly) { complete("Ok") }

// tests: Get() ~> Host("short.com") ~> route ~> check { status shouldEqual OK responseAs[String] shouldEqual "Ok" }

Get() ~> Host("verylonghostname.com") ~> route ~> check { handled shouldBe false }`

Java

source`import static akka.http.javadsl.server.Directives.complete; import static akka.http.javadsl.server.Directives.host;

final Route shortOnly = host(hostname -> hostname.length() < 10, () -> complete(StatusCodes.OK));

testRoute(shortOnly).run(HttpRequest.GET("/").addHeader(Host.create("short.com"))) .assertStatusCode(StatusCodes.OK);

testRoute(shortOnly).run(HttpRequest.GET("/").addHeader(Host.create("verylonghostname.com"))) .assertStatusCode(StatusCodes.NOT_FOUND);`

Using a regular expressions:

Scala

source`val route = concat( host("api|rest".r) { prefix => complete(s"Extracted prefix: $prefix") }, host("public.(my|your)company.com".r) { captured => complete(s"You came through $captured company") } )

// tests: Get() ~> Host("api.company.com") ~> route ~> check { status shouldEqual OK responseAs[String] shouldEqual "Extracted prefix: api" }

Get() ~> Host("public.mycompany.com") ~> route ~> check { status shouldEqual OK responseAs[String] shouldEqual "You came through my company" }`

Java

source`import akka.http.javadsl.server.Directives;

import static akka.http.javadsl.server.Directives.host;

final Route hostPrefixRoute = host(Pattern.compile("api|rest"), prefix -> complete("Extracted prefix: " + prefix));

final Route hostPartRoute = host(Pattern.compile("public.(my|your)company.com"), captured -> complete("You came through " + captured + " company"));

final Route route = Directives.concat(hostPrefixRoute, hostPartRoute);

testRoute(route).run(HttpRequest.GET("/").addHeader(Host.create("api.company.com"))) .assertStatusCode(StatusCodes.OK).assertEntity("Extracted prefix: api");

testRoute(route).run(HttpRequest.GET("/").addHeader(Host.create("public.mycompany.com"))) .assertStatusCode(StatusCodes.OK) .assertEntity("You came through my company");`

Beware that in the case of introducing multiple capturing groups in the regex such as in the case bellow, the directive will fail at runtime, at the moment the route tree is evaluated for the first time. This might cause your http handler actor to enter in a fail/restart loop depending on your supervision strategy.

Scala

sourcean[IllegalArgumentException] should be thrownBy { host("server-([0-9]).company.(com|net|org)".r) { target => complete("Will never complete :'(") } }

Java

source// this will throw IllegalArgumentException final Route hostRegex = host(Pattern.compile("server-([0-9]).company.(com|net|org)"), s -> // will not reach here complete(s) );

Found an error in this documentation? The source code for this page can be found here. Please feel free to edit and contribute a pull request.