!htc #19514 add withXYZ methods to all configs
This commit is contained in:
parent
244c52c226
commit
379a3a85b4
71 changed files with 1225 additions and 1030 deletions
|
|
@ -183,7 +183,7 @@ class BasicDirectivesExamplesSpec extends RoutingSpec {
|
|||
}
|
||||
"withSettings-0" in compileOnlySpec {
|
||||
//#withSettings-0
|
||||
val special = RoutingSettings(system).copy(fileIODispatcher = "special-io-dispatcher")
|
||||
val special = RoutingSettingsImpl(system).copy(fileIODispatcher = "special-io-dispatcher")
|
||||
|
||||
def sample() =
|
||||
path("sample") {
|
||||
|
|
@ -687,7 +687,7 @@ class BasicDirectivesExamplesSpec extends RoutingSpec {
|
|||
"extractSettings-examples" in {
|
||||
//#extractSettings-examples
|
||||
val route =
|
||||
extractSettings { settings: RoutingSettings =>
|
||||
extractSettings { settings: RoutingSettingsImpl =>
|
||||
complete(s"RoutingSettings.renderVanityFooter = ${settings.renderVanityFooter}")
|
||||
}
|
||||
|
||||
|
|
@ -705,7 +705,7 @@ class BasicDirectivesExamplesSpec extends RoutingSpec {
|
|||
|
||||
val route =
|
||||
tunedSettings {
|
||||
extractSettings { settings: RoutingSettings =>
|
||||
extractSettings { settings: RoutingSettingsImpl =>
|
||||
complete(s"RoutingSettings.fileGetConditional = ${settings.fileGetConditional}")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,13 @@ package akka.http.javadsl.model;
|
|||
* and static constructors to create custom ones.
|
||||
*/
|
||||
public abstract class HttpMethod {
|
||||
|
||||
/**
|
||||
* Returns the name of the method, always equal to [[value]].
|
||||
*/
|
||||
public final String name() {
|
||||
return value();
|
||||
}
|
||||
/**
|
||||
* Returns the name of the method.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -16,163 +16,165 @@ import java.util.Optional;
|
|||
* Represents an Uri. Use the `withX` methods to create modified copies of a given instance.
|
||||
*/
|
||||
public abstract class Uri {
|
||||
/**
|
||||
* Returns if this is an absolute Uri.
|
||||
*/
|
||||
public abstract boolean isAbsolute();
|
||||
/**
|
||||
* Returns if this is an absolute Uri.
|
||||
*/
|
||||
public abstract boolean isAbsolute();
|
||||
|
||||
/**
|
||||
* Returns if this is a relative Uri.
|
||||
*/
|
||||
public abstract boolean isRelative();
|
||||
/**
|
||||
* Returns if this is a relative Uri.
|
||||
*/
|
||||
public abstract boolean isRelative();
|
||||
|
||||
/**
|
||||
* Returns if this is an empty Uri.
|
||||
*/
|
||||
public abstract boolean isEmpty();
|
||||
/**
|
||||
* Returns if this is an empty Uri.
|
||||
*/
|
||||
public abstract boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Returns the scheme of this Uri.
|
||||
*/
|
||||
public abstract String scheme();
|
||||
/**
|
||||
* Returns the scheme of this Uri.
|
||||
*/
|
||||
public abstract String scheme();
|
||||
|
||||
/**
|
||||
* Returns the Host of this Uri.
|
||||
*/
|
||||
public abstract Host host();
|
||||
/**
|
||||
* Returns the Host of this Uri.
|
||||
*/
|
||||
public abstract Host host();
|
||||
|
||||
/**
|
||||
* Returns the port of this Uri.
|
||||
*/
|
||||
public abstract int port();
|
||||
/**
|
||||
* Returns the port of this Uri.
|
||||
*/
|
||||
public abstract int port();
|
||||
|
||||
/**
|
||||
* Returns the user-info of this Uri.
|
||||
*/
|
||||
public abstract String userInfo();
|
||||
/**
|
||||
* Returns the user-info of this Uri.
|
||||
*/
|
||||
public abstract String userInfo();
|
||||
|
||||
/**
|
||||
* Returns a String representation of the path of this Uri.
|
||||
*/
|
||||
public abstract String path();
|
||||
/**
|
||||
* Returns a String representation of the path of this Uri.
|
||||
*/
|
||||
public abstract String path();
|
||||
|
||||
/**
|
||||
* Returns the the path segments of this Uri as an Iterable.
|
||||
*/
|
||||
public abstract Iterable<String> pathSegments();
|
||||
/**
|
||||
* Returns the the path segments of this Uri as an Iterable.
|
||||
*/
|
||||
public abstract Iterable<String> pathSegments();
|
||||
|
||||
/**
|
||||
* Returns a decoded String representation of the query of this Uri.
|
||||
*/
|
||||
public abstract Optional<String> queryString(Charset charset);
|
||||
/**
|
||||
* Returns a decoded String representation of the query of this Uri.
|
||||
*/
|
||||
public abstract Optional<String> queryString(Charset charset);
|
||||
|
||||
/**
|
||||
* Returns an undecoded String representation of the query of this Uri.
|
||||
*/
|
||||
public abstract Optional<String> rawQueryString();
|
||||
/**
|
||||
* Returns an undecoded String representation of the query of this Uri.
|
||||
*/
|
||||
public abstract Optional<String> rawQueryString();
|
||||
|
||||
/**
|
||||
* Returns the parsed Query instance of this Uri.
|
||||
*/
|
||||
public abstract Query query();
|
||||
/**
|
||||
* Returns the parsed Query instance of this Uri.
|
||||
*/
|
||||
public abstract Query query();
|
||||
|
||||
/**
|
||||
* Returns the parsed Query instance of this Uri using the given charset and parsing mode.
|
||||
*/
|
||||
public abstract Query query(Charset charset, akka.http.scaladsl.model.Uri.ParsingMode mode);
|
||||
/**
|
||||
* Returns the parsed Query instance of this Uri using the given charset and parsing mode.
|
||||
*/
|
||||
public abstract Query query(Charset charset, akka.http.scaladsl.model.Uri.ParsingMode mode);
|
||||
|
||||
/**
|
||||
* Returns the fragment part of this Uri.
|
||||
*/
|
||||
public abstract Optional<String> fragment();
|
||||
/**
|
||||
* Returns the fragment part of this Uri.
|
||||
*/
|
||||
public abstract Optional<String> fragment();
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance with a new scheme.
|
||||
*/
|
||||
public abstract Uri scheme(String scheme);
|
||||
/**
|
||||
* Returns a copy of this instance with a new scheme.
|
||||
*/
|
||||
public abstract Uri scheme(String scheme);
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance with a new Host.
|
||||
*/
|
||||
public abstract Uri host(Host host);
|
||||
/**
|
||||
* Returns a copy of this instance with a new Host.
|
||||
*/
|
||||
public abstract Uri host(Host host);
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance with a new host.
|
||||
*/
|
||||
public abstract Uri host(String host);
|
||||
/**
|
||||
* Returns a copy of this instance with a new host.
|
||||
*/
|
||||
public abstract Uri host(String host);
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance with a new port.
|
||||
*/
|
||||
public abstract Uri port(int port);
|
||||
/**
|
||||
* Returns a copy of this instance with a new port.
|
||||
*/
|
||||
public abstract Uri port(int port);
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance with new user-info.
|
||||
*/
|
||||
public abstract Uri userInfo(String userInfo);
|
||||
/**
|
||||
* Returns a copy of this instance with new user-info.
|
||||
*/
|
||||
public abstract Uri userInfo(String userInfo);
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance with a new path.
|
||||
*/
|
||||
public abstract Uri path(String path);
|
||||
/**
|
||||
* Returns a copy of this instance with a new path.
|
||||
*/
|
||||
public abstract Uri path(String path);
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance with a path segment added at the end.
|
||||
*/
|
||||
public abstract Uri addPathSegment(String segment);
|
||||
/**
|
||||
* Returns a copy of this instance with a path segment added at the end.
|
||||
*/
|
||||
public abstract Uri addPathSegment(String segment);
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance with a new query.
|
||||
*/
|
||||
public abstract Uri rawQueryString(String rawQuery);
|
||||
/**
|
||||
* Returns a copy of this instance with a new query.
|
||||
*/
|
||||
public abstract Uri rawQueryString(String rawQuery);
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance with a new query.
|
||||
*/
|
||||
public abstract Uri query(Query query);
|
||||
/**
|
||||
* Returns a copy of this instance with a new query.
|
||||
*/
|
||||
public abstract Uri query(Query query);
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance that is relative.
|
||||
*/
|
||||
public abstract Uri toRelative();
|
||||
/**
|
||||
* Returns a copy of this instance that is relative.
|
||||
*/
|
||||
public abstract Uri toRelative();
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance with a new fragment.
|
||||
*/
|
||||
public abstract Uri fragment(String fragment);
|
||||
/**
|
||||
* Returns a copy of this instance with a new fragment.
|
||||
*/
|
||||
public abstract Uri fragment(String fragment);
|
||||
|
||||
/**
|
||||
* Returns a copy of this instance with a new optional fragment.
|
||||
*/
|
||||
public abstract Uri fragment(Optional<String> fragment);
|
||||
/**
|
||||
* Returns a copy of this instance with a new optional fragment.
|
||||
*/
|
||||
public abstract Uri fragment(Optional<String> fragment);
|
||||
|
||||
public static final akka.http.scaladsl.model.Uri.ParsingMode STRICT = UriJavaAccessor.pmStrict();
|
||||
public static final akka.http.scaladsl.model.Uri.ParsingMode RELAXED = UriJavaAccessor.pmRelaxed();
|
||||
public static final akka.http.scaladsl.model.Uri.ParsingMode STRICT = UriJavaAccessor.pmStrict();
|
||||
public static final akka.http.scaladsl.model.Uri.ParsingMode RELAXED = UriJavaAccessor.pmRelaxed();
|
||||
|
||||
/**
|
||||
* Creates a default Uri to be modified using the modification methods.
|
||||
*/
|
||||
public static final Uri EMPTY = new JavaUri(akka.http.scaladsl.model.Uri.Empty$.MODULE$);
|
||||
/**
|
||||
* Creates a default Uri to be modified using the modification methods.
|
||||
*/
|
||||
public static final Uri EMPTY = new JavaUri(akka.http.scaladsl.model.Uri.Empty$.MODULE$);
|
||||
|
||||
/**
|
||||
* Returns a Uri created by parsing the given string representation.
|
||||
*/
|
||||
public static Uri create(String uri) {
|
||||
return new JavaUri(akka.http.scaladsl.model.Uri.apply(uri));
|
||||
}
|
||||
/**
|
||||
* Returns a Uri created by parsing the given string representation.
|
||||
*/
|
||||
public static Uri create(String uri) {
|
||||
return new JavaUri(akka.http.scaladsl.model.Uri.apply(uri));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Uri created by parsing the given string representation with the provided parsing mode.
|
||||
*/
|
||||
public static Uri create(String uri, akka.http.scaladsl.model.Uri.ParsingMode parsingMode) {
|
||||
return new JavaUri(akka.http.scaladsl.model.Uri.apply(ParserInput$.MODULE$.apply(uri), parsingMode));
|
||||
}
|
||||
/**
|
||||
* Returns a Uri created by parsing the given string representation with the provided parsing mode.
|
||||
*/
|
||||
public static Uri create(String uri, akka.http.scaladsl.model.Uri.ParsingMode parsingMode) {
|
||||
return new JavaUri(akka.http.scaladsl.model.Uri.apply(ParserInput$.MODULE$.apply(uri), parsingMode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Uri created by parsing the given string representation with the provided charset and parsing mode.
|
||||
*/
|
||||
public static Uri create(String uri, Charset charset, akka.http.scaladsl.model.Uri.ParsingMode parsingMode) {
|
||||
return new JavaUri(akka.http.scaladsl.model.Uri.apply(ParserInput$.MODULE$.apply(uri), charset, parsingMode));
|
||||
}
|
||||
/**
|
||||
* Returns a Uri created by parsing the given string representation with the provided charset and parsing mode.
|
||||
*/
|
||||
public static Uri create(String uri, Charset charset, akka.http.scaladsl.model.Uri.ParsingMode parsingMode) {
|
||||
return new JavaUri(akka.http.scaladsl.model.Uri.apply(ParserInput$.MODULE$.apply(uri), charset, parsingMode));
|
||||
}
|
||||
|
||||
|
||||
public static interface ParsingMode {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,118 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http
|
||||
|
||||
import java.util.Random
|
||||
|
||||
import akka.http.impl.engine.ws.Randoms
|
||||
import akka.io.Inet.SocketOption
|
||||
|
||||
import scala.concurrent.duration.{ Duration, FiniteDuration }
|
||||
import scala.collection.immutable
|
||||
|
||||
import com.typesafe.config.Config
|
||||
import akka.actor.ActorSystem
|
||||
|
||||
import akka.http.impl.util._
|
||||
|
||||
import akka.http.scaladsl.model.headers.`User-Agent`
|
||||
|
||||
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")
|
||||
|
||||
def copy(
|
||||
userAgentHeader: Option[`User-Agent`] = userAgentHeader,
|
||||
connectingTimeout: FiniteDuration = connectingTimeout,
|
||||
idleTimeout: Duration = idleTimeout,
|
||||
requestHeaderSizeHint: Int = requestHeaderSizeHint,
|
||||
websocketRandomFactory: () ⇒ Random = websocketRandomFactory,
|
||||
socketOptions: immutable.Traversable[SocketOption] = socketOptions,
|
||||
parserSettings: ParserSettings = parserSettings) =
|
||||
new ClientConnectionSettings(
|
||||
userAgentHeader = userAgentHeader,
|
||||
connectingTimeout = connectingTimeout,
|
||||
idleTimeout = idleTimeout,
|
||||
requestHeaderSizeHint = requestHeaderSizeHint,
|
||||
websocketRandomFactory = websocketRandomFactory,
|
||||
socketOptions = socketOptions,
|
||||
parserSettings = parserSettings)
|
||||
|
||||
override def toString = {
|
||||
getClass.getSimpleName + "(" +
|
||||
userAgentHeader + "," +
|
||||
connectingTimeout + "," +
|
||||
idleTimeout + "," +
|
||||
requestHeaderSizeHint + "," +
|
||||
websocketRandomFactory + "," +
|
||||
socketOptions + "," +
|
||||
parserSettings + "," +
|
||||
")"
|
||||
}
|
||||
}
|
||||
|
||||
object ClientConnectionSettings extends SettingsCompanion[ClientConnectionSettings]("akka.http.client") {
|
||||
def fromSubConfig(root: Config, inner: Config) = {
|
||||
val c = inner.withFallback(root.getConfig(prefix))
|
||||
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")))
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of ClientConnectionSettings using the configuration provided by the given
|
||||
* ActorSystem.
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
def create(system: ActorSystem): ClientConnectionSettings = ClientConnectionSettings(system)
|
||||
|
||||
/**
|
||||
* Creates an instance of ClientConnectionSettings using the given Config.
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
def create(config: Config): ClientConnectionSettings = ClientConnectionSettings(config)
|
||||
|
||||
/**
|
||||
* Create an instance of ClientConnectionSettings using the given String of config overrides to override
|
||||
* settings set in the class loader of this class (i.e. by application.conf or reference.conf files in
|
||||
* the class loader of this class).
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
def create(configOverrides: String): ClientConnectionSettings = ClientConnectionSettings(configOverrides)
|
||||
|
||||
def apply(
|
||||
userAgentHeader: Option[`User-Agent`],
|
||||
connectingTimeout: FiniteDuration,
|
||||
idleTimeout: Duration,
|
||||
requestHeaderSizeHint: Int,
|
||||
websocketRandomFactory: () ⇒ Random,
|
||||
socketOptions: immutable.Traversable[SocketOption],
|
||||
parserSettings: ParserSettings) =
|
||||
new ClientConnectionSettings(
|
||||
userAgentHeader = userAgentHeader,
|
||||
connectingTimeout = connectingTimeout,
|
||||
idleTimeout = idleTimeout,
|
||||
requestHeaderSizeHint = requestHeaderSizeHint,
|
||||
websocketRandomFactory = websocketRandomFactory,
|
||||
socketOptions = socketOptions,
|
||||
parserSettings = parserSettings)
|
||||
|
||||
}
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.event.LoggingAdapter
|
||||
import akka.http.impl.util._
|
||||
import akka.http.javadsl.ConnectionContext
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
|
||||
final case class HostConnectionPoolSetup(host: String, port: Int, setup: ConnectionPoolSetup)
|
||||
|
||||
final case class ConnectionPoolSetup(
|
||||
settings: ConnectionPoolSettings,
|
||||
connectionContext: ConnectionContext = ConnectionContext.noEncryption(),
|
||||
log: LoggingAdapter)
|
||||
|
||||
object ConnectionPoolSetup {
|
||||
/** Java API */
|
||||
def create(settings: ConnectionPoolSettings,
|
||||
connectionContext: ConnectionContext,
|
||||
log: LoggingAdapter): ConnectionPoolSetup =
|
||||
ConnectionPoolSetup(settings, connectionContext, log)
|
||||
}
|
||||
|
||||
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")
|
||||
require(maxOpenRequests > 0 && (maxOpenRequests & (maxOpenRequests - 1)) == 0, "max-open-requests must be a power of 2 > 0")
|
||||
require(pipeliningLimit > 0, "pipelining-limit must be > 0")
|
||||
require(idleTimeout >= Duration.Zero, "idle-timeout must be >= 0")
|
||||
|
||||
def copy(
|
||||
maxConnections: Int = maxConnections,
|
||||
maxRetries: Int = maxRetries,
|
||||
maxOpenRequests: Int = maxOpenRequests,
|
||||
pipeliningLimit: Int = pipeliningLimit,
|
||||
idleTimeout: Duration = idleTimeout,
|
||||
connectionSettings: ClientConnectionSettings = connectionSettings) =
|
||||
new ConnectionPoolSettings(
|
||||
maxConnections = maxConnections,
|
||||
maxRetries = maxRetries,
|
||||
maxOpenRequests = maxOpenRequests,
|
||||
pipeliningLimit = pipeliningLimit,
|
||||
idleTimeout = idleTimeout,
|
||||
connectionSettings = connectionSettings)
|
||||
|
||||
// TODO we should automate generating those
|
||||
override def toString = {
|
||||
getClass.getSimpleName + "(" +
|
||||
maxConnections + "," +
|
||||
maxRetries + "," +
|
||||
maxOpenRequests + "," +
|
||||
pipeliningLimit + "," +
|
||||
idleTimeout + "," +
|
||||
connectionSettings +
|
||||
")"
|
||||
}
|
||||
}
|
||||
|
||||
object ConnectionPoolSettings extends SettingsCompanion[ConnectionPoolSettings]("akka.http.host-connection-pool") {
|
||||
def fromSubConfig(root: Config, c: Config) = {
|
||||
new ConnectionPoolSettings(
|
||||
c getInt "max-connections",
|
||||
c getInt "max-retries",
|
||||
c getInt "max-open-requests",
|
||||
c getInt "pipelining-limit",
|
||||
c getPotentiallyInfiniteDuration "idle-timeout",
|
||||
ClientConnectionSettings.fromSubConfig(root, c.getConfig("client")))
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of ConnectionPoolSettings using the configuration provided by the given
|
||||
* ActorSystem.
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
def create(system: ActorSystem): ConnectionPoolSettings = ConnectionPoolSettings(system)
|
||||
|
||||
/**
|
||||
* Creates an instance of ConnectionPoolSettings using the given Config.
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
def create(config: Config): ConnectionPoolSettings = ConnectionPoolSettings(config)
|
||||
|
||||
/**
|
||||
* Create an instance of ConnectionPoolSettings using the given String of config overrides to override
|
||||
* settings set in the class loader of this class (i.e. by application.conf or reference.conf files in
|
||||
* the class loader of this class).
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
def create(configOverrides: String): ConnectionPoolSettings = ConnectionPoolSettings(configOverrides)
|
||||
|
||||
def apply(
|
||||
maxConnections: Int,
|
||||
maxRetries: Int,
|
||||
maxOpenRequests: Int,
|
||||
pipeliningLimit: Int,
|
||||
idleTimeout: Duration,
|
||||
connectionSettings: ClientConnectionSettings) =
|
||||
new ConnectionPoolSettings(
|
||||
maxConnections: Int,
|
||||
maxRetries: Int,
|
||||
maxOpenRequests: Int,
|
||||
pipeliningLimit: Int,
|
||||
idleTimeout: Duration,
|
||||
connectionSettings: ClientConnectionSettings)
|
||||
}
|
||||
|
|
@ -1,231 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http
|
||||
|
||||
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.{ BodyPartParser, HttpHeaderParser }
|
||||
|
||||
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")
|
||||
require(maxResponseReasonLength > 0, "max-response-reason-length must be > 0")
|
||||
require(maxHeaderNameLength > 0, "max-header-name-length must be > 0")
|
||||
require(maxHeaderValueLength > 0, "max-header-value-length must be > 0")
|
||||
require(maxHeaderCount > 0, "max-header-count must be > 0")
|
||||
require(maxContentLength > 0, "max-content-length must be > 0")
|
||||
require(maxChunkExtLength > 0, "max-chunk-ext-length must be > 0")
|
||||
require(maxChunkSize > 0, "max-chunk-size must be > 0")
|
||||
|
||||
override val defaultHeaderValueCacheLimit: Int = headerValueCacheLimits("default")
|
||||
|
||||
override def headerValueCacheLimit(headerName: String): Int =
|
||||
headerValueCacheLimits.getOrElse(headerName, defaultHeaderValueCacheLimit)
|
||||
|
||||
def withCustomMethods(methods: HttpMethod*): ParserSettings = {
|
||||
val map = methods.map(m ⇒ m.name -> m).toMap
|
||||
copy(customMethods = map.get)
|
||||
}
|
||||
def withCustomStatusCodes(codes: StatusCode*): 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)
|
||||
|
||||
// TODO we should automate generating those
|
||||
override def toString = {
|
||||
getClass.getSimpleName + "(" +
|
||||
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") {
|
||||
def fromSubConfig(root: Config, inner: Config) = {
|
||||
val c = inner.withFallback(root.getConfig(prefix))
|
||||
val cacheConfig = c getConfig "header-cache"
|
||||
|
||||
ParserSettings(
|
||||
c getIntBytes "max-uri-length",
|
||||
c getIntBytes "max-method-length",
|
||||
c getIntBytes "max-response-reason-length",
|
||||
c getIntBytes "max-header-name-length",
|
||||
c getIntBytes "max-header-value-length",
|
||||
c getIntBytes "max-header-count",
|
||||
c getPossiblyInfiniteBytes "max-content-length",
|
||||
c getIntBytes "max-chunk-ext-length",
|
||||
c getIntBytes "max-chunk-size",
|
||||
Uri.ParsingMode(c getString "uri-parsing-mode"),
|
||||
CookieParsingMode(c getString "cookie-parsing-mode"),
|
||||
c getBoolean "illegal-header-warnings",
|
||||
ErrorLoggingVerbosity(c getString "error-logging-verbosity"),
|
||||
cacheConfig.entrySet.asScala.map(kvp ⇒ kvp.getKey -> cacheConfig.getInt(kvp.getKey))(collection.breakOut),
|
||||
c getBoolean "tls-session-info-header",
|
||||
_ ⇒ None,
|
||||
_ ⇒ None)
|
||||
}
|
||||
|
||||
sealed trait ErrorLoggingVerbosity
|
||||
object ErrorLoggingVerbosity {
|
||||
case object Off extends ErrorLoggingVerbosity
|
||||
case object Simple extends ErrorLoggingVerbosity
|
||||
case object Full extends ErrorLoggingVerbosity
|
||||
|
||||
def apply(string: String): ErrorLoggingVerbosity =
|
||||
string.toRootLowerCase match {
|
||||
case "off" ⇒ Off
|
||||
case "simple" ⇒ Simple
|
||||
case "full" ⇒ Full
|
||||
case x ⇒ throw new IllegalArgumentException(s"[$x] is not a legal `error-logging-verbosity` setting")
|
||||
}
|
||||
}
|
||||
|
||||
sealed trait CookieParsingMode
|
||||
object CookieParsingMode {
|
||||
case object RFC6265 extends CookieParsingMode
|
||||
case object Raw extends CookieParsingMode
|
||||
|
||||
def apply(mode: String): CookieParsingMode = mode.toRootLowerCase match {
|
||||
case "rfc6265" ⇒ RFC6265
|
||||
case "raw" ⇒ Raw
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of ParserSettings using the configuration provided by the given
|
||||
* ActorSystem.
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
def create(system: ActorSystem): ParserSettings = ParserSettings(system)
|
||||
|
||||
/**
|
||||
* Creates an instance of ParserSettings using the given Config.
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
def create(config: Config): ParserSettings = ParserSettings(config)
|
||||
|
||||
/**
|
||||
* Create an instance of ParserSettings using the given String of config overrides to override
|
||||
* settings set in the class loader of this class (i.e. by application.conf or reference.conf files in
|
||||
* the class loader of this class).
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
def create(configOverrides: String): ParserSettings = ParserSettings(configOverrides)
|
||||
|
||||
implicit def default(implicit refFactory: ActorRefFactory): ParserSettings =
|
||||
apply(actorSystem)
|
||||
|
||||
def apply(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]): ParserSettings =
|
||||
new ParserSettings(maxUriLength,
|
||||
maxMethodLength,
|
||||
maxResponseReasonLength,
|
||||
maxHeaderNameLength,
|
||||
maxHeaderValueLength,
|
||||
maxHeaderCount,
|
||||
maxContentLength,
|
||||
maxChunkExtLength,
|
||||
maxChunkSize,
|
||||
uriParsingMode,
|
||||
cookieParsingMode,
|
||||
illegalHeaderWarnings,
|
||||
errorLoggingVerbosity,
|
||||
headerValueCacheLimits,
|
||||
includeTlsSessionInfoHeader,
|
||||
customMethods,
|
||||
customStatusCodes)
|
||||
}
|
||||
|
||||
|
|
@ -1,211 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http
|
||||
|
||||
import java.util.Random
|
||||
|
||||
import akka.http.impl.engine.ws.Randoms
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import scala.language.implicitConversions
|
||||
import scala.collection.immutable
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import akka.ConfigurationException
|
||||
import akka.actor.{ ActorSystem, ActorRefFactory }
|
||||
import akka.io.Inet.SocketOption
|
||||
|
||||
import akka.http.impl.util._
|
||||
|
||||
import akka.http.scaladsl.model.HttpHeader
|
||||
import akka.http.scaladsl.model.headers.{ Host, Server }
|
||||
|
||||
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")
|
||||
require(0 < responseHeaderSizeHint, "response-size-hint must be > 0")
|
||||
require(0 < backlog, "backlog must be > 0")
|
||||
|
||||
def copy(
|
||||
serverHeader: Option[Server] = serverHeader,
|
||||
timeouts: ServerSettings.Timeouts = timeouts,
|
||||
maxConnections: Int = maxConnections,
|
||||
pipeliningLimit: Int = pipeliningLimit,
|
||||
remoteAddressHeader: Boolean = remoteAddressHeader,
|
||||
rawRequestUriHeader: Boolean = rawRequestUriHeader,
|
||||
transparentHeadRequests: Boolean = transparentHeadRequests,
|
||||
verboseErrorMessages: Boolean = verboseErrorMessages,
|
||||
responseHeaderSizeHint: Int = responseHeaderSizeHint,
|
||||
backlog: Int = backlog,
|
||||
socketOptions: immutable.Traversable[SocketOption] = socketOptions,
|
||||
defaultHostHeader: Host = defaultHostHeader,
|
||||
websocketRandomFactory: () ⇒ Random = websocketRandomFactory,
|
||||
parserSettings: ParserSettings = parserSettings) =
|
||||
new ServerSettings(
|
||||
serverHeader = serverHeader,
|
||||
timeouts = timeouts,
|
||||
maxConnections = maxConnections,
|
||||
pipeliningLimit = pipeliningLimit,
|
||||
remoteAddressHeader = remoteAddressHeader,
|
||||
rawRequestUriHeader = rawRequestUriHeader,
|
||||
transparentHeadRequests = transparentHeadRequests,
|
||||
verboseErrorMessages = verboseErrorMessages,
|
||||
responseHeaderSizeHint = responseHeaderSizeHint,
|
||||
backlog = backlog,
|
||||
socketOptions = socketOptions,
|
||||
defaultHostHeader = defaultHostHeader,
|
||||
websocketRandomFactory = websocketRandomFactory,
|
||||
parserSettings = parserSettings)
|
||||
|
||||
// TODO we should automate generating those
|
||||
override def toString: String = {
|
||||
getClass.getSimpleName + "(" +
|
||||
serverHeader + "," +
|
||||
timeouts + "," +
|
||||
maxConnections + "," +
|
||||
pipeliningLimit + "," +
|
||||
remoteAddressHeader + "," +
|
||||
rawRequestUriHeader + "," +
|
||||
transparentHeadRequests + "," +
|
||||
verboseErrorMessages + "," +
|
||||
responseHeaderSizeHint + "," +
|
||||
backlog + "," +
|
||||
socketOptions + "," +
|
||||
defaultHostHeader + "," +
|
||||
websocketRandomFactory + "," +
|
||||
parserSettings + "," +
|
||||
")"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object ServerSettings extends SettingsCompanion[ServerSettings]("akka.http.server") {
|
||||
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")
|
||||
|
||||
def copy(
|
||||
idleTimeout: Duration = idleTimeout,
|
||||
requestTimeout: Duration = requestTimeout,
|
||||
bindTimeout: FiniteDuration = bindTimeout) =
|
||||
new Timeouts(
|
||||
idleTimeout,
|
||||
requestTimeout,
|
||||
bindTimeout)
|
||||
|
||||
override def toString = {
|
||||
"Timeouts(" +
|
||||
idleTimeout + "," +
|
||||
requestTimeout + "," +
|
||||
bindTimeout + "," +
|
||||
")"
|
||||
}
|
||||
}
|
||||
implicit def timeoutsShortcut(s: ServerSettings): Timeouts = s.timeouts
|
||||
|
||||
def fromSubConfig(root: Config, c: Config) = new ServerSettings(
|
||||
c.getString("server-header").toOption.map(Server(_)),
|
||||
new Timeouts(
|
||||
c getPotentiallyInfiniteDuration "idle-timeout",
|
||||
c getPotentiallyInfiniteDuration "request-timeout",
|
||||
c getFiniteDuration "bind-timeout"),
|
||||
c getInt "max-connections",
|
||||
c getInt "pipelining-limit",
|
||||
c getBoolean "remote-address-header",
|
||||
c getBoolean "raw-request-uri-header",
|
||||
c getBoolean "transparent-head-requests",
|
||||
c getBoolean "verbose-error-messages",
|
||||
c getIntBytes "response-header-size-hint",
|
||||
c getInt "backlog",
|
||||
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
|
||||
case result ⇒
|
||||
val info = result.errors.head.withSummary("Configured `default-host-header` is illegal")
|
||||
throw new ConfigurationException(info.formatPretty)
|
||||
},
|
||||
Randoms.SecureRandomInstances, // can currently only be overridden from code
|
||||
ParserSettings.fromSubConfig(root, c.getConfig("parsing")))
|
||||
|
||||
def apply(optionalSettings: Option[ServerSettings])(implicit actorRefFactory: ActorRefFactory): ServerSettings =
|
||||
optionalSettings getOrElse apply(actorSystem)
|
||||
|
||||
/**
|
||||
* Creates an instance of ServerSettings using the configuration provided by the given
|
||||
* ActorSystem.
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
def create(system: ActorSystem): ServerSettings = ServerSettings(system)
|
||||
|
||||
/**
|
||||
* Creates an instance of ServerSettings using the given Config.
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
def create(config: Config): ServerSettings = ServerSettings(config)
|
||||
|
||||
/**
|
||||
* Create an instance of ServerSettings using the given String of config overrides to override
|
||||
* settings set in the class loader of this class (i.e. by application.conf or reference.conf files in
|
||||
* the class loader of this class).
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
def create(configOverrides: String): ServerSettings = ServerSettings(configOverrides)
|
||||
|
||||
def apply(
|
||||
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) =
|
||||
new ServerSettings(
|
||||
serverHeader = serverHeader,
|
||||
timeouts = timeouts,
|
||||
maxConnections = maxConnections,
|
||||
pipeliningLimit = pipeliningLimit,
|
||||
remoteAddressHeader = remoteAddressHeader,
|
||||
rawRequestUriHeader = rawRequestUriHeader,
|
||||
transparentHeadRequests = transparentHeadRequests,
|
||||
verboseErrorMessages = verboseErrorMessages,
|
||||
responseHeaderSizeHint = responseHeaderSizeHint,
|
||||
backlog = backlog,
|
||||
socketOptions = socketOptions,
|
||||
defaultHostHeader = defaultHostHeader,
|
||||
websocketRandomFactory = websocketRandomFactory,
|
||||
parserSettings = parserSettings)
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
package akka.http.impl.engine.client
|
||||
|
||||
import akka.NotUsed
|
||||
import akka.stream.impl.fusing.GraphInterpreter
|
||||
import akka.http.scaladsl.settings.ClientConnectionSettings
|
||||
import language.existentials
|
||||
import scala.annotation.tailrec
|
||||
import scala.collection.mutable.ListBuffer
|
||||
|
|
@ -14,7 +14,6 @@ import akka.util.ByteString
|
|||
import akka.event.LoggingAdapter
|
||||
import akka.stream._
|
||||
import akka.stream.scaladsl._
|
||||
import akka.http.ClientConnectionSettings
|
||||
import akka.http.scaladsl.Http
|
||||
import akka.http.scaladsl.model.headers.Host
|
||||
import akka.http.scaladsl.model.{ IllegalResponseException, HttpMethod, HttpRequest, HttpResponse }
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ package akka.http.impl.engine.client
|
|||
|
||||
import java.net.InetSocketAddress
|
||||
import akka.NotUsed
|
||||
import akka.http.ConnectionPoolSettings
|
||||
import akka.http.scaladsl.settings.ConnectionPoolSettings
|
||||
|
||||
import scala.concurrent.{ Promise, Future }
|
||||
import scala.util.Try
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package akka.http.impl.engine.client
|
|||
import java.util.concurrent.atomic.AtomicReference
|
||||
import scala.annotation.tailrec
|
||||
import scala.concurrent.{ Future, Promise }
|
||||
import akka.http.HostConnectionPoolSetup
|
||||
import akka.http.impl.settings.HostConnectionPoolSetup
|
||||
import akka.actor.{ Deploy, Props, ActorSystem, ActorRef }
|
||||
import akka.http.scaladsl.Http
|
||||
import akka.http.scaladsl.model.{ HttpResponse, HttpRequest }
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import akka.stream.actor.ActorPublisherMessage._
|
|||
import akka.stream.actor.ActorSubscriberMessage._
|
||||
import akka.stream.impl.{ SeqActorName, FixedSizeBuffer }
|
||||
import akka.stream.scaladsl.{ Keep, Flow, Sink, Source }
|
||||
import akka.http.HostConnectionPoolSetup
|
||||
import akka.http.impl.settings.HostConnectionPoolSetup
|
||||
import akka.http.scaladsl.model._
|
||||
import akka.http.scaladsl.{ ConnectionContext, HttpsConnectionContext, Http }
|
||||
import PoolFlow._
|
||||
|
|
|
|||
|
|
@ -7,10 +7,9 @@ package akka.http.impl.engine.client
|
|||
import java.net.InetSocketAddress
|
||||
|
||||
import akka.actor._
|
||||
import akka.http.ConnectionPoolSettings
|
||||
import akka.http.scaladsl.settings.ConnectionPoolSettings
|
||||
import akka.http.impl.util._
|
||||
import akka.http.scaladsl.model.{ HttpEntity, HttpRequest, HttpResponse }
|
||||
import akka.http.scaladsl.util.FastFuture
|
||||
import akka.stream._
|
||||
import akka.stream.actor._
|
||||
import akka.stream.impl.{ ActorProcessor, ExposedPublisher, SeqActorName, SubscribePending }
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import akka.parboiled2.CharUtils
|
|||
import akka.util.ByteString
|
||||
import akka.stream.stage._
|
||||
import akka.http.impl.model.parser.CharacterClasses
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
import akka.http.scaladsl.model._
|
||||
import headers._
|
||||
import HttpProtocols._
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ package akka.http.impl.engine.parsing
|
|||
|
||||
import java.lang.{ StringBuilder ⇒ JStringBuilder }
|
||||
import scala.annotation.tailrec
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
import akka.util.ByteString
|
||||
import akka.http.impl.engine.ws.Handshake
|
||||
import akka.http.impl.model.parser.CharacterClasses
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
package akka.http.impl.engine.parsing
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
import akka.http.impl.model.parser.CharacterClasses
|
||||
import akka.util.ByteString
|
||||
import akka.http.scaladsl.model._
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
package akka.http.impl.engine
|
||||
|
||||
import java.lang.{ StringBuilder ⇒ JStringBuilder }
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import akka.event.LoggingAdapter
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package akka.http.impl.engine.rendering
|
||||
|
||||
import akka.http.ClientConnectionSettings
|
||||
import akka.http.scaladsl.settings.ClientConnectionSettings
|
||||
import akka.http.scaladsl.model.RequestEntityAcceptance._
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import akka.stream._
|
|||
import akka.stream.io._
|
||||
import akka.stream.scaladsl._
|
||||
import akka.stream.stage._
|
||||
import akka.http.ServerSettings
|
||||
import akka.http.scaladsl.settings.ServerSettings
|
||||
import akka.http.impl.engine.HttpConnectionTimeoutException
|
||||
import akka.http.impl.engine.parsing.ParserOutput._
|
||||
import akka.http.impl.engine.parsing._
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import akka.stream.BidiShape
|
|||
import akka.stream.io.{ SessionBytes, SendBytes, SslTlsInbound }
|
||||
import akka.stream.scaladsl._
|
||||
|
||||
import akka.http.ClientConnectionSettings
|
||||
import akka.http.scaladsl.settings.ClientConnectionSettings
|
||||
import akka.http.scaladsl.Http
|
||||
import akka.http.scaladsl.model.{ HttpResponse, HttpMethods }
|
||||
import akka.http.scaladsl.model.headers.Host
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
package akka.http.impl.model.parser
|
||||
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.ParserSettings.CookieParsingMode
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings.CookieParsingMode
|
||||
import akka.http.scaladsl.model.headers.HttpCookiePair
|
||||
import scala.util.control.NonFatal
|
||||
import akka.http.impl.util.SingletonException
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.impl.settings
|
||||
|
||||
import java.util.Random
|
||||
|
||||
import akka.http.impl.engine.ws.Randoms
|
||||
import akka.http.impl.util._
|
||||
import akka.http.scaladsl.model.headers.`User-Agent`
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
import akka.io.Inet.SocketOption
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import scala.collection.immutable
|
||||
import scala.concurrent.duration.{ Duration, FiniteDuration }
|
||||
|
||||
/** INTERNAL API */
|
||||
private[akka] final case class ClientConnectionSettingsImpl(
|
||||
userAgentHeader: Option[`User-Agent`],
|
||||
connectingTimeout: FiniteDuration,
|
||||
idleTimeout: Duration,
|
||||
requestHeaderSizeHint: Int,
|
||||
websocketRandomFactory: () ⇒ Random,
|
||||
socketOptions: immutable.Seq[SocketOption],
|
||||
parserSettings: ParserSettings)
|
||||
extends akka.http.scaladsl.settings.ClientConnectionSettings {
|
||||
|
||||
require(connectingTimeout >= Duration.Zero, "connectingTimeout must be >= 0")
|
||||
require(requestHeaderSizeHint > 0, "request-size-hint must be > 0")
|
||||
}
|
||||
|
||||
object ClientConnectionSettingsImpl extends SettingsCompanion[ClientConnectionSettingsImpl]("akka.http.client") {
|
||||
def fromSubConfig(root: Config, inner: Config) = {
|
||||
val c = inner.withFallback(root.getConfig(prefix))
|
||||
new ClientConnectionSettingsImpl(
|
||||
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 = ParserSettingsImpl.fromSubConfig(root, c.getConfig("parsing")))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* Copyright (C) 2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.impl.settings
|
||||
|
||||
import akka.http.impl.util.SettingsCompanion
|
||||
import akka.http.impl.util._
|
||||
import akka.http.scaladsl.settings.{ ConnectionPoolSettings, ClientConnectionSettings }
|
||||
import com.typesafe.config.Config
|
||||
import scala.concurrent.duration.Duration
|
||||
|
||||
/** INTERNAL API */
|
||||
private[akka] final case class ConnectionPoolSettingsImpl(
|
||||
val maxConnections: Int,
|
||||
val maxRetries: Int,
|
||||
val maxOpenRequests: Int,
|
||||
val pipeliningLimit: Int,
|
||||
val idleTimeout: Duration,
|
||||
val connectionSettings: ClientConnectionSettings)
|
||||
extends ConnectionPoolSettings {
|
||||
|
||||
require(maxConnections > 0, "max-connections must be > 0")
|
||||
require(maxRetries >= 0, "max-retries must be >= 0")
|
||||
require(maxOpenRequests > 0 && (maxOpenRequests & (maxOpenRequests - 1)) == 0, "max-open-requests must be a power of 2 > 0")
|
||||
require(pipeliningLimit > 0, "pipelining-limit must be > 0")
|
||||
require(idleTimeout >= Duration.Zero, "idle-timeout must be >= 0")
|
||||
|
||||
}
|
||||
|
||||
object ConnectionPoolSettingsImpl extends SettingsCompanion[ConnectionPoolSettingsImpl]("akka.http.host-connection-pool") {
|
||||
def fromSubConfig(root: Config, c: Config) = {
|
||||
ConnectionPoolSettingsImpl(
|
||||
c getInt "max-connections",
|
||||
c getInt "max-retries",
|
||||
c getInt "max-open-requests",
|
||||
c getInt "pipelining-limit",
|
||||
c getPotentiallyInfiniteDuration "idle-timeout",
|
||||
ClientConnectionSettingsImpl.fromSubConfig(root, c.getConfig("client")))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Copyright (C) 2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.impl.settings
|
||||
|
||||
import akka.event.LoggingAdapter
|
||||
import akka.http.scaladsl.ConnectionContext
|
||||
import akka.http.scaladsl.settings.ConnectionPoolSettings
|
||||
|
||||
/** INTERNAL API */
|
||||
private[akka] final case class ConnectionPoolSetup(
|
||||
settings: ConnectionPoolSettings,
|
||||
connectionContext: ConnectionContext = ConnectionContext.noEncryption(),
|
||||
log: LoggingAdapter)
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/**
|
||||
* Copyright (C) 2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.impl.settings
|
||||
|
||||
/** INTERNAL API */
|
||||
final case class HostConnectionPoolSetup(host: String, port: Int, setup: ConnectionPoolSetup)
|
||||
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.impl.settings
|
||||
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings.{ ErrorLoggingVerbosity, CookieParsingMode }
|
||||
import com.typesafe.config.Config
|
||||
import scala.collection.JavaConverters._
|
||||
import akka.http.scaladsl.model.{ StatusCode, HttpMethod, Uri }
|
||||
import akka.http.impl.util._
|
||||
|
||||
/** INTERNAL API */
|
||||
private[akka] final case class ParserSettingsImpl(
|
||||
maxUriLength: Int,
|
||||
maxMethodLength: Int,
|
||||
maxResponseReasonLength: Int,
|
||||
maxHeaderNameLength: Int,
|
||||
maxHeaderValueLength: Int,
|
||||
maxHeaderCount: Int,
|
||||
maxContentLength: Long,
|
||||
maxChunkExtLength: Int,
|
||||
maxChunkSize: Int,
|
||||
uriParsingMode: Uri.ParsingMode,
|
||||
cookieParsingMode: CookieParsingMode,
|
||||
illegalHeaderWarnings: Boolean,
|
||||
errorLoggingVerbosity: ParserSettings.ErrorLoggingVerbosity,
|
||||
headerValueCacheLimits: Map[String, Int],
|
||||
includeTlsSessionInfoHeader: Boolean,
|
||||
customMethods: String ⇒ Option[HttpMethod],
|
||||
customStatusCodes: Int ⇒ Option[StatusCode])
|
||||
extends akka.http.scaladsl.settings.ParserSettings {
|
||||
|
||||
require(maxUriLength > 0, "max-uri-length must be > 0")
|
||||
require(maxMethodLength > 0, "max-method-length must be > 0")
|
||||
require(maxResponseReasonLength > 0, "max-response-reason-length must be > 0")
|
||||
require(maxHeaderNameLength > 0, "max-header-name-length must be > 0")
|
||||
require(maxHeaderValueLength > 0, "max-header-value-length must be > 0")
|
||||
require(maxHeaderCount > 0, "max-header-count must be > 0")
|
||||
require(maxContentLength > 0, "max-content-length must be > 0")
|
||||
require(maxChunkExtLength > 0, "max-chunk-ext-length must be > 0")
|
||||
require(maxChunkSize > 0, "max-chunk-size must be > 0")
|
||||
|
||||
override val defaultHeaderValueCacheLimit: Int = headerValueCacheLimits("default")
|
||||
|
||||
override def headerValueCacheLimit(headerName: String): Int =
|
||||
headerValueCacheLimits.getOrElse(headerName, defaultHeaderValueCacheLimit)
|
||||
}
|
||||
|
||||
object ParserSettingsImpl extends SettingsCompanion[ParserSettingsImpl]("akka.http.parsing") {
|
||||
def fromSubConfig(root: Config, inner: Config) = {
|
||||
val c = inner.withFallback(root.getConfig(prefix))
|
||||
val cacheConfig = c getConfig "header-cache"
|
||||
|
||||
new ParserSettingsImpl(
|
||||
c getIntBytes "max-uri-length",
|
||||
c getIntBytes "max-method-length",
|
||||
c getIntBytes "max-response-reason-length",
|
||||
c getIntBytes "max-header-name-length",
|
||||
c getIntBytes "max-header-value-length",
|
||||
c getIntBytes "max-header-count",
|
||||
c getPossiblyInfiniteBytes "max-content-length",
|
||||
c getIntBytes "max-chunk-ext-length",
|
||||
c getIntBytes "max-chunk-size",
|
||||
Uri.ParsingMode(c getString "uri-parsing-mode"),
|
||||
CookieParsingMode(c getString "cookie-parsing-mode"),
|
||||
c getBoolean "illegal-header-warnings",
|
||||
ErrorLoggingVerbosity(c getString "error-logging-verbosity"),
|
||||
cacheConfig.entrySet.asScala.map(kvp ⇒ kvp.getKey -> cacheConfig.getInt(kvp.getKey))(collection.breakOut),
|
||||
c getBoolean "tls-session-info-header",
|
||||
_ ⇒ None,
|
||||
_ ⇒ None)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/**
|
||||
* Copyright (C) 2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.impl.settings
|
||||
|
||||
import java.util.Random
|
||||
|
||||
import akka.http.impl.engine.ws.Randoms
|
||||
import akka.http.scaladsl.settings.{ ServerSettings, ParserSettings }
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import scala.language.implicitConversions
|
||||
import scala.collection.immutable
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import akka.http.javadsl.{ settings ⇒ js }
|
||||
import akka.ConfigurationException
|
||||
import akka.io.Inet.SocketOption
|
||||
|
||||
import akka.http.impl.util._
|
||||
|
||||
import akka.http.scaladsl.model.HttpHeader
|
||||
import akka.http.scaladsl.model.headers.{ Host, Server }
|
||||
|
||||
/** INTERNAL API */
|
||||
private[akka] final case class ServerSettingsImpl(
|
||||
serverHeader: Option[Server],
|
||||
timeouts: ServerSettings.Timeouts,
|
||||
maxConnections: Int,
|
||||
pipeliningLimit: Int,
|
||||
remoteAddressHeader: Boolean,
|
||||
rawRequestUriHeader: Boolean,
|
||||
transparentHeadRequests: Boolean,
|
||||
verboseErrorMessages: Boolean,
|
||||
responseHeaderSizeHint: Int,
|
||||
backlog: Int,
|
||||
socketOptions: immutable.Seq[SocketOption],
|
||||
defaultHostHeader: Host,
|
||||
websocketRandomFactory: () ⇒ Random,
|
||||
parserSettings: ParserSettings) extends ServerSettings {
|
||||
|
||||
require(0 < maxConnections, "max-connections must be > 0")
|
||||
require(0 < pipeliningLimit && pipeliningLimit <= 1024, "pipelining-limit must be > 0 and <= 1024")
|
||||
require(0 < responseHeaderSizeHint, "response-size-hint must be > 0")
|
||||
require(0 < backlog, "backlog must be > 0")
|
||||
|
||||
}
|
||||
|
||||
object ServerSettingsImpl extends SettingsCompanion[ServerSettingsImpl]("akka.http.server") {
|
||||
implicit def timeoutsShortcut(s: js.ServerSettings): js.ServerSettings.Timeouts = s.getTimeouts
|
||||
|
||||
/** INTERNAL API */
|
||||
final case class Timeouts(
|
||||
idleTimeout: Duration,
|
||||
requestTimeout: Duration,
|
||||
bindTimeout: FiniteDuration) extends ServerSettings.Timeouts {
|
||||
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")
|
||||
}
|
||||
|
||||
def fromSubConfig(root: Config, c: Config) = new ServerSettingsImpl(
|
||||
c.getString("server-header").toOption.map(Server(_)),
|
||||
new Timeouts(
|
||||
c getPotentiallyInfiniteDuration "idle-timeout",
|
||||
c getPotentiallyInfiniteDuration "request-timeout",
|
||||
c getFiniteDuration "bind-timeout"),
|
||||
c getInt "max-connections",
|
||||
c getInt "pipelining-limit",
|
||||
c getBoolean "remote-address-header",
|
||||
c getBoolean "raw-request-uri-header",
|
||||
c getBoolean "transparent-head-requests",
|
||||
c getBoolean "verbose-error-messages",
|
||||
c getIntBytes "response-header-size-hint",
|
||||
c getInt "backlog",
|
||||
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
|
||||
case result ⇒
|
||||
val info = result.errors.head.withSummary("Configured `default-host-header` is illegal")
|
||||
throw new ConfigurationException(info.formatPretty)
|
||||
},
|
||||
Randoms.SecureRandomInstances, // can currently only be overridden from code
|
||||
ParserSettingsImpl.fromSubConfig(root, c.getConfig("parsing")))
|
||||
|
||||
// def apply(optionalSettings: Option[ServerSettings])(implicit actorRefFactory: ActorRefFactory): ServerSettings =
|
||||
// optionalSettings getOrElse apply(actorSystem)
|
||||
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ import akka.{ NotUsed, japi }
|
|||
import akka.http.impl.model.{ JavaQuery, JavaUri }
|
||||
import akka.http.javadsl.{ model ⇒ jm, HttpConnectionContext, ConnectionContext, HttpsConnectionContext }
|
||||
import akka.http.scaladsl.{ model ⇒ sm }
|
||||
import akka.http.javadsl.{ settings ⇒ js }
|
||||
|
||||
import scala.compat.java8.OptionConverters._
|
||||
|
||||
|
|
@ -168,6 +169,14 @@ private[http] object JavaMapping {
|
|||
implicit object HttpConnectionContext extends Inherited[HttpConnectionContext, akka.http.scaladsl.HttpConnectionContext]
|
||||
implicit object HttpsConnectionContext extends Inherited[HttpsConnectionContext, akka.http.scaladsl.HttpsConnectionContext]
|
||||
|
||||
implicit object ClientConnectionSettings extends Inherited[js.ClientConnectionSettings, akka.http.scaladsl.settings.ClientConnectionSettings]
|
||||
implicit object ConnectionPoolSettings extends Inherited[js.ConnectionPoolSettings, akka.http.scaladsl.settings.ConnectionPoolSettings]
|
||||
implicit object ParserSettings extends Inherited[js.ParserSettings, akka.http.scaladsl.settings.ParserSettings]
|
||||
implicit object CookieParsingMode extends Inherited[js.ParserSettings.CookieParsingMode, akka.http.scaladsl.settings.ParserSettings.CookieParsingMode]
|
||||
implicit object ErrorLoggingVerbosity extends Inherited[js.ParserSettings.ErrorLoggingVerbosity, akka.http.scaladsl.settings.ParserSettings.ErrorLoggingVerbosity]
|
||||
implicit object ServerSettings extends Inherited[js.ServerSettings, akka.http.scaladsl.settings.ServerSettings]
|
||||
implicit object ServerSettingsT extends Inherited[js.ServerSettings.Timeouts, akka.http.scaladsl.settings.ServerSettings.Timeouts]
|
||||
|
||||
implicit object DateTime extends Inherited[jm.DateTime, akka.http.scaladsl.model.DateTime]
|
||||
|
||||
implicit object ContentType extends Inherited[jm.ContentType, sm.ContentType]
|
||||
|
|
@ -198,9 +207,10 @@ private[http] object JavaMapping {
|
|||
implicit object TransferEncoding extends Inherited[jm.TransferEncoding, sm.TransferEncoding]
|
||||
|
||||
implicit object HostHeader extends Inherited[jm.headers.Host, sm.headers.Host]
|
||||
|
||||
implicit object Server extends Inherited[jm.headers.Server, sm.headers.Server]
|
||||
implicit object ByteRange extends Inherited[jm.headers.ByteRange, sm.headers.ByteRange]
|
||||
implicit object CacheDirective extends Inherited[jm.headers.CacheDirective, sm.headers.CacheDirective]
|
||||
implicit object UserAgent extends Inherited[jm.headers.UserAgent, sm.headers.`User-Agent`]
|
||||
implicit object ContentDispositionType extends Inherited[jm.headers.ContentDispositionType, sm.headers.ContentDispositionType]
|
||||
implicit object EntityTag extends Inherited[jm.headers.EntityTag, sm.headers.EntityTag]
|
||||
implicit object EntityTagRange extends Inherited[jm.headers.EntityTagRange, sm.headers.EntityTagRange]
|
||||
|
|
@ -228,6 +238,7 @@ private[http] object JavaMapping {
|
|||
def toScala(javaObject: J): Uri.S = cast[JavaUri](javaObject).uri
|
||||
def toJava(scalaObject: S): Uri.J = JavaUri(scalaObject)
|
||||
}
|
||||
implicit object UriParsingMode extends Inherited[jm.Uri.ParsingMode, akka.http.scaladsl.model.Uri.ParsingMode]
|
||||
|
||||
implicit object Query extends JavaMapping[jm.Query, sm.Uri.Query] {
|
||||
def toScala(javaObject: J): Query.S = cast[JavaQuery](javaObject).query
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import com.typesafe.config.ConfigFactory._
|
|||
import scala.util.control.NonFatal
|
||||
import scala.collection.immutable.ListMap
|
||||
import scala.collection.JavaConverters._
|
||||
import akka.actor.ActorSystem
|
||||
import akka.actor.{ ActorRefFactory, ActorSystem }
|
||||
|
||||
/**
|
||||
* INTERNAL API
|
||||
|
|
@ -19,6 +19,9 @@ private[http] abstract class SettingsCompanion[T](protected val prefix: String)
|
|||
private final val MaxCached = 8
|
||||
private[this] var cache = ListMap.empty[ActorSystem, T]
|
||||
|
||||
implicit def default(implicit refFactory: ActorRefFactory): T =
|
||||
apply(actorSystem)
|
||||
|
||||
def apply(system: ActorSystem): T =
|
||||
// we use and update the cache without any synchronization,
|
||||
// there are two possible "problems" resulting from this:
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import akka.io.Inet.SocketOption
|
|||
import com.typesafe.config.Config
|
||||
|
||||
private[http] object SocketOptionSettings {
|
||||
def fromSubConfig(root: Config, c: Config): immutable.Traversable[SocketOption] = {
|
||||
def fromSubConfig(root: Config, c: Config): immutable.Seq[SocketOption] = {
|
||||
def so[T](setting: String)(f: (Config, String) ⇒ T)(cons: T ⇒ SocketOption): List[SocketOption] =
|
||||
c.getString(setting) match {
|
||||
case "undefined" ⇒ Nil
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package akka.http.javadsl
|
||||
|
||||
import akka.http.HostConnectionPoolSetup
|
||||
import akka.http.impl.settings.HostConnectionPoolSetup
|
||||
|
||||
trait HostConnectionPool {
|
||||
def setup: HostConnectionPoolSetup
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ package akka.http.javadsl
|
|||
|
||||
import java.net.InetSocketAddress
|
||||
import java.util.Optional
|
||||
import akka.http.impl.settings.HostConnectionPoolSetup
|
||||
import akka.http.impl.util.JavaMapping
|
||||
import akka.http.impl.util.JavaMapping.HttpsConnectionContext
|
||||
import akka.http.javadsl.model.ws._
|
||||
import akka.{ stream, NotUsed }
|
||||
import akka.http.javadsl.settings.{ ConnectionPoolSettings, ClientConnectionSettings, ServerSettings }
|
||||
import akka.{ NotUsed, stream }
|
||||
import akka.stream.io.{ SslTlsInbound, SslTlsOutbound }
|
||||
import scala.language.implicitConversions
|
||||
import scala.concurrent.Future
|
||||
|
|
@ -44,29 +46,29 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
private lazy val delegate = akka.http.scaladsl.Http(system)
|
||||
|
||||
/**
|
||||
* Constructs a server layer stage using the configured default [[ServerSettings]]. The returned [[BidiFlow]] isn't
|
||||
* Constructs a server layer stage using the configured default [[akka.http.javadsl.settings.ServerSettings]]. The returned [[BidiFlow]] isn't
|
||||
* reusable and can only be materialized once.
|
||||
*/
|
||||
def serverLayer(materializer: Materializer): BidiFlow[HttpResponse, SslTlsOutbound, SslTlsInbound, HttpRequest, NotUsed] =
|
||||
adaptServerLayer(delegate.serverLayer()(materializer))
|
||||
|
||||
/**
|
||||
* Constructs a server layer stage using the given [[ServerSettings]]. The returned [[BidiFlow]] isn't reusable and
|
||||
* Constructs a server layer stage using the given [[akka.http.javadsl.settings.ServerSettings]]. The returned [[BidiFlow]] isn't reusable and
|
||||
* can only be materialized once.
|
||||
*/
|
||||
def serverLayer(settings: ServerSettings,
|
||||
materializer: Materializer): BidiFlow[HttpResponse, SslTlsOutbound, SslTlsInbound, HttpRequest, NotUsed] =
|
||||
adaptServerLayer(delegate.serverLayer(settings)(materializer))
|
||||
adaptServerLayer(delegate.serverLayer(settings.asScala)(materializer))
|
||||
|
||||
/**
|
||||
* Constructs a server layer stage using the given [[ServerSettings]]. The returned [[BidiFlow]] isn't reusable and
|
||||
* Constructs a server layer stage using the given [[akka.http.javadsl.settings.ServerSettings]]. The returned [[BidiFlow]] isn't reusable and
|
||||
* can only be materialized once. The `remoteAddress`, if provided, will be added as a header to each [[HttpRequest]]
|
||||
* this layer produces if the `akka.http.server.remote-address-header` configuration option is enabled.
|
||||
*/
|
||||
def serverLayer(settings: ServerSettings,
|
||||
remoteAddress: Optional[InetSocketAddress],
|
||||
materializer: Materializer): BidiFlow[HttpResponse, SslTlsOutbound, SslTlsInbound, HttpRequest, NotUsed] =
|
||||
adaptServerLayer(delegate.serverLayer(settings, remoteAddress.asScala)(materializer))
|
||||
adaptServerLayer(delegate.serverLayer(settings.asScala, remoteAddress.asScala)(materializer))
|
||||
|
||||
/**
|
||||
* Constructs a server layer stage using the given [[ServerSettings]]. The returned [[BidiFlow]] isn't reusable and
|
||||
|
|
@ -77,7 +79,7 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
remoteAddress: Optional[InetSocketAddress],
|
||||
log: LoggingAdapter,
|
||||
materializer: Materializer): BidiFlow[HttpResponse, SslTlsOutbound, SslTlsInbound, HttpRequest, NotUsed] =
|
||||
adaptServerLayer(delegate.serverLayer(settings, remoteAddress.asScala, log)(materializer))
|
||||
adaptServerLayer(delegate.serverLayer(settings.asScala, remoteAddress.asScala, log)(materializer))
|
||||
|
||||
/**
|
||||
* Creates a [[Source]] of [[IncomingConnection]] instances which represents a prospective HTTP server binding
|
||||
|
|
@ -110,7 +112,7 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
connectionContext: ConnectionContext,
|
||||
settings: ServerSettings,
|
||||
materializer: Materializer): Source[IncomingConnection, CompletionStage[ServerBinding]] =
|
||||
new Source(delegate.bind(interface, port, settings = settings, connectionContext = ConnectionContext.noEncryption().asScala)(materializer)
|
||||
new Source(delegate.bind(interface, port, settings = settings.asScala, connectionContext = ConnectionContext.noEncryption().asScala)(materializer)
|
||||
.map(new IncomingConnection(_))
|
||||
.mapMaterializedValue(_.map(new ServerBinding(_))(ec).toJava))
|
||||
|
||||
|
|
@ -150,7 +152,7 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
settings: ServerSettings,
|
||||
log: LoggingAdapter,
|
||||
materializer: Materializer): Source[IncomingConnection, CompletionStage[ServerBinding]] =
|
||||
new Source(delegate.bind(interface, port, ConnectionContext.noEncryption().asScala, settings, log)(materializer)
|
||||
new Source(delegate.bind(interface, port, ConnectionContext.noEncryption().asScala, settings.asScala, log)(materializer)
|
||||
.map(new IncomingConnection(_))
|
||||
.mapMaterializedValue(_.map(new ServerBinding(_))(ec).toJava))
|
||||
|
||||
|
|
@ -197,7 +199,7 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
log: LoggingAdapter,
|
||||
materializer: Materializer): CompletionStage[ServerBinding] =
|
||||
delegate.bindAndHandle(handler.asInstanceOf[Flow[sm.HttpRequest, sm.HttpResponse, _]].asScala,
|
||||
interface, port, connectionContext.asScala, settings, log)(materializer)
|
||||
interface, port, connectionContext.asScala, settings.asScala, log)(materializer)
|
||||
.map(new ServerBinding(_))(ec).toJava
|
||||
|
||||
/**
|
||||
|
|
@ -241,7 +243,7 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
log: LoggingAdapter,
|
||||
materializer: Materializer): CompletionStage[ServerBinding] =
|
||||
delegate.bindAndHandleSync(handler.apply(_).asScala,
|
||||
interface, port, connectionContext.asScala, settings, log)(materializer)
|
||||
interface, port, connectionContext.asScala, settings.asScala, log)(materializer)
|
||||
.map(new ServerBinding(_))(ec).toJava
|
||||
|
||||
/**
|
||||
|
|
@ -284,21 +286,21 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
parallelism: Int, log: LoggingAdapter,
|
||||
materializer: Materializer): CompletionStage[ServerBinding] =
|
||||
delegate.bindAndHandleAsync(handler.apply(_).toScala,
|
||||
interface, port, connectionContext.asScala, settings, parallelism, log)(materializer)
|
||||
interface, port, connectionContext.asScala, settings.asScala, parallelism, log)(materializer)
|
||||
.map(new ServerBinding(_))(ec).toJava
|
||||
|
||||
/**
|
||||
* Constructs a client layer stage using the configured default [[ClientConnectionSettings]].
|
||||
* Constructs a client layer stage using the configured default [[akka.http.javadsl.settings.ClientConnectionSettings]].
|
||||
*/
|
||||
def clientLayer(hostHeader: headers.Host): BidiFlow[HttpRequest, SslTlsOutbound, SslTlsInbound, HttpResponse, NotUsed] =
|
||||
adaptClientLayer(delegate.clientLayer(JavaMapping.toScala(hostHeader)))
|
||||
|
||||
/**
|
||||
* Constructs a client layer stage using the given [[ClientConnectionSettings]].
|
||||
* Constructs a client layer stage using the given [[akka.http.javadsl.settings.ClientConnectionSettings]].
|
||||
*/
|
||||
def clientLayer(hostHeader: headers.Host,
|
||||
settings: ClientConnectionSettings): BidiFlow[HttpRequest, SslTlsOutbound, SslTlsInbound, HttpResponse, NotUsed] =
|
||||
adaptClientLayer(delegate.clientLayer(JavaMapping.toScala(hostHeader), settings))
|
||||
adaptClientLayer(delegate.clientLayer(JavaMapping.toScala(hostHeader), settings.asScala))
|
||||
|
||||
/**
|
||||
* Constructs a client layer stage using the given [[ClientConnectionSettings]].
|
||||
|
|
@ -306,7 +308,7 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
def clientLayer(hostHeader: headers.Host,
|
||||
settings: ClientConnectionSettings,
|
||||
log: LoggingAdapter): BidiFlow[HttpRequest, SslTlsOutbound, SslTlsInbound, HttpResponse, NotUsed] =
|
||||
adaptClientLayer(delegate.clientLayer(JavaMapping.toScala(hostHeader), settings, log))
|
||||
adaptClientLayer(delegate.clientLayer(JavaMapping.toScala(hostHeader), settings.asScala, log))
|
||||
|
||||
/**
|
||||
* Creates a [[Flow]] representing a prospective HTTP client connection to the given endpoint.
|
||||
|
|
@ -340,8 +342,8 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
log: LoggingAdapter): Flow[HttpRequest, HttpResponse, CompletionStage[OutgoingConnection]] =
|
||||
adaptOutgoingFlow {
|
||||
connectionContext match {
|
||||
case https: HttpsConnectionContext ⇒ delegate.outgoingConnectionHttps(host, port, https.asScala, localAddress.asScala, settings, log)
|
||||
case _ ⇒ delegate.outgoingConnection(host, port, localAddress.asScala, settings, log)
|
||||
case https: HttpsConnectionContext ⇒ delegate.outgoingConnectionHttps(host, port, https.asScala, localAddress.asScala, settings.asScala, log)
|
||||
case _ ⇒ delegate.outgoingConnection(host, port, localAddress.asScala, settings.asScala, log)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -389,8 +391,8 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
log: LoggingAdapter, materializer: Materializer): Flow[Pair[HttpRequest, T], Pair[Try[HttpResponse], T], HostConnectionPool] =
|
||||
adaptTupleFlow {
|
||||
to.effectiveConnectionContext(defaultClientHttpsContext) match {
|
||||
case https: HttpsConnectionContext ⇒ delegate.newHostConnectionPoolHttps[T](to.host, to.port, https.asScala, settings, log)(materializer)
|
||||
case _ ⇒ delegate.newHostConnectionPool[T](to.host, to.port, settings, log)(materializer)
|
||||
case https: HttpsConnectionContext ⇒ delegate.newHostConnectionPoolHttps[T](to.host, to.port, https.asScala, settings.asScala, log)(materializer)
|
||||
case _ ⇒ delegate.newHostConnectionPool[T](to.host, to.port, settings.asScala, log)(materializer)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -442,7 +444,7 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
def cachedHostConnectionPool[T](to: ConnectHttp,
|
||||
settings: ConnectionPoolSettings,
|
||||
log: LoggingAdapter, materializer: Materializer): Flow[Pair[HttpRequest, T], Pair[Try[HttpResponse], T], HostConnectionPool] =
|
||||
adaptTupleFlow(delegate.cachedHostConnectionPoolHttps[T](to.host, to.port, to.effectiveConnectionContext(defaultClientHttpsContext).asScala, settings, log)(materializer))
|
||||
adaptTupleFlow(delegate.cachedHostConnectionPoolHttps[T](to.host, to.port, to.effectiveConnectionContext(defaultClientHttpsContext).asScala, settings.asScala, log)(materializer))
|
||||
|
||||
/**
|
||||
* Creates a new "super connection pool flow", which routes incoming requests to a (cached) host connection pool
|
||||
|
|
@ -477,7 +479,7 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
def superPool[T](settings: ConnectionPoolSettings,
|
||||
connectionContext: HttpsConnectionContext,
|
||||
log: LoggingAdapter, materializer: Materializer): Flow[Pair[HttpRequest, T], Pair[Try[HttpResponse], T], NotUsed] =
|
||||
adaptTupleFlow(delegate.superPool[T](connectionContext.asScala, settings, log)(materializer))
|
||||
adaptTupleFlow(delegate.superPool[T](connectionContext.asScala, settings.asScala, log)(materializer))
|
||||
|
||||
/**
|
||||
* Creates a new "super connection pool flow", which routes incoming requests to a (cached) host connection pool
|
||||
|
|
@ -496,7 +498,7 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
*/
|
||||
def superPool[T](settings: ConnectionPoolSettings,
|
||||
log: LoggingAdapter, materializer: Materializer): Flow[Pair[HttpRequest, T], Pair[Try[HttpResponse], T], NotUsed] =
|
||||
adaptTupleFlow(delegate.superPool[T](defaultClientHttpsContext.asScala, settings, log)(materializer))
|
||||
adaptTupleFlow(delegate.superPool[T](defaultClientHttpsContext.asScala, settings.asScala, log)(materializer))
|
||||
|
||||
/**
|
||||
* Fires a single [[HttpRequest]] across the (cached) host connection pool for the request's
|
||||
|
|
@ -535,7 +537,7 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
connectionContext: HttpsConnectionContext,
|
||||
settings: ConnectionPoolSettings,
|
||||
log: LoggingAdapter, materializer: Materializer): CompletionStage[HttpResponse] =
|
||||
delegate.singleRequest(request.asScala, connectionContext.asScala, settings, log)(materializer).toJava
|
||||
delegate.singleRequest(request.asScala, connectionContext.asScala, settings.asScala, log)(materializer).toJava
|
||||
|
||||
/**
|
||||
* Constructs a WebSocket [[BidiFlow]].
|
||||
|
|
@ -553,7 +555,7 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
*/
|
||||
def webSocketClientLayer(request: WebSocketRequest,
|
||||
settings: ClientConnectionSettings): BidiFlow[Message, SslTlsOutbound, SslTlsInbound, Message, CompletionStage[WebSocketUpgradeResponse]] =
|
||||
adaptWsBidiFlow(delegate.webSocketClientLayer(request.asScala, settings))
|
||||
adaptWsBidiFlow(delegate.webSocketClientLayer(request.asScala, settings.asScala))
|
||||
|
||||
/**
|
||||
* Constructs a WebSocket [[BidiFlow]] using the configured default [[ClientConnectionSettings]],
|
||||
|
|
@ -564,7 +566,7 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
def webSocketClientLayer(request: WebSocketRequest,
|
||||
settings: ClientConnectionSettings,
|
||||
log: LoggingAdapter): BidiFlow[Message, SslTlsOutbound, SslTlsInbound, Message, CompletionStage[WebSocketUpgradeResponse]] =
|
||||
adaptWsBidiFlow(delegate.webSocketClientLayer(request.asScala, settings, log))
|
||||
adaptWsBidiFlow(delegate.webSocketClientLayer(request.asScala, settings.asScala, log))
|
||||
|
||||
/**
|
||||
* Constructs a flow that once materialized establishes a WebSocket connection to the given Uri.
|
||||
|
|
@ -587,7 +589,7 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
settings: ClientConnectionSettings,
|
||||
log: LoggingAdapter): Flow[Message, Message, CompletionStage[WebSocketUpgradeResponse]] =
|
||||
adaptWsFlow {
|
||||
delegate.webSocketClientFlow(request.asScala, connectionContext.asScala, localAddress.asScala, settings, log)
|
||||
delegate.webSocketClientFlow(request.asScala, connectionContext.asScala, localAddress.asScala, settings.asScala, log)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -639,7 +641,7 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
adaptWsFlow[T](clientFlow),
|
||||
connectionContext.asScala,
|
||||
localAddress.asScala,
|
||||
settings,
|
||||
settings.asScala,
|
||||
log)(materializer)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* Copyright (C) 2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package akka.http.javadsl.settings
|
||||
|
||||
import java.util.{ Optional, Random }
|
||||
|
||||
import akka.http.impl.settings.ClientConnectionSettingsImpl
|
||||
import akka.http.javadsl.model.headers.UserAgent
|
||||
import akka.io.Inet.SocketOption
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import akka.http.impl.util.JavaMapping.Implicits._
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.compat.java8.OptionConverters._
|
||||
import scala.concurrent.duration.{ Duration, FiniteDuration }
|
||||
|
||||
abstract class ClientConnectionSettings {
|
||||
def getUserAgentHeader: Optional[UserAgent]
|
||||
def getConnectingTimeout: FiniteDuration
|
||||
def getIdleTimeout: Duration
|
||||
def getRequestHeaderSizeHint: Int
|
||||
def getWebsocketRandomFactory: java.util.function.Supplier[Random]
|
||||
def getSocketOptions: java.lang.Iterable[SocketOption]
|
||||
def getParserSettings: ParserSettings
|
||||
|
||||
// ---
|
||||
|
||||
def withUserAgentHeader(newValue: Optional[UserAgent]): ClientConnectionSettings = self.copy(userAgentHeader = newValue.asScala.map(_.asScala))
|
||||
def withConnectingTimeout(newValue: FiniteDuration): ClientConnectionSettings = self.copy(connectingTimeout = newValue)
|
||||
def withIdleTimeout(newValue: Duration): ClientConnectionSettings = self.copy(idleTimeout = newValue)
|
||||
def withRequestHeaderSizeHint(newValue: Int): ClientConnectionSettings = self.copy(requestHeaderSizeHint = newValue)
|
||||
def withWebsocketRandomFactory(newValue: java.util.function.Supplier[Random]): ClientConnectionSettings = self.copy(websocketRandomFactory = () ⇒ newValue.get())
|
||||
def withSocketOptions(newValue: java.lang.Iterable[SocketOption]): ClientConnectionSettings = self.copy(socketOptions = newValue.asScala.toList)
|
||||
def withParserSettings(newValue: ParserSettings): ClientConnectionSettings = self.copy(parserSettings = newValue.asScala)
|
||||
|
||||
/** INTERNAL API: safe by construction */
|
||||
protected val self = this.asInstanceOf[ClientConnectionSettingsImpl]
|
||||
}
|
||||
|
||||
object ClientConnectionSettings extends SettingsCompanion[ClientConnectionSettings] {
|
||||
def create(config: Config): ClientConnectionSettings = ClientConnectionSettingsImpl(config)
|
||||
def create(configOverrides: String): ClientConnectionSettings = ClientConnectionSettingsImpl(configOverrides)
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* Copyright (C) 2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package akka.http.javadsl.settings
|
||||
|
||||
import akka.http.impl.settings.ConnectionPoolSettingsImpl
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
import akka.http.impl.util.JavaMapping.Implicits._
|
||||
|
||||
abstract class ConnectionPoolSettings {
|
||||
def getMaxConnections: Int
|
||||
def getMaxRetries: Int
|
||||
def getMaxOpenRequests: Int
|
||||
def getPipeliningLimit: Int
|
||||
def getIdleTimeout: Duration
|
||||
def getConnectionSettings: ClientConnectionSettings
|
||||
|
||||
// ---
|
||||
|
||||
def withMaxConnections(n: Int): ConnectionPoolSettings = self.copy(maxConnections = n)
|
||||
def withMaxRetries(n: Int): ConnectionPoolSettings = self.copy(maxRetries = n)
|
||||
def withMaxOpenRequests(newValue: Int): ConnectionPoolSettings = self.copy(maxOpenRequests = newValue)
|
||||
def withPipeliningLimit(newValue: Int): ConnectionPoolSettings = self.copy(pipeliningLimit = newValue)
|
||||
def withIdleTimeout(newValue: Duration): ConnectionPoolSettings = self.copy(idleTimeout = newValue)
|
||||
def withConnectionSettings(newValue: ClientConnectionSettings): ConnectionPoolSettings = self.copy(connectionSettings = newValue.asScala)
|
||||
|
||||
/** INTERNAL API */
|
||||
protected def self = this.asInstanceOf[ConnectionPoolSettingsImpl]
|
||||
}
|
||||
|
||||
object ConnectionPoolSettings extends SettingsCompanion[ConnectionPoolSettings] {
|
||||
override def create(config: Config): ConnectionPoolSettings = ConnectionPoolSettingsImpl(config)
|
||||
override def create(configOverrides: String): ConnectionPoolSettings = ConnectionPoolSettingsImpl(configOverrides)
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* Copyright (C) 2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package akka.http.javadsl.settings
|
||||
|
||||
import java.util.Optional
|
||||
|
||||
import akka.http.impl.engine.parsing.BodyPartParser
|
||||
import akka.http.impl.settings.ParserSettingsImpl
|
||||
import java.{ util ⇒ ju }
|
||||
import akka.http.impl.util.JavaMapping.Implicits._
|
||||
import scala.annotation.varargs
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.compat.java8.OptionConverters
|
||||
|
||||
import akka.http.javadsl.model.{ HttpMethod, StatusCode, Uri }
|
||||
import com.typesafe.config.Config
|
||||
|
||||
abstract class ParserSettings extends BodyPartParser.Settings {
|
||||
def getMaxUriLength: Int
|
||||
def getMaxMethodLength: Int
|
||||
def getMaxResponseReasonLength: Int
|
||||
def getMaxHeaderNameLength: Int
|
||||
def getMaxHeaderValueLength: Int
|
||||
def getMaxHeaderCount: Int
|
||||
def getMaxContentLength: Long
|
||||
def getMaxChunkExtLength: Int
|
||||
def getMaxChunkSize: Int
|
||||
def getUriParsingMode: Uri.ParsingMode
|
||||
def getCookieParsingMode: ParserSettings.CookieParsingMode
|
||||
def getIllegalHeaderWarnings: Boolean
|
||||
def getErrorLoggingVerbosity: ParserSettings.ErrorLoggingVerbosity
|
||||
def getHeaderValueCacheLimits: ju.Map[String, Int]
|
||||
def getIncludeTlsSessionInfoHeader: Boolean
|
||||
def headerValueCacheLimits: Map[String, Int]
|
||||
def getCustomMethods: java.util.function.Function[String, Optional[HttpMethod]]
|
||||
def getCustomStatusCodes: java.util.function.Function[Int, Optional[StatusCode]]
|
||||
|
||||
// ---
|
||||
|
||||
def withMaxUriLength(newValue: Int): ParserSettings = self.copy(maxUriLength = newValue)
|
||||
def withMaxMethodLength(newValue: Int): ParserSettings = self.copy(maxMethodLength = newValue)
|
||||
def withMaxResponseReasonLength(newValue: Int): ParserSettings = self.copy(maxResponseReasonLength = newValue)
|
||||
def withMaxHeaderNameLength(newValue: Int): ParserSettings = self.copy(maxHeaderNameLength = newValue)
|
||||
def withMaxHeaderValueLength(newValue: Int): ParserSettings = self.copy(maxHeaderValueLength = newValue)
|
||||
def withMaxHeaderCount(newValue: Int): ParserSettings = self.copy(maxHeaderCount = newValue)
|
||||
def withMaxContentLength(newValue: Long): ParserSettings = self.copy(maxContentLength = newValue)
|
||||
def withMaxChunkExtLength(newValue: Int): ParserSettings = self.copy(maxChunkExtLength = newValue)
|
||||
def withMaxChunkSize(newValue: Int): ParserSettings = self.copy(maxChunkSize = newValue)
|
||||
def withUriParsingMode(newValue: Uri.ParsingMode): ParserSettings = self.copy(uriParsingMode = newValue.asScala)
|
||||
def withCookieParsingMode(newValue: ParserSettings.CookieParsingMode): ParserSettings = self.copy(cookieParsingMode = newValue.asScala)
|
||||
def withIllegalHeaderWarnings(newValue: Boolean): ParserSettings = self.copy(illegalHeaderWarnings = newValue)
|
||||
def withErrorLoggingVerbosity(newValue: ParserSettings.ErrorLoggingVerbosity): ParserSettings = self.copy(errorLoggingVerbosity = newValue.asScala)
|
||||
def withHeaderValueCacheLimits(newValue: ju.Map[String, Int]): ParserSettings = self.copy(headerValueCacheLimits = newValue.asScala.toMap)
|
||||
def withIncludeTlsSessionInfoHeader(newValue: Boolean): ParserSettings = self.copy(includeTlsSessionInfoHeader = newValue)
|
||||
|
||||
// special ---
|
||||
|
||||
def withCustomMethods(methods: HttpMethod*): ParserSettings = {
|
||||
val map = methods.map(m ⇒ m.name -> m.asScala).toMap
|
||||
self.copy(customMethods = map.get)
|
||||
}
|
||||
def withCustomStatusCodes(codes: StatusCode*): ParserSettings = {
|
||||
val map = codes.map(c ⇒ c.intValue -> c.asScala).toMap
|
||||
self.copy(customStatusCodes = map.get)
|
||||
}
|
||||
|
||||
/** INTERNAL API */
|
||||
protected def self = this.asInstanceOf[ParserSettingsImpl]
|
||||
}
|
||||
|
||||
object ParserSettings extends SettingsCompanion[ParserSettings] {
|
||||
trait CookieParsingMode
|
||||
trait ErrorLoggingVerbosity
|
||||
|
||||
override def create(config: Config): ParserSettings = ParserSettingsImpl(config)
|
||||
override def create(configOverrides: String): ParserSettings = ParserSettingsImpl(configOverrides)
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* Copyright (C) 2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package akka.http.javadsl.settings
|
||||
|
||||
import java.util.{ Optional, Random }
|
||||
|
||||
import akka.http.impl.settings.ServerSettingsImpl
|
||||
import akka.http.javadsl.model.headers.Host
|
||||
import akka.http.javadsl.model.headers.Server
|
||||
import akka.io.Inet.SocketOption
|
||||
import akka.http.impl.util.JavaMapping.Implicits._
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.compat.java8.OptionConverters._
|
||||
|
||||
import scala.concurrent.duration.{ Duration, FiniteDuration }
|
||||
|
||||
abstract class ServerSettings {
|
||||
def getServerHeader: Optional[Server]
|
||||
def getTimeouts: ServerSettings.Timeouts
|
||||
def getMaxConnections: Int
|
||||
def getPipeliningLimit: Int
|
||||
def getRemoteAddressHeader: Boolean
|
||||
def getRawRequestUriHeader: Boolean
|
||||
def getTransparentHeadRequests: Boolean
|
||||
def getVerboseErrorMessages: Boolean
|
||||
def getResponseHeaderSizeHint: Int
|
||||
def getBacklog: Int
|
||||
def getSocketOptions: java.lang.Iterable[SocketOption]
|
||||
def getDefaultHostHeader: Host
|
||||
def getWebsocketRandomFactory: java.util.function.Supplier[Random]
|
||||
def getParserSettings: ParserSettings
|
||||
|
||||
// ---
|
||||
|
||||
def withServerHeader(newValue: Optional[Server]): ServerSettings = self.copy(serverHeader = newValue.asScala.map(_.asScala))
|
||||
def withTimeouts(newValue: ServerSettings.Timeouts): ServerSettings = self.copy(timeouts = newValue.asScala)
|
||||
def withMaxConnections(newValue: Int): ServerSettings = self.copy(maxConnections = newValue)
|
||||
def withPipeliningLimit(newValue: Int): ServerSettings = self.copy(pipeliningLimit = newValue)
|
||||
def withRemoteAddressHeader(newValue: Boolean): ServerSettings = self.copy(remoteAddressHeader = newValue)
|
||||
def withRawRequestUriHeader(newValue: Boolean): ServerSettings = self.copy(rawRequestUriHeader = newValue)
|
||||
def withTransparentHeadRequests(newValue: Boolean): ServerSettings = self.copy(transparentHeadRequests = newValue)
|
||||
def withVerboseErrorMessages(newValue: Boolean): ServerSettings = self.copy(verboseErrorMessages = newValue)
|
||||
def withResponseHeaderSizeHint(newValue: Int): ServerSettings = self.copy(responseHeaderSizeHint = newValue)
|
||||
def withBacklog(newValue: Int): ServerSettings = self.copy(backlog = newValue)
|
||||
def withSocketOptions(newValue: java.lang.Iterable[SocketOption]): ServerSettings = self.copy(socketOptions = newValue.asScala.toList)
|
||||
def withDefaultHostHeader(newValue: Host): ServerSettings = self.copy(defaultHostHeader = newValue.asScala)
|
||||
def withParserSettings(newValue: ParserSettings): ServerSettings = self.copy(parserSettings = newValue.asScala)
|
||||
def withWebsocketRandomFactory(newValue: java.util.function.Supplier[Random]): ServerSettings = self.copy(websocketRandomFactory = () ⇒ newValue.get())
|
||||
|
||||
/** INTERNAL API */
|
||||
protected def self = this.asInstanceOf[ServerSettingsImpl]
|
||||
}
|
||||
|
||||
object ServerSettings {
|
||||
trait Timeouts {
|
||||
def idleTimeout: Duration
|
||||
def requestTimeout: Duration
|
||||
def bindTimeout: FiniteDuration
|
||||
|
||||
// ---
|
||||
def withIdleTimeout(newValue: Duration): ServerSettings.Timeouts = self.copy(idleTimeout = newValue)
|
||||
def withRequestTimeout(newValue: Duration): ServerSettings.Timeouts = self.copy(requestTimeout = newValue)
|
||||
def withBindTimeout(newValue: FiniteDuration): ServerSettings.Timeouts = self.copy(bindTimeout = newValue)
|
||||
|
||||
/** INTERNAL API */
|
||||
protected def self = this.asInstanceOf[ServerSettingsImpl.Timeouts]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package akka.http.javadsl.settings
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import com.typesafe.config.Config
|
||||
|
||||
trait SettingsCompanion[T] {
|
||||
|
||||
/**
|
||||
* Creates an instance of settings using the configuration provided by the given ActorSystem.
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
final def create(system: ActorSystem): T = create(system.settings.config)
|
||||
|
||||
/**
|
||||
* Creates an instance of settings using the given Config.
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
def create(config: Config): T
|
||||
|
||||
/**
|
||||
* Create an instance of settings using the given String of config overrides to override
|
||||
* settings set in the class loader of this class (i.e. by application.conf or reference.conf files in
|
||||
* the class loader of this class).
|
||||
*
|
||||
* Java API
|
||||
*/
|
||||
def create(configOverrides: String): T
|
||||
}
|
||||
|
|
@ -15,10 +15,12 @@ import akka.http.impl.engine.HttpConnectionTimeoutException
|
|||
import akka.http.impl.engine.client._
|
||||
import akka.http.impl.engine.server._
|
||||
import akka.http.impl.engine.ws.WebSocketClientBlueprint
|
||||
import akka.http.impl.settings.{ ConnectionPoolSetup, HostConnectionPoolSetup }
|
||||
import akka.http.impl.util.StreamUtils
|
||||
import akka.http.scaladsl.model._
|
||||
import akka.http.scaladsl.model.headers.Host
|
||||
import akka.http.scaladsl.model.ws.{ Message, WebSocketRequest, WebSocketUpgradeResponse }
|
||||
import akka.http.scaladsl.settings.{ ServerSettings, ClientConnectionSettings, ConnectionPoolSettings }
|
||||
import akka.http.scaladsl.util.FastFuture
|
||||
import akka.NotUsed
|
||||
import akka.stream.Materializer
|
||||
|
|
@ -68,7 +70,7 @@ class HttpExt(private val config: Config)(implicit val system: ActorSystem) exte
|
|||
* which is 80 for HTTP and 443 for HTTPS.
|
||||
*
|
||||
* To configure additional settings for a server started using this method,
|
||||
* use the `akka.http.server` config section or pass in a [[ServerSettings]] explicitly.
|
||||
* use the `akka.http.server` config section or pass in a [[akka.http.scaladsl.settings.ServerSettings]] explicitly.
|
||||
*/
|
||||
def bind(interface: String, port: Int = DefaultPortForProtocol,
|
||||
connectionContext: ConnectionContext = defaultServerHttpContext,
|
||||
|
|
@ -297,6 +299,8 @@ class HttpExt(private val config: Config)(implicit val system: ActorSystem) exte
|
|||
}
|
||||
|
||||
/**
|
||||
* INTERNAL API
|
||||
*
|
||||
* Starts a new connection pool to the given host and configuration and returns a [[Flow]] which dispatches
|
||||
* the requests from all its materializations across this pool.
|
||||
* While the started host connection pool internally shuts itself down automatically after the configured idle
|
||||
|
|
@ -310,7 +314,7 @@ class HttpExt(private val config: Config)(implicit val system: ActorSystem) exte
|
|||
* In order to allow for easy response-to-request association the flow takes in a custom, opaque context
|
||||
* object of type `T` from the application which is emitted together with the corresponding response.
|
||||
*/
|
||||
private def newHostConnectionPool[T](setup: HostConnectionPoolSetup)(
|
||||
private[akka] def newHostConnectionPool[T](setup: HostConnectionPoolSetup)(
|
||||
implicit fm: Materializer): Flow[(HttpRequest, T), (Try[HttpResponse], T), HostConnectionPool] = {
|
||||
val gatewayFuture = FastFuture.successful(new PoolGateway(setup, Promise()))
|
||||
gatewayClientFlow(setup, gatewayFuture)
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@ final case class HttpMethod private[http] (override val value: String,
|
|||
isSafe: Boolean,
|
||||
isIdempotent: Boolean,
|
||||
requestEntityAcceptance: RequestEntityAcceptance) extends jm.HttpMethod with SingletonValueRenderable {
|
||||
def name = value
|
||||
|
||||
override def isEntityAccepted: Boolean = requestEntityAcceptance.isEntityAccepted
|
||||
override def toString: String = s"HttpMethod($value)"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -599,8 +599,7 @@ object Uri {
|
|||
"pop3" -> 110, "nntp" -> 119, "imap" -> 143, "snmp" -> 161, "ldap" -> 389, "https" -> 443, "wss" -> 443, "imaps" -> 993,
|
||||
"nfs" -> 2049).withDefaultValue(-1)
|
||||
|
||||
sealed trait ParsingMode
|
||||
|
||||
sealed trait ParsingMode extends akka.http.javadsl.model.Uri.ParsingMode
|
||||
object ParsingMode {
|
||||
case object Strict extends ParsingMode
|
||||
case object Relaxed extends ParsingMode
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* Copyright (C) 2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package akka.http.scaladsl.settings
|
||||
|
||||
import java.lang.Iterable
|
||||
import java.util.{ Optional, Random }
|
||||
import java.util.function.Supplier
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.http.impl.settings.ClientConnectionSettingsImpl
|
||||
import akka.http.javadsl.model.headers.UserAgent
|
||||
import akka.http.javadsl.{ settings ⇒ js }
|
||||
import akka.http.scaladsl.model.headers.`User-Agent`
|
||||
import akka.io.Inet.SocketOption
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import scala.collection.immutable
|
||||
import scala.compat.java8.OptionConverters
|
||||
import scala.concurrent.duration.{ FiniteDuration, Duration }
|
||||
import scala.collection.JavaConverters._
|
||||
|
||||
abstract class ClientConnectionSettings extends akka.http.javadsl.settings.ClientConnectionSettings {
|
||||
def userAgentHeader: Option[`User-Agent`]
|
||||
def connectingTimeout: FiniteDuration
|
||||
def idleTimeout: Duration
|
||||
def requestHeaderSizeHint: Int
|
||||
def websocketRandomFactory: () ⇒ Random
|
||||
def socketOptions: immutable.Seq[SocketOption]
|
||||
def parserSettings: ParserSettings
|
||||
|
||||
/* JAVA APIs */
|
||||
|
||||
final override def getConnectingTimeout: FiniteDuration = connectingTimeout
|
||||
final override def getParserSettings: js.ParserSettings = parserSettings
|
||||
final override def getIdleTimeout: Duration = idleTimeout
|
||||
final override def getSocketOptions: Iterable[SocketOption] = socketOptions.asJava
|
||||
final override def getUserAgentHeader: Optional[UserAgent] = OptionConverters.toJava(userAgentHeader)
|
||||
final override def getRequestHeaderSizeHint: Int = requestHeaderSizeHint
|
||||
final override def getWebsocketRandomFactory: Supplier[Random] = new Supplier[Random] {
|
||||
override def get(): Random = websocketRandomFactory()
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
// overrides for more specific return type
|
||||
override def withConnectingTimeout(newValue: FiniteDuration): ClientConnectionSettings = self.copy(connectingTimeout = newValue)
|
||||
override def withIdleTimeout(newValue: Duration): ClientConnectionSettings = self.copy(idleTimeout = newValue)
|
||||
override def withRequestHeaderSizeHint(newValue: Int): ClientConnectionSettings = self.copy(requestHeaderSizeHint = newValue)
|
||||
|
||||
// overloads for idiomatic Scala use
|
||||
def withWebsocketRandomFactory(newValue: () ⇒ Random): ClientConnectionSettings = self.copy(websocketRandomFactory = newValue)
|
||||
def withUserAgentHeader(newValue: Option[`User-Agent`]): ClientConnectionSettings = self.copy(userAgentHeader = newValue)
|
||||
def withSocketOptions(newValue: immutable.Seq[SocketOption]): ClientConnectionSettings = self.copy(socketOptions = newValue)
|
||||
def withParserSettings(newValue: ParserSettings): ClientConnectionSettings = self.copy(parserSettings = newValue)
|
||||
}
|
||||
|
||||
object ClientConnectionSettings extends SettingsCompanion[ClientConnectionSettings] {
|
||||
override def apply(config: Config): ClientConnectionSettings = ClientConnectionSettingsImpl(config)
|
||||
override def apply(configOverrides: String): ClientConnectionSettings = ClientConnectionSettingsImpl(configOverrides)
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* Copyright (C) 2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package akka.http.scaladsl.settings
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.http.impl.settings.ConnectionPoolSettingsImpl
|
||||
import akka.http.javadsl.{ settings ⇒ js }
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
|
||||
abstract class ConnectionPoolSettings extends js.ConnectionPoolSettings {
|
||||
def maxConnections: Int
|
||||
def maxRetries: Int
|
||||
def maxOpenRequests: Int
|
||||
def pipeliningLimit: Int
|
||||
def idleTimeout: Duration
|
||||
def connectionSettings: ClientConnectionSettings
|
||||
|
||||
/* JAVA APIs */
|
||||
|
||||
final override def getConnectionSettings: js.ClientConnectionSettings = connectionSettings
|
||||
final override def getPipeliningLimit: Int = pipeliningLimit
|
||||
final override def getIdleTimeout: Duration = idleTimeout
|
||||
final override def getMaxConnections: Int = maxConnections
|
||||
final override def getMaxOpenRequests: Int = maxOpenRequests
|
||||
final override def getMaxRetries: Int = maxRetries
|
||||
|
||||
// ---
|
||||
|
||||
// overrides for more precise return type
|
||||
override def withMaxConnections(n: Int): ConnectionPoolSettings = self.copy(maxConnections = n)
|
||||
override def withMaxRetries(n: Int): ConnectionPoolSettings = self.copy(maxRetries = n)
|
||||
override def withMaxOpenRequests(newValue: Int): ConnectionPoolSettings = self.copy(maxOpenRequests = newValue)
|
||||
override def withPipeliningLimit(newValue: Int): ConnectionPoolSettings = self.copy(pipeliningLimit = newValue)
|
||||
override def withIdleTimeout(newValue: Duration): ConnectionPoolSettings = self.copy(idleTimeout = newValue)
|
||||
|
||||
// overloads for idiomatic Scala use
|
||||
def withConnectionSettings(newValue: ClientConnectionSettings): ConnectionPoolSettings = self.copy(connectionSettings = newValue)
|
||||
}
|
||||
|
||||
object ConnectionPoolSettings extends SettingsCompanion[ConnectionPoolSettings] {
|
||||
override def apply(config: Config) = ConnectionPoolSettingsImpl(config)
|
||||
override def apply(configOverrides: String) = ConnectionPoolSettingsImpl(configOverrides)
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/**
|
||||
* Copyright (C) 2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package akka.http.scaladsl.settings
|
||||
|
||||
import java.util
|
||||
import java.util.Optional
|
||||
import java.util.function.Function
|
||||
|
||||
import akka.http.impl.settings.ParserSettingsImpl
|
||||
import akka.http.impl.util._
|
||||
import akka.http.scaladsl.model.HttpMethod
|
||||
import akka.http.scaladsl.model.StatusCode
|
||||
import akka.http.scaladsl.model.{ HttpMethod, StatusCode, Uri }
|
||||
import akka.http.scaladsl.{ settings ⇒ js }
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import scala.annotation.varargs
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.compat.java8.OptionConverters
|
||||
|
||||
abstract class ParserSettings extends akka.http.javadsl.settings.ParserSettings {
|
||||
def maxUriLength: Int
|
||||
def maxMethodLength: Int
|
||||
def maxResponseReasonLength: Int
|
||||
def maxHeaderNameLength: Int
|
||||
def maxHeaderValueLength: Int
|
||||
def maxHeaderCount: Int
|
||||
def maxContentLength: Long
|
||||
def maxChunkExtLength: Int
|
||||
def maxChunkSize: Int
|
||||
def uriParsingMode: Uri.ParsingMode
|
||||
def cookieParsingMode: ParserSettings.CookieParsingMode
|
||||
def illegalHeaderWarnings: Boolean
|
||||
def errorLoggingVerbosity: ParserSettings.ErrorLoggingVerbosity
|
||||
def headerValueCacheLimits: Map[String, Int]
|
||||
def includeTlsSessionInfoHeader: Boolean
|
||||
def customMethods: String ⇒ Option[HttpMethod]
|
||||
def customStatusCodes: Int ⇒ Option[StatusCode]
|
||||
|
||||
/* Java APIs */
|
||||
override def getCookieParsingMode: js.ParserSettings.CookieParsingMode = cookieParsingMode
|
||||
override def getHeaderValueCacheLimits: util.Map[String, Int] = headerValueCacheLimits.asJava
|
||||
override def getMaxChunkExtLength = maxChunkExtLength
|
||||
override def getUriParsingMode: akka.http.javadsl.model.Uri.ParsingMode = uriParsingMode
|
||||
override def getMaxHeaderCount = maxHeaderCount
|
||||
override def getMaxContentLength = maxContentLength
|
||||
override def getMaxHeaderValueLength = maxHeaderValueLength
|
||||
override def getIncludeTlsSessionInfoHeader = includeTlsSessionInfoHeader
|
||||
override def getIllegalHeaderWarnings = illegalHeaderWarnings
|
||||
override def getMaxHeaderNameLength = maxHeaderNameLength
|
||||
override def getMaxChunkSize = maxChunkSize
|
||||
override def getMaxResponseReasonLength = maxResponseReasonLength
|
||||
override def getMaxUriLength = maxUriLength
|
||||
override def getMaxMethodLength = maxMethodLength
|
||||
override def getErrorLoggingVerbosity: js.ParserSettings.ErrorLoggingVerbosity = errorLoggingVerbosity
|
||||
|
||||
override def getCustomMethods = new Function[String, Optional[akka.http.javadsl.model.HttpMethod]] {
|
||||
override def apply(t: String) = OptionConverters.toJava(customMethods(t))
|
||||
}
|
||||
override def getCustomStatusCodes = new Function[Int, Optional[akka.http.javadsl.model.StatusCode]] {
|
||||
override def apply(t: Int) = OptionConverters.toJava(customStatusCodes(t))
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
// override for more specific return type
|
||||
override def withMaxUriLength(newValue: Int): ParserSettings = self.copy(maxUriLength = newValue)
|
||||
override def withMaxMethodLength(newValue: Int): ParserSettings = self.copy(maxMethodLength = newValue)
|
||||
override def withMaxResponseReasonLength(newValue: Int): ParserSettings = self.copy(maxResponseReasonLength = newValue)
|
||||
override def withMaxHeaderNameLength(newValue: Int): ParserSettings = self.copy(maxHeaderNameLength = newValue)
|
||||
override def withMaxHeaderValueLength(newValue: Int): ParserSettings = self.copy(maxHeaderValueLength = newValue)
|
||||
override def withMaxHeaderCount(newValue: Int): ParserSettings = self.copy(maxHeaderCount = newValue)
|
||||
override def withMaxContentLength(newValue: Long): ParserSettings = self.copy(maxContentLength = newValue)
|
||||
override def withMaxChunkExtLength(newValue: Int): ParserSettings = self.copy(maxChunkExtLength = newValue)
|
||||
override def withMaxChunkSize(newValue: Int): ParserSettings = self.copy(maxChunkSize = newValue)
|
||||
override def withIllegalHeaderWarnings(newValue: Boolean): ParserSettings = self.copy(illegalHeaderWarnings = newValue)
|
||||
override def withIncludeTlsSessionInfoHeader(newValue: Boolean): ParserSettings = self.copy(includeTlsSessionInfoHeader = newValue)
|
||||
|
||||
// overloads for idiomatic Scala use
|
||||
def withUriParsingMode(newValue: Uri.ParsingMode): ParserSettings = self.copy(uriParsingMode = newValue)
|
||||
def withCookieParsingMode(newValue: ParserSettings.CookieParsingMode): ParserSettings = self.copy(cookieParsingMode = newValue)
|
||||
def withErrorLoggingVerbosity(newValue: ParserSettings.ErrorLoggingVerbosity): ParserSettings = self.copy(errorLoggingVerbosity = newValue)
|
||||
def withHeaderValueCacheLimits(newValue: Map[String, Int]): ParserSettings = self.copy(headerValueCacheLimits = newValue)
|
||||
def withCustomMethods(methods: HttpMethod*): ParserSettings = {
|
||||
val map = methods.map(m ⇒ m.name -> m).toMap
|
||||
self.copy(customMethods = map.get)
|
||||
}
|
||||
def withCustomStatusCodes(codes: StatusCode*): ParserSettings = {
|
||||
val map = codes.map(c ⇒ c.intValue -> c).toMap
|
||||
self.copy(customStatusCodes = map.get)
|
||||
}
|
||||
}
|
||||
|
||||
object ParserSettings extends SettingsCompanion[ParserSettings] {
|
||||
trait CookieParsingMode extends akka.http.javadsl.settings.ParserSettings.CookieParsingMode
|
||||
object CookieParsingMode {
|
||||
case object RFC6265 extends CookieParsingMode
|
||||
case object Raw extends CookieParsingMode
|
||||
|
||||
def apply(mode: String): CookieParsingMode = mode.toRootLowerCase match {
|
||||
case "rfc6265" ⇒ RFC6265
|
||||
case "raw" ⇒ Raw
|
||||
}
|
||||
}
|
||||
|
||||
trait ErrorLoggingVerbosity extends akka.http.javadsl.settings.ParserSettings.ErrorLoggingVerbosity
|
||||
object ErrorLoggingVerbosity {
|
||||
case object Off extends ErrorLoggingVerbosity
|
||||
case object Simple extends ErrorLoggingVerbosity
|
||||
case object Full extends ErrorLoggingVerbosity
|
||||
|
||||
def apply(string: String): ErrorLoggingVerbosity =
|
||||
string.toRootLowerCase match {
|
||||
case "off" ⇒ Off
|
||||
case "simple" ⇒ Simple
|
||||
case "full" ⇒ Full
|
||||
case x ⇒ throw new IllegalArgumentException(s"[$x] is not a legal `error-logging-verbosity` setting")
|
||||
}
|
||||
}
|
||||
|
||||
override def apply(config: Config): ParserSettings = ParserSettingsImpl(config)
|
||||
override def apply(configOverrides: String): ParserSettings = ParserSettingsImpl(configOverrides)
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/**
|
||||
* Copyright (C) 2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package akka.http.scaladsl.settings
|
||||
|
||||
import java.util.Random
|
||||
import java.util.function.Supplier
|
||||
|
||||
import akka.http.impl.settings.ServerSettingsImpl
|
||||
import akka.http.impl.util.JavaMapping.Implicits._
|
||||
import akka.http.javadsl.{ model ⇒ jm, settings ⇒ js }
|
||||
import akka.http.scaladsl.model.headers.Host
|
||||
import akka.http.scaladsl.model.headers.Server
|
||||
import akka.io.Inet.SocketOption
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.collection.immutable
|
||||
import scala.compat.java8.OptionConverters
|
||||
import scala.concurrent.duration.{ FiniteDuration, Duration }
|
||||
import scala.language.implicitConversions
|
||||
|
||||
abstract class ServerSettings extends akka.http.javadsl.settings.ServerSettings {
|
||||
def serverHeader: Option[Server]
|
||||
def timeouts: ServerSettings.Timeouts
|
||||
def maxConnections: Int
|
||||
def pipeliningLimit: Int
|
||||
def remoteAddressHeader: Boolean
|
||||
def rawRequestUriHeader: Boolean
|
||||
def transparentHeadRequests: Boolean
|
||||
def verboseErrorMessages: Boolean
|
||||
def responseHeaderSizeHint: Int
|
||||
def backlog: Int
|
||||
def socketOptions: immutable.Seq[SocketOption]
|
||||
def defaultHostHeader: Host
|
||||
def websocketRandomFactory: () ⇒ Random
|
||||
def parserSettings: ParserSettings
|
||||
|
||||
/* Java APIs */
|
||||
|
||||
override def getBacklog = backlog
|
||||
override def getDefaultHostHeader = defaultHostHeader.asJava
|
||||
override def getPipeliningLimit = pipeliningLimit
|
||||
override def getParserSettings: js.ParserSettings = parserSettings
|
||||
override def getMaxConnections = maxConnections
|
||||
override def getTransparentHeadRequests = transparentHeadRequests
|
||||
override def getResponseHeaderSizeHint = responseHeaderSizeHint
|
||||
override def getVerboseErrorMessages = verboseErrorMessages
|
||||
override def getSocketOptions = socketOptions.asJava
|
||||
override def getServerHeader = OptionConverters.toJava(serverHeader.map(_.asJava))
|
||||
override def getTimeouts = timeouts
|
||||
override def getRawRequestUriHeader = rawRequestUriHeader
|
||||
override def getRemoteAddressHeader = remoteAddressHeader
|
||||
override def getWebsocketRandomFactory = new Supplier[Random] {
|
||||
override def get(): Random = websocketRandomFactory()
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
// override for more specific return type
|
||||
override def withMaxConnections(newValue: Int): ServerSettings = self.copy(maxConnections = newValue)
|
||||
override def withPipeliningLimit(newValue: Int): ServerSettings = self.copy(pipeliningLimit = newValue)
|
||||
override def withRemoteAddressHeader(newValue: Boolean): ServerSettings = self.copy(remoteAddressHeader = newValue)
|
||||
override def withRawRequestUriHeader(newValue: Boolean): ServerSettings = self.copy(rawRequestUriHeader = newValue)
|
||||
override def withTransparentHeadRequests(newValue: Boolean): ServerSettings = self.copy(transparentHeadRequests = newValue)
|
||||
override def withVerboseErrorMessages(newValue: Boolean): ServerSettings = self.copy(verboseErrorMessages = newValue)
|
||||
override def withResponseHeaderSizeHint(newValue: Int): ServerSettings = self.copy(responseHeaderSizeHint = newValue)
|
||||
override def withBacklog(newValue: Int): ServerSettings = self.copy(backlog = newValue)
|
||||
override def withSocketOptions(newValue: java.lang.Iterable[SocketOption]): ServerSettings = self.copy(socketOptions = newValue.asScala.toList)
|
||||
override def withWebsocketRandomFactory(newValue: java.util.function.Supplier[Random]): ServerSettings = self.copy(websocketRandomFactory = () ⇒ newValue.get())
|
||||
|
||||
// overloads for Scala idiomatic use
|
||||
def withTimeouts(newValue: ServerSettings.Timeouts): ServerSettings = self.copy(timeouts = newValue)
|
||||
def withServerHeader(newValue: Option[Server]): ServerSettings = self.copy(serverHeader = newValue)
|
||||
def withDefaultHostHeader(newValue: Host): ServerSettings = self.copy(defaultHostHeader = newValue)
|
||||
def withParserSettings(newValue: ParserSettings): ServerSettings = self.copy(parserSettings = newValue)
|
||||
def withWebsocketRandomFactory(newValue: () ⇒ Random): ServerSettings = self.copy(websocketRandomFactory = newValue)
|
||||
def withSocketOptions(newValue: immutable.Seq[SocketOption]): ServerSettings = self.copy(socketOptions = newValue)
|
||||
|
||||
}
|
||||
|
||||
object ServerSettings extends SettingsCompanion[ServerSettings] {
|
||||
trait Timeouts extends akka.http.javadsl.settings.ServerSettings.Timeouts {
|
||||
// ---
|
||||
// override for more specific return types
|
||||
override def withIdleTimeout(newValue: Duration): ServerSettings.Timeouts = self.copy(idleTimeout = newValue)
|
||||
override def withRequestTimeout(newValue: Duration): ServerSettings.Timeouts = self.copy(requestTimeout = newValue)
|
||||
override def withBindTimeout(newValue: FiniteDuration): ServerSettings.Timeouts = self.copy(bindTimeout = newValue)
|
||||
}
|
||||
|
||||
implicit def timeoutsShortcut(s: ServerSettings): Timeouts = s.timeouts
|
||||
|
||||
override def apply(config: Config): ServerSettings = ServerSettingsImpl(config)
|
||||
override def apply(configOverrides: String): ServerSettings = ServerSettingsImpl(configOverrides)
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package akka.http.scaladsl.settings
|
||||
|
||||
import akka.actor.{ ActorRefFactory, ActorSystem }
|
||||
import com.typesafe.config.Config
|
||||
import akka.http.impl.util._
|
||||
|
||||
/** INTERNAL API */
|
||||
private[akka] trait SettingsCompanion[T] {
|
||||
|
||||
/**
|
||||
* Creates an instance of settings using the configuration provided by the given ActorSystem.
|
||||
*/
|
||||
final def apply(system: ActorSystem): T = apply(system.settings.config)
|
||||
implicit def default(implicit system: ActorRefFactory): T = apply(actorSystem)
|
||||
|
||||
/**
|
||||
* Creates an instance of settings using the given Config.
|
||||
*/
|
||||
def apply(config: Config): T
|
||||
|
||||
/**
|
||||
* Create an instance of settings using the given String of config overrides to override
|
||||
* settings set in the class loader of this class (i.e. by application.conf or reference.conf files in
|
||||
* the class loader of this class).
|
||||
*/
|
||||
def apply(configOverrides: String): T
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@ import java.net.InetSocketAddress
|
|||
import java.nio.ByteBuffer
|
||||
import java.nio.channels.{ SocketChannel, ServerSocketChannel }
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import akka.http.impl.settings.ConnectionPoolSettingsImpl
|
||||
|
||||
import scala.concurrent.Await
|
||||
import scala.concurrent.duration._
|
||||
import scala.util.control.NonFatal
|
||||
|
|
@ -15,7 +17,7 @@ import scala.util.{ Failure, Success, Try }
|
|||
import akka.util.ByteString
|
||||
import akka.http.scaladsl.{ TestUtils, Http }
|
||||
import akka.http.impl.util.{ SingletonException, StreamUtils }
|
||||
import akka.http.{ ClientConnectionSettings, ConnectionPoolSettings, ServerSettings }
|
||||
import akka.http.scaladsl.settings.{ ClientConnectionSettings, ConnectionPoolSettings, ServerSettings }
|
||||
import akka.stream.io.{ SessionBytes, SendBytes, SslTlsOutbound }
|
||||
import akka.stream.{ BidiShape, ActorMaterializer }
|
||||
import akka.stream.testkit.{ TestPublisher, TestSubscriber, AkkaSpec }
|
||||
|
|
@ -128,7 +130,7 @@ class ConnectionPoolSpec extends AkkaSpec("""
|
|||
}
|
||||
|
||||
"be able to handle 500 pipelined requests against the test server" in new TestSetup {
|
||||
val settings = ConnectionPoolSettings(system).copy(maxConnections = 4, pipeliningLimit = 2)
|
||||
val settings = ConnectionPoolSettings(system).withMaxConnections(4).withPipeliningLimit(2)
|
||||
val poolFlow = Http().cachedHostConnectionPool[Int](serverHostName, serverPort, settings = settings)
|
||||
|
||||
val N = 500
|
||||
|
|
@ -229,7 +231,7 @@ class ConnectionPoolSpec extends AkkaSpec("""
|
|||
}
|
||||
|
||||
"The single-request client infrastructure" should {
|
||||
class LocalTestSetup extends TestSetup(ServerSettings(system).copy(rawRequestUriHeader = true), autoAccept = true)
|
||||
class LocalTestSetup extends TestSetup(ServerSettings(system).withRawRequestUriHeader(true), autoAccept = true)
|
||||
|
||||
"transform absolute request URIs into relative URIs plus host header" in new LocalTestSetup {
|
||||
val request = HttpRequest(uri = s"http://$serverHostName:$serverPort/abc?query#fragment")
|
||||
|
|
@ -326,7 +328,7 @@ class ConnectionPoolSpec extends AkkaSpec("""
|
|||
pipeliningLimit: Int = 1,
|
||||
idleTimeout: Duration = 5.seconds,
|
||||
ccSettings: ClientConnectionSettings = ClientConnectionSettings(system)) = {
|
||||
val settings = new ConnectionPoolSettings(maxConnections, maxRetries, maxOpenRequests, pipeliningLimit,
|
||||
val settings = new ConnectionPoolSettingsImpl(maxConnections, maxRetries, maxOpenRequests, pipeliningLimit,
|
||||
idleTimeout, ClientConnectionSettings(system))
|
||||
flowTestBench(Http().cachedHostConnectionPool[T](serverHostName, serverPort, settings))
|
||||
}
|
||||
|
|
@ -337,7 +339,7 @@ class ConnectionPoolSpec extends AkkaSpec("""
|
|||
pipeliningLimit: Int = 1,
|
||||
idleTimeout: Duration = 5.seconds,
|
||||
ccSettings: ClientConnectionSettings = ClientConnectionSettings(system)) = {
|
||||
val settings = ConnectionPoolSettings(maxConnections, maxRetries, maxOpenRequests, pipeliningLimit,
|
||||
val settings = new ConnectionPoolSettingsImpl(maxConnections, maxRetries, maxOpenRequests, pipeliningLimit,
|
||||
idleTimeout, ClientConnectionSettings(system))
|
||||
flowTestBench(Http().superPool[T](settings = settings))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
package akka.http.impl.engine.client
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.http.{ ClientConnectionSettings, ConnectionPoolSettings, ServerSettings }
|
||||
import akka.http.scaladsl.settings.{ ClientConnectionSettings, ConnectionPoolSettings, ServerSettings }
|
||||
import akka.stream.testkit.AkkaSpec
|
||||
import com.typesafe.config.ConfigFactory
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ package akka.http.impl.engine.client
|
|||
import scala.concurrent.duration._
|
||||
import scala.reflect.ClassTag
|
||||
import org.scalatest.Inside
|
||||
import akka.http.ClientConnectionSettings
|
||||
import akka.http.scaladsl.settings.ClientConnectionSettings
|
||||
import akka.stream.io.{ SessionBytes, SslTlsOutbound, SendBytes }
|
||||
import akka.util.ByteString
|
||||
import akka.event.NoLogging
|
||||
|
|
@ -521,9 +521,9 @@ class LowLevelOutgoingConnectionSpec extends AkkaSpec("akka.loggers = []\n akka.
|
|||
|
||||
def settings = {
|
||||
val s = ClientConnectionSettings(system)
|
||||
.copy(userAgentHeader = Some(`User-Agent`(List(ProductVersion("akka-http", "test")))))
|
||||
.withUserAgentHeader(Some(`User-Agent`(List(ProductVersion("akka-http", "test")))))
|
||||
if (maxResponseContentLength < 0) s
|
||||
else s.copy(parserSettings = s.parserSettings.copy(maxContentLength = maxResponseContentLength))
|
||||
else s.withParserSettings(s.parserSettings.withMaxContentLength(maxResponseContentLength))
|
||||
}
|
||||
|
||||
val (netOut, netIn) = {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
package akka.http.impl.engine.parsing
|
||||
|
||||
import java.lang.{ StringBuilder ⇒ JStringBuilder }
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
import com.typesafe.config.{ ConfigFactory, Config }
|
||||
import scala.annotation.tailrec
|
||||
import scala.util.Random
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package akka.http.impl.engine.parsing
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
import com.typesafe.config.{ ConfigFactory, Config }
|
||||
|
||||
object HttpHeaderParserTestBed extends App {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import akka.stream.io.{ SslTlsPlacebo, SessionBytes }
|
|||
import org.scalatest.matchers.Matcher
|
||||
import org.scalatest.{ BeforeAndAfterAll, FreeSpec, Matchers }
|
||||
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
import akka.http.impl.engine.parsing.ParserOutput._
|
||||
import akka.http.impl.util._
|
||||
import akka.http.scaladsl.model.HttpEntity._
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
package akka.http.impl.engine.parsing
|
||||
|
||||
import akka.NotUsed
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
import akka.http.scaladsl.util.FastFuture
|
||||
import akka.stream.io.{ SslTlsPlacebo, SessionBytes }
|
||||
import com.typesafe.config.{ ConfigFactory, Config }
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
package akka.http.impl.engine.server
|
||||
|
||||
import java.net.{ InetAddress, InetSocketAddress }
|
||||
import akka.http.ServerSettings
|
||||
import akka.http.scaladsl.settings.ServerSettings
|
||||
import scala.reflect.ClassTag
|
||||
import scala.util.Random
|
||||
import scala.annotation.tailrec
|
||||
|
|
@ -366,7 +366,7 @@ class HttpServerSpec extends AkkaSpec(
|
|||
}
|
||||
|
||||
"translate HEAD request to GET request when transparent-head-requests are enabled" in new TestSetup {
|
||||
override def settings = ServerSettings(system).copy(transparentHeadRequests = true)
|
||||
override def settings = ServerSettings(system).withTransparentHeadRequests(true)
|
||||
send("""HEAD / HTTP/1.1
|
||||
|Host: example.com
|
||||
|
|
||||
|
|
@ -375,7 +375,7 @@ class HttpServerSpec extends AkkaSpec(
|
|||
}
|
||||
|
||||
"keep HEAD request when transparent-head-requests are disabled" in new TestSetup {
|
||||
override def settings = ServerSettings(system).copy(transparentHeadRequests = false)
|
||||
override def settings = ServerSettings(system).withTransparentHeadRequests(false)
|
||||
send("""HEAD / HTTP/1.1
|
||||
|Host: example.com
|
||||
|
|
||||
|
|
@ -662,7 +662,7 @@ class HttpServerSpec extends AkkaSpec(
|
|||
|
||||
expectRequest() shouldEqual HttpRequest(uri = "http://example.com/abc", protocol = HttpProtocols.`HTTP/1.0`)
|
||||
|
||||
override def settings: ServerSettings = super.settings.copy(defaultHostHeader = Host("example.com"))
|
||||
override def settings: ServerSettings = super.settings.withDefaultHostHeader(Host("example.com"))
|
||||
}
|
||||
|
||||
"fail an HTTP/1.0 request with 400 if no default-host-header is set" in new TestSetup {
|
||||
|
|
@ -690,7 +690,7 @@ class HttpServerSpec extends AkkaSpec(
|
|||
Some(new InetSocketAddress(theAddress, 8080))
|
||||
|
||||
override def settings: ServerSettings =
|
||||
super.settings.copy(remoteAddressHeader = true)
|
||||
super.settings.withRemoteAddressHeader(true)
|
||||
|
||||
send("""GET / HTTP/1.1
|
||||
|Host: example.com
|
||||
|
|
@ -987,13 +987,13 @@ class HttpServerSpec extends AkkaSpec(
|
|||
override def settings = {
|
||||
val s = super.settings
|
||||
if (maxContentLength < 0) s
|
||||
else s.copy(parserSettings = s.parserSettings.copy(maxContentLength = maxContentLength))
|
||||
else s.withParserSettings(s.parserSettings.withMaxContentLength(maxContentLength))
|
||||
}
|
||||
}
|
||||
class RequestTimeoutTestSetup(requestTimeout: Duration) extends TestSetup {
|
||||
override def settings = {
|
||||
val s = super.settings
|
||||
s.copy(timeouts = s.timeouts.copy(requestTimeout = requestTimeout))
|
||||
s.withTimeouts(s.timeouts.withRequestTimeout(requestTimeout))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ package akka.http.impl.engine.server
|
|||
|
||||
import java.net.InetSocketAddress
|
||||
import akka.http.impl.engine.ws.ByteStringSinkProbe
|
||||
import akka.http.scaladsl.settings.ServerSettings
|
||||
import akka.stream.io.{ SendBytes, SslTlsOutbound, SessionBytes }
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
import akka.actor.ActorSystem
|
||||
|
|
@ -15,7 +16,6 @@ import akka.stream.{ ClosedShape, Materializer }
|
|||
import akka.stream.scaladsl._
|
||||
import akka.stream.testkit.{ TestPublisher, TestSubscriber }
|
||||
import akka.http.impl.util._
|
||||
import akka.http.ServerSettings
|
||||
import akka.http.scaladsl.model.headers.{ ProductVersion, Server }
|
||||
import akka.http.scaladsl.model.{ HttpResponse, HttpRequest }
|
||||
import akka.stream.OverflowStrategy
|
||||
|
|
@ -28,7 +28,7 @@ abstract class HttpServerTestSetupBase {
|
|||
val responses = TestPublisher.probe[HttpResponse]()
|
||||
|
||||
def settings = ServerSettings(system)
|
||||
.copy(serverHeader = Some(Server(List(ProductVersion("akka-http", "test")))))
|
||||
.withServerHeader(Some(Server(List(ProductVersion("akka-http", "test")))))
|
||||
def remoteAddress: Option[InetSocketAddress] = None
|
||||
|
||||
val (netIn, netOut) = {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import akka.stream.ClosedShape
|
|||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import akka.http.ClientConnectionSettings
|
||||
import akka.http.scaladsl.settings.ClientConnectionSettings
|
||||
import akka.http.scaladsl.Http
|
||||
import akka.http.scaladsl.model.headers.{ ProductVersion, `User-Agent` }
|
||||
import akka.http.scaladsl.model.ws._
|
||||
|
|
@ -297,9 +297,8 @@ class WebSocketClientSpec extends FreeSpec with Matchers with WithMaterializerSp
|
|||
|
||||
val random = new Random(0)
|
||||
def settings = ClientConnectionSettings(system)
|
||||
.copy(
|
||||
userAgentHeader = Some(`User-Agent`(List(ProductVersion("akka-http", "test")))),
|
||||
websocketRandomFactory = () ⇒ random)
|
||||
.withUserAgentHeader(Some(`User-Agent`(List(ProductVersion("akka-http", "test")))))
|
||||
.withWebsocketRandomFactory(() ⇒ random)
|
||||
|
||||
def targetUri: Uri = "ws://example.org/ws"
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package akka.http.impl.model.parser
|
||||
|
||||
import akka.http.ParserSettings.CookieParsingMode
|
||||
import akka.http.scaladsl.settings.ParserSettings.CookieParsingMode
|
||||
import akka.http.impl.model.parser.HeaderParser.Settings
|
||||
import org.scalatest.{ Matchers, FreeSpec }
|
||||
import org.scalatest.matchers.{ Matcher, MatchResult }
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ package akka.http.scaladsl
|
|||
import java.io.{ BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter }
|
||||
import java.net.{ BindException, Socket }
|
||||
import java.util.concurrent.TimeoutException
|
||||
import akka.http.scaladsl.settings.{ ConnectionPoolSettings, ClientConnectionSettings, ServerSettings }
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.{ Await, Future, Promise }
|
||||
|
|
@ -18,7 +20,6 @@ import akka.http.scaladsl.model.HttpEntity._
|
|||
import akka.http.scaladsl.model.HttpMethods._
|
||||
import akka.http.scaladsl.model._
|
||||
import akka.http.scaladsl.model.headers._
|
||||
import akka.http.{ ConnectionPoolSettings, ClientConnectionSettings, ServerSettings }
|
||||
import akka.stream.scaladsl._
|
||||
import akka.stream.testkit._
|
||||
import akka.stream.{ ActorMaterializer, BindFailedException, StreamTcpException }
|
||||
|
|
@ -114,7 +115,7 @@ class ClientServerSpec extends WordSpec with Matchers with BeforeAndAfterAll wit
|
|||
|
||||
"prevent more than the configured number of max-connections with bindAndHandle" in {
|
||||
val (_, hostname, port) = TestUtils.temporaryServerHostnameAndPort()
|
||||
val settings = ServerSettings(system).copy(maxConnections = 1)
|
||||
val settings = ServerSettings(system).withMaxConnections(1)
|
||||
|
||||
val receivedSlow = Promise[Long]()
|
||||
val receivedFast = Promise[Long]()
|
||||
|
|
@ -155,7 +156,7 @@ class ClientServerSpec extends WordSpec with Matchers with BeforeAndAfterAll wit
|
|||
"timeouts" should {
|
||||
def bindServer(hostname: String, port: Int, serverTimeout: FiniteDuration): (Promise[Long], ServerBinding) = {
|
||||
val s = ServerSettings(system)
|
||||
val settings = s.copy(timeouts = s.timeouts.copy(idleTimeout = serverTimeout))
|
||||
val settings = s.withTimeouts(s.timeouts.withIdleTimeout(serverTimeout))
|
||||
|
||||
val receivedRequest = Promise[Long]()
|
||||
|
||||
|
|
@ -204,7 +205,7 @@ class ClientServerSpec extends WordSpec with Matchers with BeforeAndAfterAll wit
|
|||
|
||||
val cs = ClientConnectionSettings(system)
|
||||
val clientTimeout = 345.millis
|
||||
val clientSettings = cs.copy(idleTimeout = clientTimeout)
|
||||
val clientSettings = cs.withIdleTimeout(clientTimeout)
|
||||
|
||||
val (_, hostname, port) = TestUtils.temporaryServerHostnameAndPort()
|
||||
val (receivedRequest: Promise[Long], b1: ServerBinding) = bindServer(hostname, port, serverTimeout)
|
||||
|
|
@ -237,7 +238,7 @@ class ClientServerSpec extends WordSpec with Matchers with BeforeAndAfterAll wit
|
|||
|
||||
val cs = ConnectionPoolSettings(system)
|
||||
val clientTimeout = 345.millis
|
||||
val clientPoolSettings = cs.copy(idleTimeout = clientTimeout)
|
||||
val clientPoolSettings = cs.withIdleTimeout(clientTimeout)
|
||||
|
||||
val (_, hostname, port) = TestUtils.temporaryServerHostnameAndPort()
|
||||
val (receivedRequest: Promise[Long], b1: ServerBinding) = bindServer(hostname, port, serverTimeout)
|
||||
|
|
@ -272,7 +273,7 @@ class ClientServerSpec extends WordSpec with Matchers with BeforeAndAfterAll wit
|
|||
|
||||
val cs = ConnectionPoolSettings(system)
|
||||
val clientTimeout = 345.millis
|
||||
val clientPoolSettings = cs.copy(idleTimeout = clientTimeout)
|
||||
val clientPoolSettings = cs.withIdleTimeout(clientTimeout)
|
||||
|
||||
val (_, hostname, port) = TestUtils.temporaryServerHostnameAndPort()
|
||||
val (receivedRequest: Promise[Long], b1: ServerBinding) = bindServer(hostname, port, serverTimeout)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import akka.http.javadsl.server.{ HttpApp, AllDirectives, Route, Directives }
|
|||
import akka.http.impl.util.JavaMapping.Implicits._
|
||||
import akka.http.impl.server.RouteImplementation
|
||||
import akka.http.scaladsl.model.HttpResponse
|
||||
import akka.http.scaladsl.server.{ RouteResult, RoutingSettings, Route ⇒ ScalaRoute }
|
||||
import akka.http.scaladsl.server.{ RouteResult, RoutingSettingsImpl, Route ⇒ ScalaRoute }
|
||||
import akka.actor.ActorSystem
|
||||
import akka.event.NoLogging
|
||||
import akka.http.impl.util._
|
||||
|
|
@ -55,7 +55,7 @@ abstract class RouteTest extends AllDirectives {
|
|||
securedConnection = defaultHostInfo.isSecuredConnection(),
|
||||
defaultHostHeader = defaultHostInfo.getHost().asScala)
|
||||
|
||||
val result = scalaRoute(new server.RequestContextImpl(effectiveRequest, NoLogging, RoutingSettings(system)))
|
||||
val result = scalaRoute(new server.RequestContextImpl(effectiveRequest, NoLogging, RoutingSettingsImpl(system)))
|
||||
|
||||
result.awaitResult(awaitDuration) match {
|
||||
case RouteResult.Complete(response) ⇒ createTestResponse(response)
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ trait RouteTest extends RequestBuilding with WSTestRequestBuilding with RouteTes
|
|||
}
|
||||
implicit def injectIntoRoute(implicit timeout: RouteTestTimeout,
|
||||
defaultHostInfo: DefaultHostInfo,
|
||||
routingSettings: RoutingSettings,
|
||||
routingSettings: RoutingSettingsImpl,
|
||||
executionContext: ExecutionContext,
|
||||
materializer: Materializer,
|
||||
routingLog: RoutingLog,
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@
|
|||
package akka.http.javadsl.client;
|
||||
|
||||
import akka.event.LoggingAdapter;
|
||||
import akka.http.ConnectionPoolSettings;
|
||||
import akka.http.javadsl.*;
|
||||
import akka.http.javadsl.model.HttpRequest;
|
||||
import akka.http.javadsl.model.HttpResponse;
|
||||
import akka.http.javadsl.testkit.JUnitRouteTest;
|
||||
import akka.http.scaladsl.settings.ConnectionPoolSettings;
|
||||
import akka.japi.Function;
|
||||
import akka.stream.javadsl.Flow;
|
||||
import scala.concurrent.Future;
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ class FileAndResourceDirectivesSpec extends RoutingSpec with Inspectors with Ins
|
|||
val base = new File(getClass.getClassLoader.getResource("").toURI).getPath
|
||||
new File(base, "subDirectory/emptySub").mkdir()
|
||||
def eraseDateTime(s: String) = s.replaceAll("""\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d""", "xxxx-xx-xx xx:xx:xx")
|
||||
implicit val settings = RoutingSettings.default.copy(renderVanityFooter = false)
|
||||
implicit val settings = RoutingSettingsImpl.default.copy(renderVanityFooter = false)
|
||||
|
||||
"properly render a simple directory" in {
|
||||
Get() ~> listDirectoryContents(base + "/someDir") ~> check {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ package akka.http.javadsl.server
|
|||
import akka.actor.ActorSystem
|
||||
import akka.http.scaladsl.{ server, Http }
|
||||
import akka.http.scaladsl.Http.ServerBinding
|
||||
import akka.http.scaladsl.server.RouteResult
|
||||
import akka.http.impl.server.RouteImplementation
|
||||
import akka.stream.{ ActorMaterializer, Materializer }
|
||||
import akka.stream.scaladsl.{ Keep, Sink }
|
||||
|
|
@ -38,7 +39,7 @@ trait HttpServiceBase {
|
|||
|
||||
import system.dispatcher
|
||||
val r: server.Route = RouteImplementation(route)
|
||||
Http(system).bind(interface, port).toMat(Sink.foreach(_.handleWith(r)))(Keep.left).run()(materializer).toJava
|
||||
Http(system).bind(interface, port).toMat(Sink.foreach(_.handleWith(RouteResult.route2HandlerFlow(r))))(Keep.left).run()(materializer).toJava
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ trait ExceptionHandler extends ExceptionHandler.PF {
|
|||
/**
|
||||
* "Seals" this handler by attaching a default handler as fallback if necessary.
|
||||
*/
|
||||
def seal(settings: RoutingSettings): ExceptionHandler
|
||||
def seal(settings: RoutingSettingsImpl): ExceptionHandler
|
||||
}
|
||||
|
||||
object ExceptionHandler {
|
||||
|
|
@ -32,11 +32,11 @@ object ExceptionHandler {
|
|||
def apply(error: Throwable) = pf(error)
|
||||
def withFallback(that: ExceptionHandler): ExceptionHandler =
|
||||
if (!knownToBeSealed) ExceptionHandler(knownToBeSealed = false)(this orElse that) else this
|
||||
def seal(settings: RoutingSettings): ExceptionHandler =
|
||||
def seal(settings: RoutingSettingsImpl): ExceptionHandler =
|
||||
if (!knownToBeSealed) ExceptionHandler(knownToBeSealed = true)(this orElse default(settings)) else this
|
||||
}
|
||||
|
||||
def default(settings: RoutingSettings): ExceptionHandler =
|
||||
def default(settings: RoutingSettingsImpl): ExceptionHandler =
|
||||
apply(knownToBeSealed = true) {
|
||||
case IllegalRequestException(info, status) ⇒ ctx ⇒ {
|
||||
ctx.log.warning("Illegal request {}\n\t{}\n\tCompleting with '{}' response",
|
||||
|
|
@ -53,6 +53,6 @@ object ExceptionHandler {
|
|||
* Creates a sealed ExceptionHandler from the given one. Returns the default handler if the given one
|
||||
* is `null`.
|
||||
*/
|
||||
def seal(handler: ExceptionHandler)(implicit settings: RoutingSettings): ExceptionHandler =
|
||||
def seal(handler: ExceptionHandler)(implicit settings: RoutingSettingsImpl): ExceptionHandler =
|
||||
if (handler ne null) handler.seal(settings) else ExceptionHandler.default(settings)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@
|
|||
package akka.http.scaladsl.server
|
||||
|
||||
import scala.concurrent.{ Future, ExecutionContextExecutor }
|
||||
import akka.http.ParserSettings
|
||||
import akka.stream.Materializer
|
||||
import akka.event.LoggingAdapter
|
||||
import akka.http.scaladsl.marshalling.ToResponseMarshallable
|
||||
import akka.http.scaladsl.model._
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
|
||||
/**
|
||||
* Immutable object encapsulating the context of an [[akka.http.scaladsl.model.HttpRequest]]
|
||||
|
|
@ -41,7 +41,7 @@ trait RequestContext {
|
|||
/**
|
||||
* The default RoutingSettings to be used for configuring directives.
|
||||
*/
|
||||
def settings: RoutingSettings
|
||||
def settings: RoutingSettingsImpl
|
||||
|
||||
/**
|
||||
* The default ParserSettings to be used for configuring directives.
|
||||
|
|
@ -55,7 +55,7 @@ trait RequestContext {
|
|||
executionContext: ExecutionContextExecutor = executionContext,
|
||||
materializer: Materializer = materializer,
|
||||
log: LoggingAdapter = log,
|
||||
settings: RoutingSettings = settings): RequestContext
|
||||
settings: RoutingSettingsImpl = settings): RequestContext
|
||||
|
||||
/**
|
||||
* Completes the request with the given ToResponseMarshallable.
|
||||
|
|
@ -97,7 +97,7 @@ trait RequestContext {
|
|||
/**
|
||||
* Returns a copy of this context with the new RoutingSettings.
|
||||
*/
|
||||
def withRoutingSettings(settings: RoutingSettings): RequestContext
|
||||
def withRoutingSettings(settings: RoutingSettingsImpl): RequestContext
|
||||
|
||||
/**
|
||||
* Returns a copy of this context with the new [[ParserSettings]].
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ package akka.http.scaladsl.server
|
|||
import scala.concurrent.{ Future, ExecutionContextExecutor }
|
||||
import akka.stream.{ ActorMaterializer, Materializer }
|
||||
import akka.event.LoggingAdapter
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
import akka.http.scaladsl.marshalling.{ Marshal, ToResponseMarshallable }
|
||||
import akka.http.scaladsl.model._
|
||||
import akka.http.scaladsl.util.FastFuture
|
||||
|
|
@ -22,16 +22,16 @@ private[http] class RequestContextImpl(
|
|||
val executionContext: ExecutionContextExecutor,
|
||||
val materializer: Materializer,
|
||||
val log: LoggingAdapter,
|
||||
val settings: RoutingSettings,
|
||||
val settings: RoutingSettingsImpl,
|
||||
val parserSettings: ParserSettings) extends RequestContext {
|
||||
|
||||
def this(request: HttpRequest, log: LoggingAdapter, settings: RoutingSettings, parserSettings: ParserSettings)(implicit ec: ExecutionContext, materializer: Materializer) =
|
||||
def this(request: HttpRequest, log: LoggingAdapter, settings: RoutingSettingsImpl, parserSettings: ParserSettings)(implicit ec: ExecutionContextExecutor, materializer: Materializer) =
|
||||
this(request, request.uri.path, ec, materializer, log, settings, parserSettings)
|
||||
|
||||
def this(request: HttpRequest, log: LoggingAdapter, settings: RoutingSettings)(implicit ec: ExecutionContextExecutor, materializer: Materializer) =
|
||||
def this(request: HttpRequest, log: LoggingAdapter, settings: RoutingSettingsImpl)(implicit ec: ExecutionContextExecutor, materializer: Materializer) =
|
||||
this(request, request.uri.path, ec, materializer, log, settings, ParserSettings(ActorMaterializer.downcast(materializer).system))
|
||||
|
||||
def reconfigure(executionContext: ExecutionContextExecutor, materializer: Materializer, log: LoggingAdapter, settings: RoutingSettings): RequestContext =
|
||||
def reconfigure(executionContext: ExecutionContextExecutor, materializer: Materializer, log: LoggingAdapter, settings: RoutingSettingsImpl): RequestContext =
|
||||
copy(executionContext = executionContext, materializer = materializer, log = log, routingSettings = settings)
|
||||
|
||||
override def complete(trm: ToResponseMarshallable): Future[RouteResult] =
|
||||
|
|
@ -61,7 +61,7 @@ private[http] class RequestContextImpl(
|
|||
override def withLog(log: LoggingAdapter): RequestContext =
|
||||
if (log != this.log) copy(log = log) else this
|
||||
|
||||
override def withRoutingSettings(routingSettings: RoutingSettings): RequestContext =
|
||||
override def withRoutingSettings(routingSettings: RoutingSettingsImpl): RequestContext =
|
||||
if (routingSettings != this.settings) copy(routingSettings = routingSettings) else this
|
||||
|
||||
override def withParserSettings(parserSettings: ParserSettings): RequestContext =
|
||||
|
|
@ -94,7 +94,7 @@ private[http] class RequestContextImpl(
|
|||
executionContext: ExecutionContextExecutor = executionContext,
|
||||
materializer: Materializer = materializer,
|
||||
log: LoggingAdapter = log,
|
||||
routingSettings: RoutingSettings = settings,
|
||||
routingSettings: RoutingSettingsImpl = settings,
|
||||
parserSettings: ParserSettings = parserSettings) =
|
||||
new RequestContextImpl(request, unmatchedPath, executionContext, materializer, log, routingSettings, parserSettings)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ package akka.http.scaladsl.server
|
|||
|
||||
import akka.NotUsed
|
||||
import akka.actor.ActorSystem
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
import akka.stream.{ ActorMaterializer, Materializer }
|
||||
|
||||
import scala.concurrent.{ ExecutionContextExecutor, Future }
|
||||
|
|
@ -24,7 +24,7 @@ object Route {
|
|||
/**
|
||||
* "Seals" a route by wrapping it with exception handling and rejection conversion.
|
||||
*/
|
||||
def seal(route: Route)(implicit routingSettings: RoutingSettings,
|
||||
def seal(route: Route)(implicit routingSettings: RoutingSettingsImpl,
|
||||
parserSettings: ParserSettings = null,
|
||||
rejectionHandler: RejectionHandler = RejectionHandler.default,
|
||||
exceptionHandler: ExceptionHandler = null): Route = {
|
||||
|
|
@ -41,7 +41,7 @@ object Route {
|
|||
*
|
||||
* This conversion is also implicitly available through [[RouteResult.route2HandlerFlow]].
|
||||
*/
|
||||
def handlerFlow(route: Route)(implicit routingSettings: RoutingSettings,
|
||||
def handlerFlow(route: Route)(implicit routingSettings: RoutingSettingsImpl,
|
||||
parserSettings: ParserSettings,
|
||||
materializer: Materializer,
|
||||
routingLog: RoutingLog,
|
||||
|
|
@ -53,7 +53,7 @@ object Route {
|
|||
/**
|
||||
* Turns a `Route` into an async handler function.
|
||||
*/
|
||||
def asyncHandler(route: Route)(implicit routingSettings: RoutingSettings,
|
||||
def asyncHandler(route: Route)(implicit routingSettings: RoutingSettingsImpl,
|
||||
parserSettings: ParserSettings,
|
||||
materializer: Materializer,
|
||||
routingLog: RoutingLog,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
package akka.http.scaladsl.server
|
||||
|
||||
import akka.NotUsed
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
|
||||
import scala.collection.immutable
|
||||
import scala.concurrent.ExecutionContext
|
||||
|
|
@ -25,7 +25,7 @@ object RouteResult {
|
|||
final case class Complete(response: HttpResponse) extends RouteResult
|
||||
final case class Rejected(rejections: immutable.Seq[Rejection]) extends RouteResult
|
||||
|
||||
implicit def route2HandlerFlow(route: Route)(implicit routingSettings: RoutingSettings,
|
||||
implicit def route2HandlerFlow(route: Route)(implicit routingSettings: RoutingSettingsImpl,
|
||||
parserSettings: ParserSettings,
|
||||
materializer: Materializer,
|
||||
routingLog: RoutingLog,
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2016 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.scaladsl.server
|
||||
|
||||
import com.typesafe.config.Config
|
||||
import akka.actor.ActorRefFactory
|
||||
import akka.http.impl.util._
|
||||
|
||||
final class RoutingSettings(
|
||||
val verboseErrorMessages: Boolean,
|
||||
val fileGetConditional: Boolean,
|
||||
val renderVanityFooter: Boolean,
|
||||
val rangeCountLimit: Int,
|
||||
val rangeCoalescingThreshold: Long,
|
||||
val decodeMaxBytesPerChunk: Int,
|
||||
val fileIODispatcher: String) {
|
||||
|
||||
def copy(
|
||||
verboseErrorMessages: Boolean = verboseErrorMessages,
|
||||
fileGetConditional: Boolean = fileGetConditional,
|
||||
renderVanityFooter: Boolean = renderVanityFooter,
|
||||
rangeCountLimit: Int = rangeCountLimit,
|
||||
rangeCoalescingThreshold: Long = rangeCoalescingThreshold,
|
||||
decodeMaxBytesPerChunk: Int = decodeMaxBytesPerChunk,
|
||||
fileIODispatcher: String = fileIODispatcher): RoutingSettings =
|
||||
new RoutingSettings(
|
||||
verboseErrorMessages,
|
||||
fileGetConditional,
|
||||
renderVanityFooter,
|
||||
rangeCountLimit,
|
||||
rangeCoalescingThreshold,
|
||||
decodeMaxBytesPerChunk,
|
||||
fileIODispatcher)
|
||||
|
||||
// TODO we should automate generating those
|
||||
override def toString = {
|
||||
getClass.getSimpleName + "(" +
|
||||
verboseErrorMessages + "," +
|
||||
fileGetConditional + "," +
|
||||
renderVanityFooter + "," +
|
||||
rangeCountLimit + "," +
|
||||
rangeCoalescingThreshold + "," +
|
||||
decodeMaxBytesPerChunk + "," +
|
||||
fileIODispatcher +
|
||||
")"
|
||||
}
|
||||
}
|
||||
|
||||
object RoutingSettings extends SettingsCompanion[RoutingSettings]("akka.http.routing") {
|
||||
def fromSubConfig(root: Config, c: Config) = new RoutingSettings(
|
||||
c getBoolean "verbose-error-messages",
|
||||
c getBoolean "file-get-conditional",
|
||||
c getBoolean "render-vanity-footer",
|
||||
c getInt "range-count-limit",
|
||||
c getBytes "range-coalescing-threshold",
|
||||
c getIntBytes "decode-max-bytes-per-chunk",
|
||||
c getString "file-io-dispatcher")
|
||||
|
||||
implicit def default(implicit refFactory: ActorRefFactory): RoutingSettings =
|
||||
apply(actorSystem)
|
||||
|
||||
def apply(
|
||||
verboseErrorMessages: Boolean,
|
||||
fileGetConditional: Boolean,
|
||||
renderVanityFooter: Boolean,
|
||||
rangeCountLimit: Int,
|
||||
rangeCoalescingThreshold: Long,
|
||||
decodeMaxBytesPerChunk: Int,
|
||||
fileIODispatcher: String): RoutingSettings =
|
||||
new RoutingSettings(
|
||||
verboseErrorMessages,
|
||||
fileGetConditional,
|
||||
renderVanityFooter,
|
||||
rangeCountLimit,
|
||||
rangeCoalescingThreshold,
|
||||
decodeMaxBytesPerChunk,
|
||||
fileIODispatcher)
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.scaladsl.server
|
||||
|
||||
import com.typesafe.config.Config
|
||||
import akka.actor.ActorRefFactory
|
||||
import akka.http.impl.util._
|
||||
|
||||
/** INTERNAL API */
|
||||
final case class RoutingSettingsImpl(
|
||||
verboseErrorMessages: Boolean,
|
||||
fileGetConditional: Boolean,
|
||||
renderVanityFooter: Boolean,
|
||||
rangeCountLimit: Int,
|
||||
rangeCoalescingThreshold: Long,
|
||||
decodeMaxBytesPerChunk: Int,
|
||||
fileIODispatcher: String)
|
||||
|
||||
object RoutingSettingsImpl extends SettingsCompanion[RoutingSettingsImpl]("akka.http.routing") {
|
||||
def fromSubConfig(root: Config, c: Config) = new RoutingSettingsImpl(
|
||||
c getBoolean "verbose-error-messages",
|
||||
c getBoolean "file-get-conditional",
|
||||
c getBoolean "render-vanity-footer",
|
||||
c getInt "range-count-limit",
|
||||
c getBytes "range-coalescing-threshold",
|
||||
c getIntBytes "decode-max-bytes-per-chunk",
|
||||
c getString "file-io-dispatcher")
|
||||
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import scala.concurrent.{ Future, ExecutionContextExecutor }
|
|||
import scala.collection.immutable
|
||||
import akka.event.LoggingAdapter
|
||||
import akka.stream.Materializer
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
import akka.http.scaladsl.server.util.Tuple
|
||||
import akka.http.scaladsl.util.FastFuture
|
||||
import akka.http.scaladsl.model._
|
||||
|
|
@ -131,13 +131,13 @@ trait BasicDirectives {
|
|||
def extractUri: Directive1[Uri] = BasicDirectives._extractUri
|
||||
|
||||
/**
|
||||
* Runs its inner route with the given alternative [[ExecutionContext]].
|
||||
* Runs its inner route with the given alternative [[ExecutionContextExecutor]].
|
||||
*/
|
||||
def withExecutionContext(ec: ExecutionContextExecutor): Directive0 =
|
||||
mapRequestContext(_ withExecutionContext ec)
|
||||
|
||||
/**
|
||||
* Extracts the [[ExecutionContext]] from the [[RequestContext]].
|
||||
* Extracts the [[ExecutionContextExecutor]] from the [[RequestContext]].
|
||||
*/
|
||||
def extractExecutionContext: Directive1[ExecutionContextExecutor] = BasicDirectives._extractExecutionContext
|
||||
|
||||
|
|
@ -165,25 +165,25 @@ trait BasicDirectives {
|
|||
BasicDirectives._extractLog
|
||||
|
||||
/**
|
||||
* Runs its inner route with the given alternative [[RoutingSettings]].
|
||||
* Runs its inner route with the given alternative [[RoutingSettingsImpl]].
|
||||
*/
|
||||
def withSettings(settings: RoutingSettings): Directive0 =
|
||||
def withSettings(settings: RoutingSettingsImpl): Directive0 =
|
||||
mapRequestContext(_ withRoutingSettings settings)
|
||||
|
||||
/**
|
||||
* Runs the inner route with settings mapped by the given function.
|
||||
*/
|
||||
def mapSettings(f: RoutingSettings ⇒ RoutingSettings): Directive0 =
|
||||
def mapSettings(f: RoutingSettingsImpl ⇒ RoutingSettingsImpl): Directive0 =
|
||||
mapRequestContext(ctx ⇒ ctx.withRoutingSettings(f(ctx.settings)))
|
||||
|
||||
/**
|
||||
* Extracts the [[RoutingSettings]] from the [[RequestContext]].
|
||||
* Extracts the [[RoutingSettingsImpl]] from the [[RequestContext]].
|
||||
*/
|
||||
def extractSettings: Directive1[RoutingSettings] =
|
||||
def extractSettings: Directive1[RoutingSettingsImpl] =
|
||||
BasicDirectives._extractSettings
|
||||
|
||||
/**
|
||||
* Extracts the [[akka.http.ParserSettings]] from the [[RequestContext]].
|
||||
* Extracts the [[akka.http.scaladsl.settings.ParserSettings]] from the [[RequestContext]].
|
||||
*/
|
||||
def extractParserSettings: Directive1[ParserSettings] =
|
||||
BasicDirectives._extractParserSettings
|
||||
|
|
@ -201,7 +201,7 @@ object BasicDirectives extends BasicDirectives {
|
|||
private val _extractExecutionContext: Directive1[ExecutionContextExecutor] = extract(_.executionContext)
|
||||
private val _extractMaterializer: Directive1[Materializer] = extract(_.materializer)
|
||||
private val _extractLog: Directive1[LoggingAdapter] = extract(_.log)
|
||||
private val _extractSettings: Directive1[RoutingSettings] = extract(_.settings)
|
||||
private val _extractSettings: Directive1[RoutingSettingsImpl] = extract(_.settings)
|
||||
private val _extractParserSettings: Directive1[ParserSettings] = extract(_.parserSettings)
|
||||
private val _extractRequestContext: Directive1[RequestContext] = extract(conforms)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ package akka.http.scaladsl.server
|
|||
package directives
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
import akka.http.scaladsl.model.Multipart
|
||||
import akka.http.scaladsl.model.Multipart.ByteRanges
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
package akka.http.scaladsl.unmarshalling
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.http.ParserSettings
|
||||
import akka.http.scaladsl.settings.ParserSettings
|
||||
|
||||
import scala.collection.immutable
|
||||
import scala.collection.immutable.VectorBuilder
|
||||
|
|
@ -23,11 +23,16 @@ import MediaTypes._
|
|||
import HttpCharsets._
|
||||
import akka.stream.impl.fusing.SubSource
|
||||
|
||||
/**
|
||||
* Provides [[Multipart]] marshallers.
|
||||
* It is possible to configure the default parsing mode by providing an implicit [[ParserSettings]] instance.
|
||||
*/
|
||||
trait MultipartUnmarshallers {
|
||||
|
||||
implicit def defaultMultipartGeneralUnmarshaller(implicit log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.General] =
|
||||
implicit def defaultMultipartGeneralUnmarshaller(implicit log: LoggingAdapter = NoLogging, parserSettings: ParserSettings = null): FromEntityUnmarshaller[Multipart.General] =
|
||||
multipartGeneralUnmarshaller(`UTF-8`)
|
||||
def multipartGeneralUnmarshaller(defaultCharset: HttpCharset)(implicit log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.General] =
|
||||
|
||||
def multipartGeneralUnmarshaller(defaultCharset: HttpCharset)(implicit log: LoggingAdapter = NoLogging, parserSettings: ParserSettings = null): FromEntityUnmarshaller[Multipart.General] =
|
||||
multipartUnmarshaller[Multipart.General, Multipart.General.BodyPart, Multipart.General.BodyPart.Strict](
|
||||
mediaRange = `multipart/*`,
|
||||
defaultContentType = MediaTypes.`text/plain` withCharset defaultCharset,
|
||||
|
|
@ -36,7 +41,7 @@ trait MultipartUnmarshallers {
|
|||
createStrictBodyPart = Multipart.General.BodyPart.Strict,
|
||||
createStrict = Multipart.General.Strict)
|
||||
|
||||
implicit def multipartFormDataUnmarshaller(implicit log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.FormData] =
|
||||
implicit def multipartFormDataUnmarshaller(implicit log: LoggingAdapter = NoLogging, parserSettings: ParserSettings = null): FromEntityUnmarshaller[Multipart.FormData] =
|
||||
multipartUnmarshaller[Multipart.FormData, Multipart.FormData.BodyPart, Multipart.FormData.BodyPart.Strict](
|
||||
mediaRange = `multipart/form-data`,
|
||||
defaultContentType = ContentTypes.`application/octet-stream`,
|
||||
|
|
@ -45,9 +50,10 @@ trait MultipartUnmarshallers {
|
|||
createStrictBodyPart = (entity, headers) ⇒ Multipart.General.BodyPart.Strict(entity, headers).toFormDataBodyPart.get,
|
||||
createStrict = (_, parts) ⇒ Multipart.FormData.Strict(parts))
|
||||
|
||||
implicit def defaultMultipartByteRangesUnmarshaller(implicit log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.ByteRanges] =
|
||||
implicit def defaultMultipartByteRangesUnmarshaller(implicit log: LoggingAdapter = NoLogging, parserSettings: ParserSettings = null): FromEntityUnmarshaller[Multipart.ByteRanges] =
|
||||
multipartByteRangesUnmarshaller(`UTF-8`)
|
||||
def multipartByteRangesUnmarshaller(defaultCharset: HttpCharset)(implicit log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[Multipart.ByteRanges] =
|
||||
|
||||
def multipartByteRangesUnmarshaller(defaultCharset: HttpCharset)(implicit log: LoggingAdapter = NoLogging, parserSettings: ParserSettings = null): FromEntityUnmarshaller[Multipart.ByteRanges] =
|
||||
multipartUnmarshaller[Multipart.ByteRanges, Multipart.ByteRanges.BodyPart, Multipart.ByteRanges.BodyPart.Strict](
|
||||
mediaRange = `multipart/byteranges`,
|
||||
defaultContentType = MediaTypes.`text/plain` withCharset defaultCharset,
|
||||
|
|
@ -56,12 +62,13 @@ trait MultipartUnmarshallers {
|
|||
createStrictBodyPart = (entity, headers) ⇒ Multipart.General.BodyPart.Strict(entity, headers).toByteRangesBodyPart.get,
|
||||
createStrict = (_, parts) ⇒ Multipart.ByteRanges.Strict(parts))
|
||||
|
||||
def multipartUnmarshaller[T <: Multipart, BP <: Multipart.BodyPart, BPS <: Multipart.BodyPart.Strict](mediaRange: MediaRange,
|
||||
defaultContentType: ContentType,
|
||||
createBodyPart: (BodyPartEntity, List[HttpHeader]) ⇒ BP,
|
||||
createStreamed: (MediaType.Multipart, Source[BP, Any]) ⇒ T,
|
||||
createStrictBodyPart: (HttpEntity.Strict, List[HttpHeader]) ⇒ BPS,
|
||||
createStrict: (MediaType.Multipart, immutable.Seq[BPS]) ⇒ T)(implicit log: LoggingAdapter = NoLogging): FromEntityUnmarshaller[T] =
|
||||
def multipartUnmarshaller[T <: Multipart, BP <: Multipart.BodyPart, BPS <: Multipart.BodyPart.Strict](
|
||||
mediaRange: MediaRange,
|
||||
defaultContentType: ContentType,
|
||||
createBodyPart: (BodyPartEntity, List[HttpHeader]) ⇒ BP,
|
||||
createStreamed: (MediaType.Multipart, Source[BP, Any]) ⇒ T,
|
||||
createStrictBodyPart: (HttpEntity.Strict, List[HttpHeader]) ⇒ BPS,
|
||||
createStrict: (MediaType.Multipart, immutable.Seq[BPS]) ⇒ T)(implicit log: LoggingAdapter = NoLogging, parserSettings: ParserSettings = null): FromEntityUnmarshaller[T] =
|
||||
Unmarshaller.withMaterializer { implicit ec ⇒ mat =>
|
||||
entity ⇒
|
||||
if (entity.contentType.mediaType.isMultipart && mediaRange.matches(entity.contentType.mediaType)) {
|
||||
|
|
@ -70,7 +77,8 @@ trait MultipartUnmarshallers {
|
|||
FastFuture.failed(new RuntimeException("Content-Type with a multipart media type must have a 'boundary' parameter"))
|
||||
case Some(boundary) ⇒
|
||||
import BodyPartParser._
|
||||
val parser = new BodyPartParser(defaultContentType, boundary, log, ParserSettings(ActorMaterializer.downcast(mat).system)) // TODO we could cache it
|
||||
val effectiveParserSettings = Option(parserSettings).getOrElse(ParserSettings(ActorMaterializer.downcast(mat).system))
|
||||
val parser = new BodyPartParser(defaultContentType, boundary, log, effectiveParserSettings)
|
||||
FastFuture.successful {
|
||||
entity match {
|
||||
case HttpEntity.Strict(ContentType(mediaType: MediaType.Multipart, _), data) ⇒
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue