!htc #19514,#18958 make config in HTTP non-case class + from reference
This commit is contained in:
parent
97df7bf689
commit
9b4b68f0c9
17 changed files with 215 additions and 124 deletions
|
|
@ -19,14 +19,14 @@ import akka.http.impl.util._
|
|||
|
||||
import akka.http.scaladsl.model.headers.`User-Agent`
|
||||
|
||||
final case class ClientConnectionSettings(
|
||||
userAgentHeader: Option[`User-Agent`],
|
||||
connectingTimeout: FiniteDuration,
|
||||
idleTimeout: Duration,
|
||||
requestHeaderSizeHint: Int,
|
||||
websocketRandomFactory: () ⇒ Random,
|
||||
socketOptions: immutable.Traversable[SocketOption],
|
||||
parserSettings: ParserSettings) {
|
||||
final class ClientConnectionSettings(
|
||||
val userAgentHeader: Option[`User-Agent`],
|
||||
val connectingTimeout: FiniteDuration,
|
||||
val idleTimeout: Duration,
|
||||
val requestHeaderSizeHint: Int,
|
||||
val websocketRandomFactory: () ⇒ Random,
|
||||
val socketOptions: immutable.Traversable[SocketOption],
|
||||
val parserSettings: ParserSettings) {
|
||||
|
||||
require(connectingTimeout >= Duration.Zero, "connectingTimeout must be >= 0")
|
||||
require(requestHeaderSizeHint > 0, "request-size-hint must be > 0")
|
||||
|
|
@ -35,14 +35,14 @@ final case class ClientConnectionSettings(
|
|||
object ClientConnectionSettings extends SettingsCompanion[ClientConnectionSettings]("akka.http.client") {
|
||||
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",
|
||||
Randoms.SecureRandomInstances, // can currently only be overridden from code
|
||||
SocketOptionSettings.fromSubConfig(root, c.getConfig("socket-options")),
|
||||
ParserSettings.fromSubConfig(root, c.getConfig("parsing")))
|
||||
new ClientConnectionSettings(
|
||||
userAgentHeader = c.getString("user-agent-header").toOption.map(`User-Agent`(_)),
|
||||
connectingTimeout = c getFiniteDuration "connecting-timeout",
|
||||
idleTimeout = c getPotentiallyInfiniteDuration "idle-timeout",
|
||||
requestHeaderSizeHint = c getIntBytes "request-header-size-hint",
|
||||
websocketRandomFactory = Randoms.SecureRandomInstances, // can currently only be overridden from code
|
||||
socketOptions = SocketOptionSettings.fromSubConfig(root, c.getConfig("socket-options")),
|
||||
parserSettings = ParserSettings.fromSubConfig(root, c.getConfig("parsing")))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -27,13 +27,13 @@ object ConnectionPoolSetup {
|
|||
ConnectionPoolSetup(settings, connectionContext, log)
|
||||
}
|
||||
|
||||
final case class ConnectionPoolSettings(
|
||||
maxConnections: Int,
|
||||
maxRetries: Int,
|
||||
maxOpenRequests: Int,
|
||||
pipeliningLimit: Int,
|
||||
idleTimeout: Duration,
|
||||
connectionSettings: ClientConnectionSettings) {
|
||||
final class ConnectionPoolSettings(
|
||||
val maxConnections: Int,
|
||||
val maxRetries: Int,
|
||||
val maxOpenRequests: Int,
|
||||
val pipeliningLimit: Int,
|
||||
val idleTimeout: Duration,
|
||||
val connectionSettings: ClientConnectionSettings) {
|
||||
|
||||
require(maxConnections > 0, "max-connections must be > 0")
|
||||
require(maxRetries >= 0, "max-retries must be >= 0")
|
||||
|
|
@ -44,7 +44,7 @@ final case class ConnectionPoolSettings(
|
|||
|
||||
object ConnectionPoolSettings extends SettingsCompanion[ConnectionPoolSettings]("akka.http.host-connection-pool") {
|
||||
def fromSubConfig(root: Config, c: Config) = {
|
||||
apply(
|
||||
new ConnectionPoolSettings(
|
||||
c getInt "max-connections",
|
||||
c getInt "max-retries",
|
||||
c getInt "max-open-requests",
|
||||
|
|
|
|||
|
|
@ -4,32 +4,33 @@
|
|||
|
||||
package akka.http
|
||||
|
||||
import java.util.Locale
|
||||
import akka.actor.ActorSystem
|
||||
import akka.actor.{ ActorRefFactory, ActorSystem }
|
||||
import akka.stream.{ ActorMaterializer, Materializer }
|
||||
import com.typesafe.config.Config
|
||||
import scala.collection.JavaConverters._
|
||||
import akka.http.scaladsl.model.{ StatusCode, HttpMethod, Uri }
|
||||
import akka.http.impl.util._
|
||||
import akka.http.impl.engine.parsing.HttpHeaderParser
|
||||
import akka.http.impl.engine.parsing.{ BodyPartParser, HttpHeaderParser }
|
||||
|
||||
final case class ParserSettings(
|
||||
maxUriLength: Int,
|
||||
maxMethodLength: Int,
|
||||
maxResponseReasonLength: Int,
|
||||
maxHeaderNameLength: Int,
|
||||
maxHeaderValueLength: Int,
|
||||
maxHeaderCount: Int,
|
||||
maxContentLength: Long,
|
||||
maxChunkExtLength: Int,
|
||||
maxChunkSize: Int,
|
||||
uriParsingMode: Uri.ParsingMode,
|
||||
cookieParsingMode: ParserSettings.CookieParsingMode,
|
||||
illegalHeaderWarnings: Boolean,
|
||||
errorLoggingVerbosity: ParserSettings.ErrorLoggingVerbosity,
|
||||
headerValueCacheLimits: Map[String, Int],
|
||||
includeTlsSessionInfoHeader: Boolean,
|
||||
customMethods: String ⇒ Option[HttpMethod],
|
||||
customStatusCodes: Int ⇒ Option[StatusCode]) extends HttpHeaderParser.Settings {
|
||||
final class ParserSettings(
|
||||
val maxUriLength: Int,
|
||||
val maxMethodLength: Int,
|
||||
val maxResponseReasonLength: Int,
|
||||
val maxHeaderNameLength: Int,
|
||||
val maxHeaderValueLength: Int,
|
||||
val maxHeaderCount: Int,
|
||||
val maxContentLength: Long,
|
||||
val maxChunkExtLength: Int,
|
||||
val maxChunkSize: Int,
|
||||
val uriParsingMode: Uri.ParsingMode,
|
||||
val cookieParsingMode: ParserSettings.CookieParsingMode,
|
||||
val illegalHeaderWarnings: Boolean,
|
||||
val errorLoggingVerbosity: ParserSettings.ErrorLoggingVerbosity,
|
||||
val headerValueCacheLimits: Map[String, Int],
|
||||
val includeTlsSessionInfoHeader: Boolean,
|
||||
val customMethods: String ⇒ Option[HttpMethod],
|
||||
val customStatusCodes: Int ⇒ Option[StatusCode])
|
||||
extends BodyPartParser.Settings {
|
||||
|
||||
require(maxUriLength > 0, "max-uri-length must be > 0")
|
||||
require(maxMethodLength > 0, "max-method-length must be > 0")
|
||||
|
|
@ -41,9 +42,9 @@ final case class ParserSettings(
|
|||
require(maxChunkExtLength > 0, "max-chunk-ext-length must be > 0")
|
||||
require(maxChunkSize > 0, "max-chunk-size must be > 0")
|
||||
|
||||
val defaultHeaderValueCacheLimit: Int = headerValueCacheLimits("default")
|
||||
override val defaultHeaderValueCacheLimit: Int = headerValueCacheLimits("default")
|
||||
|
||||
def headerValueCacheLimit(headerName: String): Int =
|
||||
override def headerValueCacheLimit(headerName: String): Int =
|
||||
headerValueCacheLimits.getOrElse(headerName, defaultHeaderValueCacheLimit)
|
||||
|
||||
def withCustomMethods(methods: HttpMethod*): ParserSettings = {
|
||||
|
|
@ -54,6 +55,41 @@ final case class ParserSettings(
|
|||
val map = codes.map(c ⇒ c.intValue -> c).toMap
|
||||
copy(customStatusCodes = map.get)
|
||||
}
|
||||
|
||||
def copy(maxUriLength: Int = maxUriLength,
|
||||
maxMethodLength: Int = maxMethodLength,
|
||||
maxResponseReasonLength: Int = maxResponseReasonLength,
|
||||
maxHeaderNameLength: Int = maxHeaderNameLength,
|
||||
maxHeaderValueLength: Int = maxHeaderValueLength,
|
||||
maxHeaderCount: Int = maxHeaderCount,
|
||||
maxContentLength: Long = maxContentLength,
|
||||
maxChunkExtLength: Int = maxChunkExtLength,
|
||||
maxChunkSize: Int = maxChunkSize,
|
||||
uriParsingMode: Uri.ParsingMode = uriParsingMode,
|
||||
cookieParsingMode: ParserSettings.CookieParsingMode = cookieParsingMode,
|
||||
illegalHeaderWarnings: Boolean = illegalHeaderWarnings,
|
||||
errorLoggingVerbosity: ParserSettings.ErrorLoggingVerbosity = errorLoggingVerbosity,
|
||||
headerValueCacheLimits: Map[String, Int] = headerValueCacheLimits,
|
||||
includeTlsSessionInfoHeader: Boolean = includeTlsSessionInfoHeader,
|
||||
customMethods: String ⇒ Option[HttpMethod] = customMethods,
|
||||
customStatusCodes: Int ⇒ Option[StatusCode] = customStatusCodes): ParserSettings =
|
||||
new ParserSettings(maxUriLength,
|
||||
maxMethodLength,
|
||||
maxResponseReasonLength,
|
||||
maxHeaderNameLength,
|
||||
maxHeaderValueLength,
|
||||
maxHeaderCount,
|
||||
maxContentLength,
|
||||
maxChunkExtLength,
|
||||
maxChunkSize,
|
||||
uriParsingMode,
|
||||
cookieParsingMode,
|
||||
illegalHeaderWarnings,
|
||||
errorLoggingVerbosity,
|
||||
headerValueCacheLimits,
|
||||
includeTlsSessionInfoHeader,
|
||||
customMethods,
|
||||
customStatusCodes)
|
||||
}
|
||||
|
||||
object ParserSettings extends SettingsCompanion[ParserSettings]("akka.http.parsing") {
|
||||
|
|
@ -61,7 +97,7 @@ object ParserSettings extends SettingsCompanion[ParserSettings]("akka.http.parsi
|
|||
val c = inner.withFallback(root.getConfig(prefix))
|
||||
val cacheConfig = c getConfig "header-cache"
|
||||
|
||||
apply(
|
||||
new ParserSettings(
|
||||
c getIntBytes "max-uri-length",
|
||||
c getIntBytes "max-method-length",
|
||||
c getIntBytes "max-response-reason-length",
|
||||
|
|
@ -130,5 +166,8 @@ object ParserSettings extends SettingsCompanion[ParserSettings]("akka.http.parsi
|
|||
* Java API
|
||||
*/
|
||||
def create(configOverrides: String): ParserSettings = ParserSettings(configOverrides)
|
||||
|
||||
implicit def default(implicit refFactory: ActorRefFactory): ParserSettings =
|
||||
apply(actorSystem)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,21 +22,21 @@ import akka.http.impl.util._
|
|||
import akka.http.scaladsl.model.HttpHeader
|
||||
import akka.http.scaladsl.model.headers.{ Host, Server }
|
||||
|
||||
final case class ServerSettings(
|
||||
serverHeader: Option[Server],
|
||||
timeouts: ServerSettings.Timeouts,
|
||||
maxConnections: Int,
|
||||
pipeliningLimit: Int,
|
||||
remoteAddressHeader: Boolean,
|
||||
rawRequestUriHeader: Boolean,
|
||||
transparentHeadRequests: Boolean,
|
||||
verboseErrorMessages: Boolean,
|
||||
responseHeaderSizeHint: Int,
|
||||
backlog: Int,
|
||||
socketOptions: immutable.Traversable[SocketOption],
|
||||
defaultHostHeader: Host,
|
||||
websocketRandomFactory: () ⇒ Random,
|
||||
parserSettings: ParserSettings) {
|
||||
final class ServerSettings(
|
||||
val serverHeader: Option[Server],
|
||||
val timeouts: ServerSettings.Timeouts,
|
||||
val maxConnections: Int,
|
||||
val pipeliningLimit: Int,
|
||||
val remoteAddressHeader: Boolean,
|
||||
val rawRequestUriHeader: Boolean,
|
||||
val transparentHeadRequests: Boolean,
|
||||
val verboseErrorMessages: Boolean,
|
||||
val responseHeaderSizeHint: Int,
|
||||
val backlog: Int,
|
||||
val socketOptions: immutable.Traversable[SocketOption],
|
||||
val defaultHostHeader: Host,
|
||||
val websocketRandomFactory: () ⇒ Random,
|
||||
val parserSettings: ParserSettings) {
|
||||
|
||||
require(0 < maxConnections, "max-connections must be > 0")
|
||||
require(0 < pipeliningLimit && pipeliningLimit <= 1024, "pipelining-limit must be > 0 and <= 1024")
|
||||
|
|
@ -45,18 +45,19 @@ final case class ServerSettings(
|
|||
}
|
||||
|
||||
object ServerSettings extends SettingsCompanion[ServerSettings]("akka.http.server") {
|
||||
final case class Timeouts(idleTimeout: Duration,
|
||||
requestTimeout: Duration,
|
||||
bindTimeout: FiniteDuration) {
|
||||
final class Timeouts(
|
||||
val idleTimeout: Duration,
|
||||
val requestTimeout: Duration,
|
||||
val bindTimeout: FiniteDuration) {
|
||||
require(idleTimeout > Duration.Zero, "idleTimeout must be infinite or > 0")
|
||||
require(requestTimeout > Duration.Zero, "requestTimeout must be infinite or > 0")
|
||||
require(bindTimeout > Duration.Zero, "bindTimeout must be > 0")
|
||||
}
|
||||
implicit def timeoutsShortcut(s: ServerSettings): Timeouts = s.timeouts
|
||||
|
||||
def fromSubConfig(root: Config, c: Config) = apply(
|
||||
def fromSubConfig(root: Config, c: Config) = new ServerSettings(
|
||||
c.getString("server-header").toOption.map(Server(_)),
|
||||
Timeouts(
|
||||
new Timeouts(
|
||||
c getPotentiallyInfiniteDuration "idle-timeout",
|
||||
c getPotentiallyInfiniteDuration "request-timeout",
|
||||
c getFiniteDuration "bind-timeout"),
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
package akka.http.impl.engine.parsing
|
||||
|
||||
import akka.NotUsed
|
||||
import akka.http.ParserSettings
|
||||
import akka.stream.impl.fusing.GraphInterpreter
|
||||
import scala.annotation.tailrec
|
||||
import akka.event.LoggingAdapter
|
||||
import akka.parboiled2.CharPredicate
|
||||
|
|
@ -27,7 +25,7 @@ import akka.stream.impl.fusing.SubSource
|
|||
private[http] final class BodyPartParser(defaultContentType: ContentType,
|
||||
boundary: String,
|
||||
log: LoggingAdapter,
|
||||
settings: BodyPartParser.Settings = BodyPartParser.defaultSettings)
|
||||
settings: BodyPartParser.Settings)
|
||||
extends PushPullStage[ByteString, BodyPartParser.Output] {
|
||||
import BodyPartParser._
|
||||
import settings._
|
||||
|
|
@ -277,28 +275,9 @@ private[http] object BodyPartParser {
|
|||
final case class EntityPart(data: ByteString) extends Output
|
||||
final case class ParseError(info: ErrorInfo) extends PartStart
|
||||
|
||||
final case class Settings(
|
||||
maxHeaderNameLength: Int,
|
||||
maxHeaderValueLength: Int,
|
||||
maxHeaderCount: Int,
|
||||
illegalHeaderWarnings: Boolean,
|
||||
headerValueCacheLimit: Int,
|
||||
uriParsingMode: Uri.ParsingMode,
|
||||
cookieParsingMode: ParserSettings.CookieParsingMode) extends HttpHeaderParser.Settings {
|
||||
require(maxHeaderNameLength > 0, "maxHeaderNameLength must be > 0")
|
||||
require(maxHeaderValueLength > 0, "maxHeaderValueLength must be > 0")
|
||||
require(maxHeaderCount > 0, "maxHeaderCount must be > 0")
|
||||
require(headerValueCacheLimit >= 0, "headerValueCacheLimit must be >= 0")
|
||||
def headerValueCacheLimit(headerName: String) = headerValueCacheLimit
|
||||
abstract class Settings extends HttpHeaderParser.Settings {
|
||||
def maxHeaderCount: Int
|
||||
def illegalHeaderWarnings: Boolean
|
||||
def defaultHeaderValueCacheLimit: Int
|
||||
}
|
||||
|
||||
// TODO: load from config
|
||||
val defaultSettings = Settings(
|
||||
maxHeaderNameLength = 64,
|
||||
maxHeaderValueLength = 8192,
|
||||
maxHeaderCount = 64,
|
||||
illegalHeaderWarnings = true,
|
||||
headerValueCacheLimit = 8,
|
||||
uriParsingMode = Uri.ParsingMode.Relaxed,
|
||||
cookieParsingMode = ParserSettings.CookieParsingMode.RFC6265)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ private[engine] final class HttpHeaderParser private (
|
|||
private[http] object HttpHeaderParser {
|
||||
import SpecializedHeaderValueParsers._
|
||||
|
||||
trait Settings extends HeaderParser.Settings {
|
||||
abstract class Settings extends HeaderParser.Settings {
|
||||
def maxHeaderNameLength: Int
|
||||
def maxHeaderValueLength: Int
|
||||
def headerValueCacheLimit(headerName: String): Int
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ private[http] object HeaderParser {
|
|||
"www-authenticate",
|
||||
"x-forwarded-for")
|
||||
|
||||
trait Settings {
|
||||
abstract class Settings {
|
||||
def uriParsingMode: Uri.ParsingMode
|
||||
def cookieParsingMode: ParserSettings.CookieParsingMode
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue