Currently it looks like setting illegal-response-header-value-processing-mode has no effect with the Authorization header:
private def handleRequest(request: HttpRequest): Future[HttpResponse] = {
val headers = HttpHeader.parse("Authorization", "invalid") match {
case ParsingResult.Ok(header, _) =>
header::Nil
case _ => sys.error("FAILURE")
}
Future.successful(HttpResponse(headers = headers))
}
def main(args: Array[String]): Unit = {
implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
implicit val ec = system.dispatcher
val parserSettings = ParserSettings(system).withIllegalResponseHeaderValueProcessingMode(ParserSettings.IllegalResponseHeaderValueProcessingMode.Warn)
val serverSettings = ServerSettings(system).withParserSettings(parserSettings)
Http()
.bindAndHandleAsync(
handler = handleRequest,
interface = "0.0.0.0",
port = 3128,
settings = serverSettings)
}
curl:
schmitch@SHANGHAI:~$ curl -v localhost:3128
* Rebuilt URL to: localhost:3128/
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 3128 (#0)
> GET / HTTP/1.1
> Host: localhost:3128
> User-Agent: curl/7.51.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: akka-http/10.0.9
< Date: Tue, 04 Jul 2017 10:15:14 GMT
< Content-Length: 0
<
I would expect to have Authorization: invalid inside the response.
Warning:
[WARN] [07/04/2017 12:20:59.379] [default-akka.actor.default-dispatcher-3] [akka.actor.ActorSystemImpl(default)] HTTP header 'Authorization: invalid' is not allowed in responses
Reference: https://github.com/playframework/playframework/issues/7549
Looks like HttpResponseRendererFactory:177
@schmitch,
@raboof pointed out to me that Authorization is in fact a request header, not a response one. See my comment here: https://github.com/playframework/playframework/issues/7549#issuecomment-312881103
Anyway, looks like having illegal-response-header-value-processing-mode configured to ignore should enable users to include this header. Not sure about the exact semantics about this configuration though.
I'm actually not sure illegal-response-header-value-processing-mode is the right thing here: it is documented in the reference.conf as:
# Configures the processing mode when encountering illegal characters in
# header value of response.
#
# Supported mode:
# `error` : default mode, throw an ParsingException and terminate the processing
# `warn` : ignore the illegal characters in response header value and log a warning message
# `ignore` : just ignore the illegal characters in response header value
illegal-response-header-value-processing-mode = error
Note that this is about the situation "when encountering illegal characters in header value of response". In this case the problem with the Authorization header is not that it contains illegal characters, but that it is a RequestHeader and thus has renderInRequests set to true and renderInResponses set to false.
I wonder if modelling it as a RawHeader for this situation would work, I'm not actually completely sure.
actually rendering a RawHeader works:
https://github.com/playframework/playframework/pull/7557
However I still think it should be configurable, maybe with a different setting?
I guess, it's a general question if the current renderInRequests / renderInResponses flags are useful or if they prevents uncommon but legitimate uses. Fortunately, there's the RawHeader workaround for now.
hm, true. I think most headers should be just forwarded to the user, besides the fact that they are not defined in the specification or only defined for requests/responses.
It's not that they are spec validations, when an Authorization header or a If-Range header appears inside the response.
I think the case (and for http2):
case x ⇒
if (x.renderInResponses) render(x)
else log.warning("HTTP header '{}' is not allowed in responses", x)
is maybe not suitable. The spec only define's these headers and how to handle them when they are inside a request or inside a response: https://tools.ietf.org/html/rfc2616#section-14. But in no way does the spec describe what to do when they appear elsewhere.
Well https://tools.ietf.org/html/rfc4229 has good introduction:
Note that neither tracks the syntax or semantics of field-values.
Also, while some HTTP headers have different semantics depending on
their context (e.g., Cache-Control in requests and responses), both
registries consider the HTTP header field-name name space singular.
which from my understanding says that they are both valid in response/request. Or that's how I would interpret the "the HTTP header field-name name space singular".
I like the idea of removing renderInRequests / renderInResponses and just rendering whatever headers are added to the request/response - seems to make things simpler generally. Might be good to check when/why those were introduced, though.
It was that PR: https://github.com/akka/akka/pull/19526
I think we definitely need some way to prevent some headers to be rendered at all (which we had with suppressRendering before).
Hard to say how to go back to that behavior in a compatible way.
Which headers should be suppressed / not rendered? (besides some RawHeaders that are still handled special? at least in http/1)
Most helpful comment
I guess, it's a general question if the current
renderInRequests/renderInResponsesflags are useful or if they prevents uncommon but legitimate uses. Fortunately, there's theRawHeaderworkaround for now.