From cad852025d358cabdbaa6ada9e282994caa2293d Mon Sep 17 00:00:00 2001 From: Konrad Malawski Date: Fri, 25 Sep 2015 15:50:11 +0200 Subject: [PATCH] Actually implement proper cascading --- akka-docs-dev/rst/java/http/http-model.rst | 17 +- .../rst/scala/http/common/http-model.rst | 17 +- .../src/main/resources/reference.conf | 280 +++++------------- .../akka/http/ClientConnectionSettings.scala | 7 +- .../akka/http/ConnectionPoolSettings.scala | 15 +- .../main/scala/akka/http/ParserSettings.scala | 3 +- .../main/scala/akka/http/ServerSettings.scala | 6 +- .../http/impl/util/SettingsCompanion.scala | 6 +- .../http/impl/util/SocketOptionSettings.scala | 6 +- .../client/ClientConfigurationSpec.scala | 27 -- .../engine/client/HttpConfigurationSpec.scala | 141 +++++++++ .../scaladsl/server/RoutingSettings.scala | 2 +- 12 files changed, 260 insertions(+), 267 deletions(-) delete mode 100644 akka-http-core/src/test/scala/akka/http/impl/engine/client/ClientConfigurationSpec.scala create mode 100644 akka-http-core/src/test/scala/akka/http/impl/engine/client/HttpConfigurationSpec.scala diff --git a/akka-docs-dev/rst/java/http/http-model.rst b/akka-docs-dev/rst/java/http/http-model.rst index 9be44c5f3b..4c9deba41a 100644 --- a/akka-docs-dev/rst/java/http/http-model.rst +++ b/akka-docs-dev/rst/java/http/http-model.rst @@ -257,11 +257,14 @@ provided to parse (or render to) Strings or byte arrays. .. note:: Various parsing and rendering settings are available to tweak in the configuration under ``akka.http.client[.parsing]``, - ``akka.http.server[.parsing]`` and ``akka.http.host-connection-pool[.client.parsing]``. Please note that while each of - these sections expose the same parsing options, they will only be used for their respective APIs. For example, changing - a setting inside ``akka.http.client.parsing`` **does not** change the same value in ``akka.http.host-connection-pool.client.parsing``, - as they are different APIs. + ``akka.http.server[.parsing]`` and ``akka.http.host-connection-pool[.client.parsing]``, with defaults for all of these + being defined in the ``akka.http.parsing`` configuration section. - You can check which settings to tweak for which method exposed on the Http object by inspecting their ScalaDoc. - In general though it's as simple as "pool" backed services use the ``host-connection-pool`` section, other clients - which expose ``Flow`` use the ``client`` section, and the server side uses the ``server`` configuration section. \ No newline at end of file + For example, if you want to change a parsing setting for all components, you can set the ``akka.http.parsing.illegal-header-warnings = off`` + value. However this setting can be stil overriden by the more specific sections, like for example ``akka.http.server.parsing.illegal-header-warnings = on``. + In this case both ``client`` and ``host-connection-pool`` APIs will see the setting ``off``, however the server will see ``on``. + + In the case of ``akka.http.host-connection-pool.client`` settings, they default to settings set in ``akka.http.client``, + and can override them if needed. This is useful, since both ``client`` and ``host-connection-pool`` APIs, + such as the Client API ``Http.get(sys).outgoingConnection`` or the Host Connection Pool APIs ``Http.get(sys).singleRequest`` + or ``Http.get(sys).superPool``, usually need the same settings, however the ``server`` most likely has a very different set of settings. diff --git a/akka-docs-dev/rst/scala/http/common/http-model.rst b/akka-docs-dev/rst/scala/http/common/http-model.rst index 6dce80d3d9..152a0b764b 100644 --- a/akka-docs-dev/rst/scala/http/common/http-model.rst +++ b/akka-docs-dev/rst/scala/http/common/http-model.rst @@ -253,11 +253,14 @@ provided to parse (or render to) Strings or byte arrays. .. note:: Various parsing and rendering settings are available to tweak in the configuration under ``akka.http.client[.parsing]``, - ``akka.http.server[.parsing]`` and ``akka.http.host-connection-pool[.client.parsing]``. Please note that while each of - these sections expose the same parsing options, they will only be used for their respective APIs. For example, changing - a setting inside ``akka.http.client.parsing`` **does not** change the same value in ``akka.http.host-connection-pool.client.parsing``, - as they are different APIs. + ``akka.http.server[.parsing]`` and ``akka.http.host-connection-pool[.client.parsing]``, with defaults for all of these + being defined in the ``akka.http.parsing`` configuration section. - You can check which settings to tweak for which method exposed on the Http object by inspecting their ScalaDoc. - In general though it's as simple as "pool" backed services use the ``host-connection-pool`` section, other clients - which expose ``Flow`` use the ``client`` section, and the server side uses the ``server`` configuration section. \ No newline at end of file + For example, if you want to change a parsing setting for all components, you can set the ``akka.http.parsing.illegal-header-warnings = off`` + value. However this setting can be stil overriden by the more specific sections, like for example ``akka.http.server.parsing.illegal-header-warnings = on``. + In this case both ``client`` and ``host-connection-pool`` APIs will see the setting ``off``, however the server will see ``on``. + + In the case of ``akka.http.host-connection-pool.client`` settings, they default to settings set in ``akka.http.client``, + and can override them if needed. This is useful, since both ``client`` and ``host-connection-pool`` APIs, + such as the Client API ``Http().outgoingConnection`` or the Host Connection Pool APIs ``Http().singleRequest`` or ``Http().superPool``, + usually need the same settings, however the ``server`` most likely has a very different set of settings. diff --git a/akka-http-core/src/main/resources/reference.conf b/akka-http-core/src/main/resources/reference.conf index 558c216f99..34a6e5a77e 100644 --- a/akka-http-core/src/main/resources/reference.conf +++ b/akka-http-core/src/main/resources/reference.conf @@ -88,76 +88,8 @@ akka.http { } # Modify to tweak parsing settings on the server-side only. - # - # IMPORTANT: - # Please note that this section is replicated in `client` and `http-connection-pool` parsing { - # The limits for the various parts of the HTTP message parser. - max-uri-length = 2k - max-method-length = 16 - max-response-reason-length = 64 - max-header-name-length = 64 - max-header-value-length = 8k - max-header-count = 64 - max-chunk-ext-length = 256 - max-chunk-size = 1m - - # Maximum content length which should not be exceeded by incoming HttpRequests. - # For file uploads which use the entityBytes Source of an incoming HttpRequest it is safe to - # set this to a very high value (or to `infinite` if feeling very adventurous) as the streaming - # upload will be back-pressured properly by Akka Streams. - # Please note however that this setting is a global property, and is applied to all incoming requests, - # not only file uploads consumed in a streaming fashion, so pick this limit wisely. - max-content-length = 8m - - # Sets the strictness mode for parsing request target URIs. - # The following values are defined: - # - # `strict`: RFC3986-compliant URIs are required, - # a 400 response is triggered on violations - # - # `relaxed`: all visible 7-Bit ASCII chars are allowed - # - # `relaxed-with-raw-query`: like `relaxed` but additionally - # the URI query is not parsed, but delivered as one raw string - # as the `key` value of a single Query structure element. - # - uri-parsing-mode = strict - - # Enables/disables the logging of warning messages in case an incoming - # message (request or response) contains an HTTP header which cannot be - # parsed into its high-level model class due to incompatible syntax. - # Note that, independently of this settings, akka-http will accept messages - # with such headers as long as the message as a whole would still be legal - # under the HTTP specification even without this header. - # If a header cannot be parsed into a high-level model instance it will be - # provided as a `RawHeader`. - # If logging is enabled it is performed with the configured - # `error-logging-verbosity`. - illegal-header-warnings = on - - # Configures the verbosity with which message (request or response) parsing - # errors are written to the application log. - # - # Supported settings: - # `off` : no log messages are produced - # `simple`: a condensed single-line message is logged - # `full` : the full error details (potentially spanning several lines) are logged - error-logging-verbosity = full - - # limits for the number of different values per header type that the - # header cache will hold - header-cache { - default = 12 - Content-MD5 = 0 - Date = 0 - If-Match = 0 - If-Modified-Since = 0 - If-None-Match = 0 - If-Range = 0 - If-Unmodified-Since = 0 - User-Agent = 32 - } + # no overrides by default, see `akka.http.parsing` for default values } } @@ -212,76 +144,8 @@ akka.http { } # Modify to tweak parsing settings on the client-side only. - # - # IMPORTANT: - # Please note that this section is replicated in `server` and `http-connection-pool`. parsing { - # The limits for the various parts of the HTTP message parser. - max-uri-length = 2k - max-method-length = 16 - max-response-reason-length = 64 - max-header-name-length = 64 - max-header-value-length = 8k - max-header-count = 64 - max-chunk-ext-length = 256 - max-chunk-size = 1m - - # Maximum content length which should not be exceeded by incoming HttpRequests. - # For file uploads which use the entityBytes Source of an incoming HttpRequest it is safe to - # set this to a very high value (or to `infinite` if feeling very adventurous) as the streaming - # upload will be back-pressured properly by Akka Streams. - # Please note however that this setting is a global property, and is applied to all incoming requests, - # not only file uploads consumed in a streaming fashion, so pick this limit wisely. - max-content-length = 8m - - # Sets the strictness mode for parsing request target URIs. - # The following values are defined: - # - # `strict`: RFC3986-compliant URIs are required, - # a 400 response is triggered on violations - # - # `relaxed`: all visible 7-Bit ASCII chars are allowed - # - # `relaxed-with-raw-query`: like `relaxed` but additionally - # the URI query is not parsed, but delivered as one raw string - # as the `key` value of a single Query structure element. - # - uri-parsing-mode = strict - - # Enables/disables the logging of warning messages in case an incoming - # message (request or response) contains an HTTP header which cannot be - # parsed into its high-level model class due to incompatible syntax. - # Note that, independently of this settings, akka-http will accept messages - # with such headers as long as the message as a whole would still be legal - # under the HTTP specification even without this header. - # If a header cannot be parsed into a high-level model instance it will be - # provided as a `RawHeader`. - # If logging is enabled it is performed with the configured - # `error-logging-verbosity`. - illegal-header-warnings = on - - # Configures the verbosity with which message (request or response) parsing - # errors are written to the application log. - # - # Supported settings: - # `off` : no log messages are produced - # `simple`: a condensed single-line message is logged - # `full` : the full error details (potentially spanning several lines) are logged - error-logging-verbosity = full - - # limits for the number of different values per header type that the - # header cache will hold - header-cache { - default = 12 - Content-MD5 = 0 - Date = 0 - If-Match = 0 - If-Modified-Since = 0 - If-None-Match = 0 - If-Range = 0 - If-Unmodified-Since = 0 - User-Agent = 32 - } + # no overrides by default, see `akka.http.parsing` for default values } } @@ -376,74 +240,82 @@ akka.http { # IMPORTANT: Please note that this section is replicated in `client` and `server`. parsing { - # The limits for the various parts of the HTTP message parser. - max-uri-length = 2k - max-method-length = 16 - max-response-reason-length = 64 - max-header-name-length = 64 - max-header-value-length = 8k - max-header-count = 64 - max-chunk-ext-length = 256 - max-chunk-size = 1m - - # Maximum content length which should not be exceeded by incoming HttpRequests. - # For file uploads which use the entityBytes Source of an incoming HttpRequest it is safe to - # set this to a very high value (or to `infinite` if feeling very adventurous) as the streaming - # upload will be back-pressured properly by Akka Streams. - # Please note however that this setting is a global property, and is applied to all incoming requests, - # not only file uploads consumed in a streaming fashion, so pick this limit wisely. - max-content-length = 8m - - # Sets the strictness mode for parsing request target URIs. - # The following values are defined: - # - # `strict`: RFC3986-compliant URIs are required, - # a 400 response is triggered on violations - # - # `relaxed`: all visible 7-Bit ASCII chars are allowed - # - # `relaxed-with-raw-query`: like `relaxed` but additionally - # the URI query is not parsed, but delivered as one raw string - # as the `key` value of a single Query structure element. - # - uri-parsing-mode = strict - - # Enables/disables the logging of warning messages in case an incoming - # message (request or response) contains an HTTP header which cannot be - # parsed into its high-level model class due to incompatible syntax. - # Note that, independently of this settings, akka-http will accept messages - # with such headers as long as the message as a whole would still be legal - # under the HTTP specification even without this header. - # If a header cannot be parsed into a high-level model instance it will be - # provided as a `RawHeader`. - # If logging is enabled it is performed with the configured - # `error-logging-verbosity`. - illegal-header-warnings = on - - # Configures the verbosity with which message (request or response) parsing - # errors are written to the application log. - # - # Supported settings: - # `off` : no log messages are produced - # `simple`: a condensed single-line message is logged - # `full` : the full error details (potentially spanning several lines) are logged - error-logging-verbosity = full - - # limits for the number of different values per header type that the - # header cache will hold - header-cache { - default = 12 - Content-MD5 = 0 - Date = 0 - If-Match = 0 - If-Modified-Since = 0 - If-None-Match = 0 - If-Range = 0 - If-Unmodified-Since = 0 - User-Agent = 32 - } + # no overrides by default, see `akka.http.parsing` for default values } } } + # Modify to tweak default parsing settings. + # + # IMPORTANT: + # Please note that this sections settings can be overriden by the corresponding settings in: + # `akka.http.server.parsing`, `akka.http.client.parsing` or `akka.http.http-connection-pool.client.parsing`. + parsing { + # The limits for the various parts of the HTTP message parser. + max-uri-length = 2k + max-method-length = 16 + max-response-reason-length = 64 + max-header-name-length = 64 + max-header-value-length = 8k + max-header-count = 64 + max-chunk-ext-length = 256 + max-chunk-size = 1m + + # Maximum content length which should not be exceeded by incoming HttpRequests. + # For file uploads which use the entityBytes Source of an incoming HttpRequest it is safe to + # set this to a very high value (or to `infinite` if feeling very adventurous) as the streaming + # upload will be back-pressured properly by Akka Streams. + # Please note however that this setting is a global property, and is applied to all incoming requests, + # not only file uploads consumed in a streaming fashion, so pick this limit wisely. + max-content-length = 8m + + # Sets the strictness mode for parsing request target URIs. + # The following values are defined: + # + # `strict`: RFC3986-compliant URIs are required, + # a 400 response is triggered on violations + # + # `relaxed`: all visible 7-Bit ASCII chars are allowed + # + # `relaxed-with-raw-query`: like `relaxed` but additionally + # the URI query is not parsed, but delivered as one raw string + # as the `key` value of a single Query structure element. + # + uri-parsing-mode = strict + + # Enables/disables the logging of warning messages in case an incoming + # message (request or response) contains an HTTP header which cannot be + # parsed into its high-level model class due to incompatible syntax. + # Note that, independently of this settings, akka-http will accept messages + # with such headers as long as the message as a whole would still be legal + # under the HTTP specification even without this header. + # If a header cannot be parsed into a high-level model instance it will be + # provided as a `RawHeader`. + # If logging is enabled it is performed with the configured + # `error-logging-verbosity`. + illegal-header-warnings = on + + # Configures the verbosity with which message (request or response) parsing + # errors are written to the application log. + # + # Supported settings: + # `off` : no log messages are produced + # `simple`: a condensed single-line message is logged + # `full` : the full error details (potentially spanning several lines) are logged + error-logging-verbosity = full + + # limits for the number of different values per header type that the + # header cache will hold + header-cache { + default = 12 + Content-MD5 = 0 + Date = 0 + If-Match = 0 + If-Modified-Since = 0 + If-None-Match = 0 + If-Range = 0 + If-Unmodified-Since = 0 + User-Agent = 32 + } + } } diff --git a/akka-http-core/src/main/scala/akka/http/ClientConnectionSettings.scala b/akka-http-core/src/main/scala/akka/http/ClientConnectionSettings.scala index dc1aacaa74..1718e7a41f 100644 --- a/akka-http-core/src/main/scala/akka/http/ClientConnectionSettings.scala +++ b/akka-http-core/src/main/scala/akka/http/ClientConnectionSettings.scala @@ -29,14 +29,15 @@ final case class ClientConnectionSettings( } object ClientConnectionSettings extends SettingsCompanion[ClientConnectionSettings]("akka.http.client") { - def fromSubConfig(c: Config) = { + def fromSubConfig(root: Config, inner: Config) = { + val c = inner.withFallback(root.getConfig(prefix)) apply( c.getString("user-agent-header").toOption.map(`User-Agent`(_)), c getFiniteDuration "connecting-timeout", c getPotentiallyInfiniteDuration "idle-timeout", c getIntBytes "request-header-size-hint", - SocketOptionSettings fromSubConfig c.getConfig("socket-options"), - ParserSettings fromSubConfig c.getConfig("parsing")) + SocketOptionSettings.fromSubConfig(root, c.getConfig("socket-options")), + ParserSettings.fromSubConfig(root, c.getConfig("parsing"))) } /** diff --git a/akka-http-core/src/main/scala/akka/http/ConnectionPoolSettings.scala b/akka-http-core/src/main/scala/akka/http/ConnectionPoolSettings.scala index 95f8a2c0b3..b990bd4383 100644 --- a/akka-http-core/src/main/scala/akka/http/ConnectionPoolSettings.scala +++ b/akka-http-core/src/main/scala/akka/http/ConnectionPoolSettings.scala @@ -5,15 +5,14 @@ package akka.http import java.lang.{ Iterable ⇒ JIterable } -import akka.http.scaladsl.HttpsContext -import com.typesafe.config.Config -import scala.collection.immutable -import scala.concurrent.duration.Duration -import akka.japi.Util._ + import akka.actor.ActorSystem import akka.event.LoggingAdapter import akka.http.impl.util._ -import akka.io.Inet +import akka.http.scaladsl.HttpsContext +import com.typesafe.config.Config + +import scala.concurrent.duration.Duration final case class HostConnectionPoolSetup(host: String, port: Int, setup: ConnectionPoolSetup) @@ -46,14 +45,14 @@ final case class ConnectionPoolSettings( } object ConnectionPoolSettings extends SettingsCompanion[ConnectionPoolSettings]("akka.http.host-connection-pool") { - def fromSubConfig(c: Config) = { + def fromSubConfig(root: Config, c: Config) = { apply( c getInt "max-connections", c getInt "max-retries", c getInt "max-open-requests", c getInt "pipelining-limit", c getPotentiallyInfiniteDuration "idle-timeout", - ClientConnectionSettings fromSubConfig c.getConfig("client")) + ClientConnectionSettings.fromSubConfig(root, c.getConfig("client"))) } /** diff --git a/akka-http-core/src/main/scala/akka/http/ParserSettings.scala b/akka-http-core/src/main/scala/akka/http/ParserSettings.scala index 99b74b19a6..9d08dd499a 100644 --- a/akka-http-core/src/main/scala/akka/http/ParserSettings.scala +++ b/akka-http-core/src/main/scala/akka/http/ParserSettings.scala @@ -55,7 +55,8 @@ final case class ParserSettings( } object ParserSettings extends SettingsCompanion[ParserSettings]("akka.http.parsing") { - def fromSubConfig(c: Config) = { + def fromSubConfig(root: Config, inner: Config) = { + val c = inner.withFallback(root.getConfig(prefix)) val cacheConfig = c getConfig "header-cache" apply( diff --git a/akka-http-core/src/main/scala/akka/http/ServerSettings.scala b/akka-http-core/src/main/scala/akka/http/ServerSettings.scala index baba8b8152..e1d4a3197a 100644 --- a/akka-http-core/src/main/scala/akka/http/ServerSettings.scala +++ b/akka-http-core/src/main/scala/akka/http/ServerSettings.scala @@ -45,7 +45,7 @@ object ServerSettings extends SettingsCompanion[ServerSettings]("akka.http.serve } implicit def timeoutsShortcut(s: ServerSettings): Timeouts = s.timeouts - def fromSubConfig(c: Config) = apply( + def fromSubConfig(root: Config, c: Config) = apply( c.getString("server-header").toOption.map(Server(_)), Timeouts( c getPotentiallyInfiniteDuration "idle-timeout", @@ -57,7 +57,7 @@ object ServerSettings extends SettingsCompanion[ServerSettings]("akka.http.serve c getBoolean "verbose-error-messages", c getIntBytes "response-header-size-hint", c getInt "backlog", - SocketOptionSettings fromSubConfig c.getConfig("socket-options"), + SocketOptionSettings.fromSubConfig(root, c.getConfig("socket-options")), defaultHostHeader = HttpHeader.parse("Host", c getString "default-host-header") match { case HttpHeader.ParsingResult.Ok(x: Host, Nil) ⇒ x @@ -65,7 +65,7 @@ object ServerSettings extends SettingsCompanion[ServerSettings]("akka.http.serve val info = result.errors.head.withSummary("Configured `default-host-header` is illegal") throw new ConfigurationException(info.formatPretty) }, - ParserSettings fromSubConfig c.getConfig("parsing")) + ParserSettings.fromSubConfig(root, c.getConfig("parsing"))) def apply(optionalSettings: Option[ServerSettings])(implicit actorRefFactory: ActorRefFactory): ServerSettings = optionalSettings getOrElse apply(actorSystem) diff --git a/akka-http-core/src/main/scala/akka/http/impl/util/SettingsCompanion.scala b/akka-http-core/src/main/scala/akka/http/impl/util/SettingsCompanion.scala index 0d3069f084..0b17652f46 100644 --- a/akka-http-core/src/main/scala/akka/http/impl/util/SettingsCompanion.scala +++ b/akka-http-core/src/main/scala/akka/http/impl/util/SettingsCompanion.scala @@ -15,7 +15,7 @@ import akka.actor.ActorSystem /** * INTERNAL API */ -private[http] abstract class SettingsCompanion[T](prefix: String) { +private[http] abstract class SettingsCompanion[T](protected val prefix: String) { private final val MaxCached = 8 private[this] var cache = ListMap.empty[ActorSystem, T] @@ -41,9 +41,9 @@ private[http] abstract class SettingsCompanion[T](prefix: String) { .withFallback(defaultReference(getClass.getClassLoader))) def apply(config: Config): T = - fromSubConfig(config getConfig prefix) + fromSubConfig(config, config getConfig prefix) - def fromSubConfig(c: Config): T + def fromSubConfig(root: Config, c: Config): T } private[http] object SettingsCompanion { diff --git a/akka-http-core/src/main/scala/akka/http/impl/util/SocketOptionSettings.scala b/akka-http-core/src/main/scala/akka/http/impl/util/SocketOptionSettings.scala index d79e02e6f1..f07d29c182 100644 --- a/akka-http-core/src/main/scala/akka/http/impl/util/SocketOptionSettings.scala +++ b/akka-http-core/src/main/scala/akka/http/impl/util/SocketOptionSettings.scala @@ -12,11 +12,11 @@ import akka.io.Inet.SocketOption import com.typesafe.config.Config private[http] object SocketOptionSettings { - def fromSubConfig(config: Config): immutable.Traversable[SocketOption] = { + def fromSubConfig(root: Config, c: Config): immutable.Traversable[SocketOption] = { def so[T](setting: String)(f: (Config, String) ⇒ T)(cons: T ⇒ SocketOption): List[SocketOption] = - config.getString(setting) match { + c.getString(setting) match { case "undefined" ⇒ Nil - case x ⇒ cons(f(config, setting)) :: Nil + case x ⇒ cons(f(c, setting)) :: Nil } so("so-receive-buffer-size")(_ getIntBytes _)(Inet.SO.ReceiveBufferSize) ::: diff --git a/akka-http-core/src/test/scala/akka/http/impl/engine/client/ClientConfigurationSpec.scala b/akka-http-core/src/test/scala/akka/http/impl/engine/client/ClientConfigurationSpec.scala deleted file mode 100644 index 3966940314..0000000000 --- a/akka-http-core/src/test/scala/akka/http/impl/engine/client/ClientConfigurationSpec.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2009-2014 Typesafe Inc. - */ - -package akka.http.impl.engine.client - -import akka.stream.testkit.AkkaSpec - -class ClientConfigurationSpec extends AkkaSpec { - "Reference configurations" should { - for { - (first, second) ← "akka.http.client" -> "akka.http.host-connection-pool.client" :: - "akka.http.client.parsing" -> "akka.http.host-connection-pool.client.parsing" :: - "akka.http.server.parsing" -> "akka.http.client.parsing" :: - Nil - } s"be consistent for: `$first` and `$second`" in { - configShouldBeEqual("akka.http.client.parsing", "akka.http.host-connection-pool.client.parsing") - } - } - - private def configShouldBeEqual(first: String, second: String): Unit = { - val config = system.settings.config - withClue(s"Config [$first] did not equal [$second]!") { - config.getConfig(first) should ===(config.getConfig(second)) - } - } -} \ No newline at end of file diff --git a/akka-http-core/src/test/scala/akka/http/impl/engine/client/HttpConfigurationSpec.scala b/akka-http-core/src/test/scala/akka/http/impl/engine/client/HttpConfigurationSpec.scala new file mode 100644 index 0000000000..fb8699ebc9 --- /dev/null +++ b/akka-http-core/src/test/scala/akka/http/impl/engine/client/HttpConfigurationSpec.scala @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2009-2014 Typesafe Inc. + */ + +package akka.http.impl.engine.client + +import akka.actor.ActorSystem +import akka.http.{ ClientConnectionSettings, ConnectionPoolSettings, ServerSettings } +import akka.stream.testkit.AkkaSpec +import com.typesafe.config.ConfigFactory + +class HttpConfigurationSpec extends AkkaSpec { + + val On = true + val Off = false + + "Reference configurations" should { + "have default client and server `parsing` settings" in { + ServerSettings(system).parserSettings.toString should ===(ClientConnectionSettings(system).parserSettings.toString) + } + "have default client and pool `parsing` settings" in { + ServerSettings(system).parserSettings.toString should ===(ConnectionPoolSettings(system).connectionSettings.parserSettings.toString) + } + "have default client and pool `client` settings" in { + ClientConnectionSettings(system).toString should ===(ConnectionPoolSettings(system).connectionSettings.toString) + } + + "override value from `akka.http.parsing` by setting `akka.http.client.parsing`" in { + configuredSystem("""akka.http.client.parsing.illegal-header-warnings = off""") { sys ⇒ + val client = ClientConnectionSettings(sys) + client.parserSettings.illegalHeaderWarnings should ===(Off) + + val pool = ConnectionPoolSettings(sys) + pool.connectionSettings.parserSettings.illegalHeaderWarnings should ===(Off) + + val server = ServerSettings(sys) + server.parserSettings.illegalHeaderWarnings should ===(On) + } + } + + "override `akka.http.parsing` by setting `akka.http.host-connection-pool.client.parsing` setting" in { + configuredSystem("""akka.http.host-connection-pool.client.parsing.illegal-header-warnings = off""") { sys ⇒ + val client = ClientConnectionSettings(sys) + client.parserSettings.illegalHeaderWarnings should ===(On) + + val pool = ConnectionPoolSettings(sys) + pool.connectionSettings.parserSettings.illegalHeaderWarnings should ===(Off) + + val server = ServerSettings(sys) + server.parserSettings.illegalHeaderWarnings should ===(On) + } + } + + "set `akka.http.host-connection-pool.client.idle-timeout` only" in { + configuredSystem("""akka.http.host-connection-pool.client.idle-timeout = 1337s""") { sys ⇒ + import scala.concurrent.duration._ + + val client = ClientConnectionSettings(sys) + client.idleTimeout should ===(60.seconds) + + val pool = ConnectionPoolSettings(sys) + pool.connectionSettings.idleTimeout should ===(1337.seconds) + + val server = ServerSettings(sys) + server.idleTimeout should ===(60.seconds) // no change, default akka.http.server.idle-timeout + } + } + "set `akka.http.server.idle-timeout` only" in { + configuredSystem("""akka.http.server.idle-timeout = 1337s""") { sys ⇒ + import scala.concurrent.duration._ + + val client = ClientConnectionSettings(sys) + client.idleTimeout should ===(60.seconds) + + val pool = ConnectionPoolSettings(sys) + pool.connectionSettings.idleTimeout should ===(60.seconds) + + val server = ServerSettings(sys) + server.idleTimeout should ===(1337.seconds) + } + } + + "change parser settings for all by setting `akka.http.parsing`" in { + configuredSystem("""akka.http.parsing.illegal-header-warnings = off""") { sys ⇒ + val client = ClientConnectionSettings(sys) + client.parserSettings.illegalHeaderWarnings should ===(Off) + + val pool = ConnectionPoolSettings(sys) + pool.connectionSettings.parserSettings.illegalHeaderWarnings should ===(Off) + + val server = ServerSettings(sys) + server.parserSettings.illegalHeaderWarnings should ===(Off) + } + } + + "change parser settings for all by setting `akka.http.parsing`, unless client/server override it" in { + configuredSystem(""" + akka.http { + parsing.illegal-header-warnings = off + server.parsing.illegal-header-warnings = on + client.parsing.illegal-header-warnings = on // also affects host-connection-pool.client + }""") { sys ⇒ + val client = ClientConnectionSettings(sys) + client.parserSettings.illegalHeaderWarnings should ===(On) + + val pool = ConnectionPoolSettings(sys) + pool.connectionSettings.parserSettings.illegalHeaderWarnings should ===(On) + + val server = ServerSettings(sys) + server.parserSettings.illegalHeaderWarnings should ===(On) + } + } + + "change parser settings for all by setting `akka.http.parsing`, unless all override it" in { + configuredSystem(""" + akka.http { + parsing.illegal-header-warnings = off + server.parsing.illegal-header-warnings = on + client.parsing.illegal-header-warnings = on + host-connection-pool.client.parsing.illegal-header-warnings = off + }""") { sys ⇒ + val client = ClientConnectionSettings(sys) + client.parserSettings.illegalHeaderWarnings should ===(On) + + val pool = ConnectionPoolSettings(sys) + pool.connectionSettings.parserSettings.illegalHeaderWarnings should ===(Off) + + val server = ServerSettings(sys) + server.parserSettings.illegalHeaderWarnings should ===(On) + } + } + } + + def configuredSystem(overrides: String)(block: ActorSystem ⇒ Unit) = { + val config = ConfigFactory.parseString(overrides).withFallback(ConfigFactory.load()) + // we go via ActorSystem in order to hit the settings caching infrastructure + val sys = ActorSystem("config-testing", config) + try block(sys) finally sys.shutdown() + } + +} \ No newline at end of file diff --git a/akka-http/src/main/scala/akka/http/scaladsl/server/RoutingSettings.scala b/akka-http/src/main/scala/akka/http/scaladsl/server/RoutingSettings.scala index 7fbd156524..fe88fc878f 100644 --- a/akka-http/src/main/scala/akka/http/scaladsl/server/RoutingSettings.scala +++ b/akka-http/src/main/scala/akka/http/scaladsl/server/RoutingSettings.scala @@ -18,7 +18,7 @@ case class RoutingSettings( fileIODispatcher: String) object RoutingSettings extends SettingsCompanion[RoutingSettings]("akka.http.routing") { - def fromSubConfig(c: Config) = apply( + def fromSubConfig(root: Config, c: Config) = apply( c getBoolean "verbose-error-messages", c getBoolean "file-get-conditional", c getBoolean "render-vanity-footer",