add Strict-Transport-Security header #19861
fix the signature of Strict-Transport-Security header #19861 parse strict-transport-security header with the max-age directive only #19861 parse includeSubDomains directive #19861 add doc on Stict-Transport-Security #19861 fix punctuation in doc on Stict-Transport-Security #19861
This commit is contained in:
parent
06b4d54960
commit
78ad0c63d3
6 changed files with 55 additions and 0 deletions
|
|
@ -282,6 +282,16 @@ Connection
|
|||
request's method, protocol and potential ``Connection`` header as well as the response's protocol, entity and
|
||||
potential ``Connection`` header. See `this test`__ for a full table of what happens when.
|
||||
|
||||
Strict-Transport-Security
|
||||
HTTP Strict Transport Security (HSTS) is a web security policy mechanism which is communicated by the
|
||||
``Strict-Transport-Security`` header. The most important security vulnerability that HSTS can fix is SSL-stripping
|
||||
man-in-the-middle attacks. The SSL-stripping attact works by transparently converting a secure HTTPS connection into a
|
||||
plain HTTP connection. The user can see that the connection is insecure, but crucially there is no way of knowing
|
||||
whether the connection should be secure. HSTS addresses this problem by informing the browser that connections to the
|
||||
site should always use TLS/SSL. See also `RFC 6797`_.
|
||||
|
||||
.. _RFC 6797: http://tools.ietf.org/html/rfc6797
|
||||
|
||||
__ @github@/akka-http-core/src/test/scala/akka/http/impl/engine/rendering/ResponseRendererSpec.scala#L422
|
||||
|
||||
Custom Headers
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2016 Lightbend Inc. <http://www.lightbend.com>
|
||||
*/
|
||||
|
||||
package akka.http.javadsl.model.headers;
|
||||
|
||||
/**
|
||||
* Model for the `Strict-Transport-Security` header.
|
||||
* Specification: https://tools.ietf.org/html/rfc6797
|
||||
*/
|
||||
public abstract class StrictTransportSecurity extends akka.http.scaladsl.model.HttpHeader {
|
||||
public abstract long maxAge();
|
||||
public abstract boolean includeSubDomains();
|
||||
|
||||
public static StrictTransportSecurity create(long maxAge) {
|
||||
return new akka.http.scaladsl.model.headers.Strict$minusTransport$minusSecurity(maxAge, false);
|
||||
}
|
||||
public static StrictTransportSecurity create(long maxAge, boolean includeSubDomains) {
|
||||
return new akka.http.scaladsl.model.headers.Strict$minusTransport$minusSecurity(maxAge, includeSubDomains);
|
||||
}
|
||||
}
|
||||
|
|
@ -150,6 +150,7 @@ private[http] object HeaderParser {
|
|||
"sec-websocket-protocol",
|
||||
"sec-websocket-version",
|
||||
"set-cookie",
|
||||
"strict-transport-security",
|
||||
"transfer-encoding",
|
||||
"upgrade",
|
||||
"user-agent",
|
||||
|
|
|
|||
|
|
@ -186,6 +186,10 @@ private[parser] trait SimpleHeaders { this: Parser with CommonRules with CommonA
|
|||
// http://tools.ietf.org/html/rfc7231#section-7.4.2
|
||||
def server = rule { products ~ EOI ~> (Server(_)) }
|
||||
|
||||
def `strict-transport-security` = rule {
|
||||
ignoreCase("max-age=") ~ `delta-seconds` ~ optional(ws(";") ~ ignoreCase("includesubdomains") ~ push(true)) ~ EOI ~> (`Strict-Transport-Security`(_, _))
|
||||
}
|
||||
|
||||
// http://tools.ietf.org/html/rfc7230#section-3.3.1
|
||||
def `transfer-encoding` = rule {
|
||||
oneOrMore(`transfer-coding`).separatedBy(listSep) ~ EOI ~> (`Transfer-Encoding`(_))
|
||||
|
|
|
|||
|
|
@ -791,6 +791,19 @@ final case class Server(products: immutable.Seq[ProductVersion]) extends jm.head
|
|||
def getProducts: Iterable[jm.headers.ProductVersion] = products.asJava
|
||||
}
|
||||
|
||||
// https://tools.ietf.org/html/rfc6797
|
||||
object `Strict-Transport-Security` extends ModeledCompanion[`Strict-Transport-Security`] {
|
||||
def apply(maxAge: Long, includeSubDomains: Option[Boolean]) = new `Strict-Transport-Security`(maxAge, includeSubDomains.getOrElse(false))
|
||||
}
|
||||
final case class `Strict-Transport-Security`(maxAge: Long, includeSubDomains: Boolean = false) extends jm.headers.StrictTransportSecurity with ResponseHeader {
|
||||
def renderValue[R <: Rendering](r: R): r.type = {
|
||||
r ~~ "max-age=" ~~ maxAge
|
||||
if (includeSubDomains) r ~~ "; includeSubDomains"
|
||||
r
|
||||
}
|
||||
protected def companion = `Strict-Transport-Security`
|
||||
}
|
||||
|
||||
// https://tools.ietf.org/html/rfc6265
|
||||
object `Set-Cookie` extends ModeledCompanion[`Set-Cookie`]
|
||||
final case class `Set-Cookie`(cookie: HttpCookie) extends jm.headers.SetCookie with ResponseHeader {
|
||||
|
|
|
|||
|
|
@ -386,6 +386,12 @@ class HttpHeaderSpec extends FreeSpec with Matchers {
|
|||
"Server: as fghf.fdf/xx" =!= `Server`(Vector(ProductVersion("as"), ProductVersion("fghf.fdf", "xx")))
|
||||
}
|
||||
|
||||
"Strict-Transport-Security" in {
|
||||
"Strict-Transport-Security: max-age=31536000" =!= `Strict-Transport-Security`(maxAge = 31536000)
|
||||
"Strict-Transport-Security: max-age=31536000" =!= `Strict-Transport-Security`(maxAge = 31536000, includeSubDomains = false)
|
||||
"Strict-Transport-Security: max-age=31536000; includeSubDomains" =!= `Strict-Transport-Security`(maxAge = 31536000, includeSubDomains = true)
|
||||
}
|
||||
|
||||
"Transfer-Encoding" in {
|
||||
"Transfer-Encoding: chunked" =!= `Transfer-Encoding`(TransferEncodings.chunked)
|
||||
"Transfer-Encoding: gzip" =!= `Transfer-Encoding`(TransferEncodings.gzip)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue