in http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/HttpMessage.scala [474:508]
def effectiveUri(
uri: Uri, headers: immutable.Seq[HttpHeader], securedConnection: Boolean, defaultHostHeader: Host): Uri = {
@tailrec def findHostAndWsUpgrade(it: Iterator[HttpHeader], host: OptionVal[Host] = OptionVal.None,
wsUpgrade: Option[Boolean] = None): (OptionVal[Host], Boolean) =
if (host.isDefined && wsUpgrade.isDefined || !it.hasNext)
(host, wsUpgrade.contains(true))
else
it.next() match {
case h: Host => findHostAndWsUpgrade(it, OptionVal.Some(h), wsUpgrade)
case u: Upgrade => findHostAndWsUpgrade(it, host, Some(u.hasWebSocket))
case _ => findHostAndWsUpgrade(it, host, wsUpgrade)
}
val (hostHeader, isWebsocket) = findHostAndWsUpgrade(headers.iterator)
if (uri.isRelative) {
def fail(detail: String) =
throw IllegalUriException(
s"Cannot establish effective URI of request to `$uri`, request has a relative URI and $detail",
"consider setting `pekko.http.server.default-host-header`")
val Host(hostHeaderHost, hostHeaderPort) = hostHeader match {
case OptionVal.None => if (defaultHostHeader.isEmpty) fail("is missing a `Host` header") else defaultHostHeader
case OptionVal.Some(x) if x.isEmpty =>
if (defaultHostHeader.isEmpty) fail("an empty `Host` header") else defaultHostHeader
case OptionVal.Some(x) => x
}
val defaultScheme =
if (isWebsocket) Uri.websocketScheme(securedConnection)
else Uri.httpScheme(securedConnection)
uri.toEffectiveRequestUri(hostHeaderHost, hostHeaderPort, defaultScheme)
} else // http://tools.ietf.org/html/rfc7230#section-5.4
if (hostHeader.isEmpty || uri.authority.isEmpty && hostHeader.get.isEmpty ||
hostHeader.get.host.equalsIgnoreCase(uri.authority.host) && hostHeader.get.port == uri.authority.port) uri
else throw IllegalUriException(
s"'Host' header value of request to `$uri` doesn't match request target authority",
s"Host header: $hostHeader\nrequest target authority: ${uri.authority}")
}