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:
drewhk 2015-08-14 11:39:47 +02:00
commit a89d7591f8
2 changed files with 40 additions and 2 deletions

View file

@ -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

View file

@ -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")