Merge pull request #18194 from spray/w/18044-fix-http-1.0-500-failures
=htc #18044 fail HTTP/1.0 requests with 400 if no default-host-header is set
This commit is contained in:
commit
a89d7591f8
2 changed files with 40 additions and 2 deletions
|
|
@ -55,10 +55,23 @@ private[http] object HttpServerBluePrint {
|
|||
}.withDeploy(Deploy.local)
|
||||
}, errorMsg = "Http.serverLayer is currently not reusable. You need to create a new instance for each materialization.")
|
||||
|
||||
def establishAbsoluteUri(requestOutput: RequestOutput): RequestOutput = requestOutput match {
|
||||
case start: RequestStart ⇒
|
||||
try {
|
||||
val effectiveUri = HttpRequest.effectiveUri(start.uri, start.headers, securedConnection = false, defaultHostHeader)
|
||||
start.copy(uri = effectiveUri)
|
||||
} catch {
|
||||
case e: IllegalUriException ⇒
|
||||
MessageStartError(StatusCodes.BadRequest, ErrorInfo("Request is missing required `Host` header", e.getMessage))
|
||||
}
|
||||
case x ⇒ x
|
||||
}
|
||||
|
||||
val requestParsingFlow = Flow[ByteString].transform(() ⇒
|
||||
// each connection uses a single (private) request parser instance for all its requests
|
||||
// which builds a cache of all header instances seen on that connection
|
||||
rootParser.createShallowCopy(() ⇒ oneHundredContinueRef).stage).named("rootParser")
|
||||
.map(establishAbsoluteUri)
|
||||
|
||||
val requestPreparation =
|
||||
Flow[RequestOutput]
|
||||
|
|
@ -66,14 +79,13 @@ private[http] object HttpServerBluePrint {
|
|||
.via(headAndTailFlow)
|
||||
.map {
|
||||
case (RequestStart(method, uri, protocol, hdrs, createEntity, _, _), entityParts) ⇒
|
||||
val effectiveUri = HttpRequest.effectiveUri(uri, hdrs, securedConnection = false, defaultHostHeader)
|
||||
val effectiveMethod = if (method == HttpMethods.HEAD && transparentHeadRequests) HttpMethods.GET else method
|
||||
val effectiveHeaders =
|
||||
if (settings.remoteAddressHeader && remoteAddress.isDefined)
|
||||
headers.`Remote-Address`(RemoteAddress(remoteAddress.get)) +: hdrs
|
||||
else hdrs
|
||||
|
||||
HttpRequest(effectiveMethod, effectiveUri, effectiveHeaders, createEntity(entityParts), protocol)
|
||||
HttpRequest(effectiveMethod, uri, effectiveHeaders, createEntity(entityParts), protocol)
|
||||
case (_, src) ⇒ src.runWith(Sink.ignore)
|
||||
}.collect {
|
||||
case r: HttpRequest ⇒ r
|
||||
|
|
|
|||
|
|
@ -661,6 +661,32 @@ class HttpServerSpec extends AkkaSpec("akka.loggers = []\n akka.loglevel = OFF")
|
|||
expectRequest shouldEqual HttpRequest(uri = "http://example.com//foo", headers = List(Host("example.com")))
|
||||
}
|
||||
|
||||
"use default-host-header for HTTP/1.0 requests" in new TestSetup {
|
||||
send("""GET /abc HTTP/1.0
|
||||
|
|
||||
|""".stripMarginWithNewline("\r\n"))
|
||||
|
||||
expectRequest shouldEqual HttpRequest(uri = "http://example.com/abc", protocol = HttpProtocols.`HTTP/1.0`)
|
||||
|
||||
override def settings: ServerSettings = super.settings.copy(defaultHostHeader = Host("example.com"))
|
||||
}
|
||||
"fail an HTTP/1.0 request with 400 if no default-host-header is set" in new TestSetup {
|
||||
send("""GET /abc HTTP/1.0
|
||||
|
|
||||
|""".stripMarginWithNewline("\r\n"))
|
||||
|
||||
netOutSub.request(1)
|
||||
wipeDate(netOut.expectNext().utf8String) shouldEqual
|
||||
"""|HTTP/1.1 400 Bad Request
|
||||
|Server: akka-http/test
|
||||
|Date: XXXX
|
||||
|Connection: close
|
||||
|Content-Type: text/plain; charset=UTF-8
|
||||
|Content-Length: 41
|
||||
|
|
||||
|Request is missing required `Host` header""".stripMarginWithNewline("\r\n")
|
||||
}
|
||||
|
||||
"support remote-address-header" in new TestSetup {
|
||||
lazy val theAddress = InetAddress.getByName("127.5.2.1")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue