+htc #16084 introduce CustomHeader superclass for user-defined headers

This commit is contained in:
Johannes Rudolph 2014-11-04 16:08:31 +01:00
parent 159adb79b3
commit 11f293731f
6 changed files with 93 additions and 0 deletions

View file

@ -0,0 +1,12 @@
/*
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.http.model.japi.headers;
public abstract class CustomHeader extends akka.http.model.HttpHeader {
public abstract String name();
public abstract String value();
protected abstract boolean suppressRendering();
}

View file

@ -77,6 +77,10 @@ private[http] class HttpRequestRendererFactory(userAgentHeader: Option[headers.`
case x: `Raw-Request-URI` // we never render this header
renderHeaders(tail, hostHeaderSeen, userAgentSeen, transferEncodingSeen)
case x: CustomHeader
if (!x.suppressRendering) render(x)
renderHeaders(tail, hostHeaderSeen, userAgentSeen, transferEncodingSeen)
case x: RawHeader if (x is "content-type") || (x is "content-length") || (x is "transfer-encoding") ||
(x is "host") || (x is "user-agent")
suppressionWarning(log, x, "illegal RawHeader")

View file

@ -105,6 +105,10 @@ private[http] class HttpResponseRendererFactory(serverHeader: Option[headers.Ser
render(x)
renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen = true, transferEncodingSeen)
case x: CustomHeader
if (!x.suppressRendering) render(x)
renderHeaders(tail, alwaysClose, connHeader, serverHeaderSeen, transferEncodingSeen)
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")

View file

@ -30,6 +30,17 @@ sealed trait ModeledHeader extends HttpHeader with Serializable {
protected def companion: ModeledCompanion
}
/**
* Superclass for user-defined custom headers defined by implementing `name` and `value`.
*/
abstract class CustomHeader extends japi.headers.CustomHeader {
/** Override to return true if this header shouldn't be rendered */
def suppressRendering: Boolean = false
def lowercaseName: String = name.toRootLowerCase
def render[R <: Rendering](r: R): r.type = r ~~ name ~~ ':' ~~ ' ' ~~ value
}
import japi.JavaMapping.Implicits._
// http://tools.ietf.org/html/rfc7230#section-6.1

View file

@ -190,6 +190,35 @@ class RequestRendererSpec extends FreeSpec with Matchers with BeforeAndAfterAll
}
}
}
"render a CustomHeader header" - {
"if suppressRendering = false" in new TestSetup(None) {
case class MyHeader(number: Int) extends CustomHeader {
def name: String = "X-My-Header"
def value: String = s"No$number"
}
HttpRequest(GET, "/abc", List(MyHeader(5))) should renderTo {
"""GET /abc HTTP/1.1
|X-My-Header: No5
|Host: test.com:8080
|
|"""
}
}
"not if suppressRendering = true" in new TestSetup(None) {
case class MyInternalHeader(number: Int) extends CustomHeader {
override def suppressRendering: Boolean = true
def name: String = "X-My-Internal-Header"
def value: String = s"No$number"
}
HttpRequest(GET, "/abc", List(MyInternalHeader(5))) should renderTo {
"""GET /abc HTTP/1.1
|Host: test.com:8080
|
|"""
}
}
}
"properly use URI from Raw-Request-URI header if present" - {
"GET request with Raw-Request-URI" in new TestSetup() {

View file

@ -4,6 +4,7 @@
package akka.http.engine.rendering
import akka.http.model.HttpMethods._
import com.typesafe.config.{ Config, ConfigFactory }
import scala.concurrent.duration._
import scala.concurrent.Await
@ -314,6 +315,38 @@ class ResponseRendererSpec extends FreeSpec with Matchers with BeforeAndAfterAll
}
}
"render a CustomHeader header" - {
"if suppressRendering = false" in new TestSetup(None) {
case class MyHeader(number: Int) extends CustomHeader {
def name: String = "X-My-Header"
def value: String = s"No$number"
}
HttpResponse(200, List(MyHeader(5))) should renderTo {
"""HTTP/1.1 200 OK
|X-My-Header: No5
|Date: Thu, 25 Aug 2011 09:10:29 GMT
|Content-Length: 0
|
|"""
}
}
"not if suppressRendering = true" in new TestSetup(None) {
case class MyInternalHeader(number: Int) extends CustomHeader {
override def suppressRendering: Boolean = true
def name: String = "X-My-Internal-Header"
def value: String = s"No$number"
}
HttpResponse(200, List(MyInternalHeader(5))) should renderTo {
"""HTTP/1.1 200 OK
|Date: Thu, 25 Aug 2011 09:10:29 GMT
|Content-Length: 0
|
|"""
}
}
}
"The 'Connection' header should be rendered correctly" in new TestSetup() {
import org.scalatest.prop.TableDrivenPropertyChecks._
import HttpProtocols._