diff --git a/akka-http-core/src/main/scala/akka/http/engine/rendering/HttpResponseRendererFactory.scala b/akka-http-core/src/main/scala/akka/http/engine/rendering/HttpResponseRendererFactory.scala index 04e1f5309e..a7b9578ebb 100644 --- a/akka-http-core/src/main/scala/akka/http/engine/rendering/HttpResponseRendererFactory.scala +++ b/akka-http-core/src/main/scala/akka/http/engine/rendering/HttpResponseRendererFactory.scala @@ -74,57 +74,57 @@ private[http] class HttpResponseRendererFactory(serverHeader: Option[headers.Ser @tailrec def renderHeaders(remaining: List[HttpHeader], alwaysClose: Boolean = false, connHeader: Connection = null, serverHeaderSeen: Boolean = false, - transferEncodingSeen: Boolean = false): Unit = + transferEncodingSeen: Boolean = false, dateSeen: Boolean = false): Unit = remaining match { case head :: tail ⇒ head match { case x: `Content-Length` ⇒ suppressionWarning(log, x, "explicit `Content-Length` header is not allowed. Use the appropriate HttpEntity subtype.") - renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen) + renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen, dateSeen) case x: `Content-Type` ⇒ suppressionWarning(log, x, "explicit `Content-Type` header is not allowed. Set `HttpResponse.entity.contentType` instead.") - renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen) + renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen, dateSeen) - case Date(_) ⇒ - suppressionWarning(log, head) - renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen) + case x: Date ⇒ + render(x) + renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen, dateSeen = true) case x: `Transfer-Encoding` ⇒ x.withChunkedPeeled match { case None ⇒ suppressionWarning(log, head) - renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen) + renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen, dateSeen) case Some(te) ⇒ // if the user applied some custom transfer-encoding we need to keep the header render(if (mustRenderTransferEncodingChunkedHeader) te.withChunked else te) - renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen = true) + renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen = true, dateSeen) } case x: `Connection` ⇒ val connectionHeader = if (connHeader eq null) x else Connection(x.tokens ++ connHeader.tokens) - renderHeaders(tail, alwaysClose, connectionHeader, serverHeaderSeen, transferEncodingSeen) + renderHeaders(tail, alwaysClose, connectionHeader, serverHeaderSeen, transferEncodingSeen, dateSeen) case x: `Server` ⇒ render(x) - renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen = true, transferEncodingSeen) + renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen = true, transferEncodingSeen, dateSeen) case x: CustomHeader ⇒ if (!x.suppressRendering) render(x) - renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen) + renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen, dateSeen) case x: RawHeader if (x is "content-type") || (x is "content-length") || (x is "transfer-encoding") || (x is "date") || (x is "server") || (x is "connection") ⇒ suppressionWarning(log, x, "illegal RawHeader") - renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen) + renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen, dateSeen) case x ⇒ render(x) - renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen) + renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen, dateSeen) } case Nil ⇒ if (!serverHeaderSeen) renderDefaultServerHeader(r) - r ~~ dateHeader + if (!dateSeen) r ~~ dateHeader close = alwaysClose || ctx.closeAfterResponseCompletion || // request wants to close (connHeader != null && connHeader.hasClose) // application wants to close diff --git a/akka-http-core/src/test/scala/akka/http/engine/rendering/ResponseRendererSpec.scala b/akka-http-core/src/test/scala/akka/http/engine/rendering/ResponseRendererSpec.scala index 63492ba916..6b3949a536 100644 --- a/akka-http-core/src/test/scala/akka/http/engine/rendering/ResponseRendererSpec.scala +++ b/akka-http-core/src/test/scala/akka/http/engine/rendering/ResponseRendererSpec.scala @@ -43,6 +43,17 @@ class ResponseRendererSpec extends FreeSpec with Matchers with BeforeAndAfterAll } } + "a custom Date header" in new TestSetup() { + HttpResponse(200, List(Date(DateTime(2011, 8, 26, 10, 11, 59)))) should renderTo { + """HTTP/1.1 200 OK + |Date: Fri, 26 Aug 2011 10:11:59 GMT + |Server: akka-http/1.0.0 + |Content-Length: 0 + | + |""" + } + } + "status 304 and a few headers" in new TestSetup() { HttpResponse(304, List(RawHeader("X-Fancy", "of course"), RawHeader("Age", "0"))) should renderTo { """HTTP/1.1 304 Not Modified