Skip to main content

Host and Scheme Directives

Host directives provide filtering and extraction based on the request's host (its URI authority or Host header). Scheme directives operate on the URI scheme (e.g., http or https).

Host Directives​

extractHost​

Extracts the hostname of the request as a String, as Pekko does from the request's effective URI: the authority of the request URI (an absolute-form request, or an HTTP/2 request's :authority), else the Host header (RFC 7230 5.4). A host name is lowercased (as Pekko's URI parser does), an IPv6 address comes without brackets in its canonical form (::1), and the result is "" when the request names no host, or when the URI authority and the Host header disagree (Pekko answers 400 then; here host(...) rejects rather than trust either). Ember 0.23.36 drops an HTTP/2 request's :authority (it parses the value as a URI and finds no authority), so an HTTP/2 request that carries its host only there (prior knowledge, HTTP/2 over TLS) has no host over Ember and host(...) rejects it; the first request of an h2c upgrade, or one with a host header, still has one.

val route: Route = extractHost { hostname =>
complete(s"Host: $hostname")
}

host (name matching)​

Rejects the request if the hostname does not match any of the given names.

val route: Route = host("example.com", "www.example.com") {
complete("Matched host")
}

host (predicate)​

Rejects the request if the predicate returns false for the hostname.

val route: Route = host(_.endsWith(".example.com")) {
complete("Subdomain of example.com")
}

host (regex)​

Matches the hostname against a regular expression. If the regex contains no capturing group, the matched prefix is extracted. If it contains exactly one capturing group, the captured string is extracted. More than one capturing group throws an IllegalArgumentException.

import scala.util.matching.Regex

val route: Route = host("""(\w+)\.example\.com""".r) { subdomain =>
complete(s"Subdomain: $subdomain")
}

Scheme Directives​

extractScheme​

Extracts the URI scheme of the request as a String. On a server the request line usually carries no scheme, so the directive first looks at the connection the request arrived on (https for a TLS connection, http otherwise) and only then at the request line; it yields an empty string when neither is known. Behind a proxy that terminates TLS the connection is plain http; read X-Forwarded-Proto yourself in that case.

val route: Route = extractScheme { scheme =>
complete(s"Scheme: $scheme")
}

scheme​

Rejects the request if the URI scheme does not match the given name. Rejected requests receive a SchemeRejection.

val route: Route = scheme("https") {
complete("Secure connection")
}