HttpBody was completely replaced by HttpData. HttpData is a data structure that
abstracts over either ByteString buffers (HttpData.Bytes), data from files
(HttpData.FileBytes), and combinations of both (HttpData.Compound). This allows spray-can
to combine both heap byte buffers and data from files without ever having to load file data into a
The companion object of HttpEntity contains lots of overloaded apply methods to create an
HttpEntity without having to deal with HttpData directly.
Authentication rejections were remodelled. There’s now only one rejection type, AuthenticationFailedRejection, that
contains a cause (CredentialsMissing or CredentialsRejected) and a list of headers to add to the response
as a challenge for the client. Previously, challenge generation wasn’t handled uniformly and challenges weren’t generated
at all in some cases. For your custom authenticator, you now have to generate the challenge headers directly in
the ContextAuthenticator implementation. HttpAuthenticator now has a new abstract method to implement to return
With request chunk aggregation turned off (spray.can.server.request-chunk-aggregation-limit=0)
spray-can will deliver request chunks as is to the user-level handler.
Previously, all chunks of a request came in subsequently without any interaction needed from the handler. Now the
ChunkedRequestStart message has to be acknowledged with a RegisterChunkHandler message which contains the
ActorRef of an actor to handle the chunks before any actual MessageChunks will be delivered. This allows to
separate the handling of multiple incoming request chunk streams to several chunk handlers.
The path matching infrastructure was changed by replacing automatic behavior with more explicit directives. Mainly, this
affects uses of nested path("") directives. Previously, path("") would either match 1) nothing, 2) a single slash,
or 3) two slashes before the path end. Since the question of whether to deliver identical content under two different
URIs (adding a trailing slash to a URI results in a semantically different URI!) is one of continuous discussion
(see for example: http://googlewebmastercentral.blogspot.de/2010/04/to-slash-or-not-to-slash.html) we want to make it
easy for your to pick your strategy and be consistent about it. With the new version, you can use one of the new
directives instead of path("") to be explicit about what to match:
pathEnd, which matches just the path end without any trailing slashes
pathSingleSlash, which matches the path only when it ends with a slash
pathEndOrSingleSlash, which matches in both cases
Directives path and pathPrefix previously matched an optional beginning slash from the (remaining) path. The
beginning slash is now required. If that’s not what you want use rawPathPrefix instead.
PathMatcher.Slash replaces the old PathMatcher.Slash_! which matches exactly one slash.
PathMatcher.PathEnd now matches exactly the end of the path (before: an optional slash as well).
PathMatcher.Segments also doesn’t match a trailing slash any more.
PathMatcher.Empty was renamed to PathMatcher.Neutral.
It is now easy to create path matchers for optional or repeated matches. Use PathMatcher.? to make a PathMatcher
optional. Use PathMatcher.repeat to capture several matches.
Introduction of ToResponseMarshaller etc.
RequestContext.complete overloads gone
Comprehensive list of breaking changes
The following list is an annotated version of all commits that were marked as breaking (!) since M8. You may
find additional information on how to fix broken code by looking into the linked commits. Changes are often accompanied
with test changes that show how code can be fixed.
ExpiringLruCache uses Duration instead of Long for timeouts .
LruCache.apply doesn’t allow Duration.Zero any more but Duration.Inf, instead, for not specifying
any timeout .
ServerSettings timeout settings were moved into a separate class .
new member HostConnectorSettings.maxRedirects to enable automatic redirection handling on the client side
spray.can.client.user-agent-header vs. specifying a custom User-Agent header behavior changed: a custom
User-Agent header now always overrides any configuration setting. The setting is used when there’s no custom
header specified [6fec00c].
Connection failure and request timeout now produce dedicated exceptions on the client side [4b48875].
HostConnectorSettings.connectionSettings are now read from spray.can.client instead of from
spray.can.client.ssl-encryption is gone. Instead, Http.Connect got a new sslEncryption parameter
replacing the global setting. [e922cd4].
HostConnectorSetup must now be created from hostname and port. Before it was created from an InetSocketAddress
which wasn’t enough to distinguish virtual hosts [a47f3b0].
keepOpenOnPeerClosed is not supported for Http and was removed from Http.Register[f6b0292].
ClientConnectionSettings and ServerSettings got a new member maxEncryptionChunkSize[0b5ef36].
Lots of formerly public types belonging to spray’s private API were marked as such [da29cdf].
spray.can.server.response-size-hint was adapted to spray.can.server.response-header-size-hint. The same
Content-Length.length is now a Long value. Also spray.can.server.parsing.max-content-length and
SetIdleTimeout command now always resets the timeout [ab17f00].
SslTlsSupport pipeline stage now publishes a SSLSessionEstablished event with session details [80982d4].
New ParserSettings.sslSessionInfoHeader setting which enables the automatic addition of a synthetic
SSL-Session-Info header to a request/response with SSL session information [e486900].
ClientConnectionSettings.userAgentHeader is now modelled directly by an Option[User-Agent]. [da12531].
Access-Control-Allow-Origin and Origin header models now have members of newly introduced type HttpOrigin
instead of the previous Uri which didn’t completely match the model [015f3c6].
Renderer.seqRenderer and related signatures changed [e058a43].
in Uri.Query a '=' is rendered even for empty values unless the special value Query.EmptyValue is used.
Also, a query parsed from ?key= will now be rendered the same way (previously, a trailing '=' was always stripped) [d2b8bba].
(Multipart)FormData.fields are now represented as Seq to be able to model duplicate fields [ad593d1].
HttpMessage.entityAccepted was renamed to HttpMessage.isEntityAccepted[5d78dae].
RequestContext.complete overloads were removed in favor of using the marshalling infrastructure
(see (Un)marshalling) [4d787dc].
CompletionMagnet is gone in favor of the new ToResponseMarshaller infrastructure [7a36de5].
FieldDefMagnetAux, ParamDefMagnetAux, and AnyParamDefMagnetAux are gone and replaced by a simpler
RequestContext.marshallingContext is gone. produce directive loses its status and header parameter
which can be replaced by using an appropriate ToResponseMarshaller[b145ced].
AuthenticationFailedRejection now directly contains challenge headers to return. There’s no need to implement
a (fake) HttpAuthenticator to make use of the rejection (see Authentication) [9c9b976].
FileAndResourceDirectives.withTrailingSlash and fileSystemPath are now private [ab35761].
decompressRequest and compressResponse now always need parentheses. Also, encoding directives like the
compressResponse automatically use the autoChunkFileBytes directives to avoid having to load potentially huge
files into memory [e3defb4].
(h)require directives can now take several rejections instead of an Option of only one [9c11228].
detachTo is gone in favor of detach() which always needs parentheses. The underlying implementation is now
Future-based and needs an (implicit or explicit) ExecutionContext or ActorRefFactory in scope [ead4a70].
PathMatcher.(flat)Map were renamed to PathMatcher.h(flat)Map. map and flatMap were reintroduced for
PathMatcher1 instances [8c91851].
AuthenticationFailedRejection and AuthenticationRequiredRejection were merged and
PathMatchers.Empty was renamed to PathMatchers.Neutral[ee7fe47].
Slash_! is gone and Slash got its semantics. PathEnd now just matches the end of the path.
PathDirectives were adapted to have the same semantics as before [1480e73].
UserPassAuthenticator.cached was renamed to CachedUserPassAuthenticator.apply.
PathMatcher.apply now takes a Path prefix instead of a String[3ff3471].
PathMatcher.Segments doesn’t match trailing slashes anymore. Implicit infrastructure for PathMatcher.?
was changed [8ee49d7].