Migration from M8
Big breaking changes
Replacement of HttpBody by HttpData
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
heap buffer.
The companion object of HttpEntity
contains lots of overloaded apply methods to create an
HttpEntity
without having to deal with HttpData
directly.
Authentication
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
challenge headers.
Chunking support
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.
PathMatcher infrastructure
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 slashespathSingleSlash
, which matches the path only when it ends with a slashpathEndOrSingleSlash
, 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.
Also:
PathMatcher.Slash
replaces the oldPathMatcher.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 toPathMatcher.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.
(Un)marshalling
(TODO)
- Introduction of ToResponseMarshaller etc.
- RequestContext.complete overloads gone
- CompletionMagnet 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.
spray-can
Server-side changes:
- Http handlers must answer
ChunkedRequestStart
message withRegisterChunkHandler
command (see chunking support) [d738e54]ServerSettings
timeout settings were moved into a separate class [9193318].
Client-side changes:
- new member
HostConnectorSettings.maxRedirects
to enable automatic redirection handling on the client side [98365ff]spray.can.client.user-agent-header
vs. specifying a customUser-Agent
header behavior changed: a customUser-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 fromspray.can.client
instead of fromspray.can.host-connector.client
[9abbcf6].spray.can.client.ssl-encryption
is gone. Instead,Http.Connect
got a newsslEncryption
parameter replacing the global setting. [e922cd4].HostConnectorSetup
must now be created from hostname and port. Before it was created from anInetSocketAddress
which wasn’t enough to distinguish virtual hosts [a47f3b0].
Other changes:
keepOpenOnPeerClosed
is not supported for Http and was removed fromHttp.Register
[f6b0292].ClientConnectionSettings
andServerSettings
got a new membermaxEncryptionChunkSize
[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 tospray.can.server.response-header-size-hint
. The same forspray.can.client.request-size-hint
[ba1ae77].Content-Length.length
is now aLong
value. Alsospray.can.server.parsing.max-content-length
andincoming-auto-chunking-threshold-size
[b2fee8d].SetIdleTimeout
command now always resets the timeout [ab17f00].SslTlsSupport
pipeline stage now publishes aSSLSessionEstablished
event with session details [80982d4].- New
ParserSettings.sslSessionInfoHeader
setting which enables the automatic addition of a syntheticSSL-Session-Info
header to a request/response with SSL session information [e486900].ClientConnectionSettings.userAgentHeader
is now modelled directly by anOption[User-Agent]
. [da12531].
[ab17f00] | use util.Timestamp instead of longs for timeout checking |
[f6b0292] | get rid of Http.Register.keepOpenOnPeerClosed, fixes #401 |
[0b5ef36] | add max-encryption-chunk-size setting to ClientConnectionSettings and ServerSettings |
[98365ff] | Implement redirection following (issue #132) |
[d738e54] | require services to respond to ChunkedRequestStart with RegisterChunkHandler, fixes #473 |
[da29cdf] | “privatize” all classes/objects not meant to be part of public API |
[6fec00c] | only render default User-Agent if no such header was explicit given, fixes #462 |
[9193318] | break out ServerSettings timeout settings into sub case class, closes #489 |
[ba1ae77] | upgrade to new HttpEntity / HttpData model |
[b2fee8d] | make Content-Length a long value, fixes #443 |
[4b48875] | introduce dedicated exceptions for connection failure and request timeout for host-level API |
[9abbcf6] | when creating HostConnectorSettings expect client settings at spray.can.client, fixes #408 |
[e922cd4] | move client.ssl-encryption setting from reference.conf into Http.Connect message, fixes #396 |
[a47f3b0] | replace InetSocketAddress in HostConnectorSetup with hostname/port pair, fixes #394 |
[80982d4] | Publish SSLSessionEstablished event from SslTlsSupport upon successful SSL handshaking |
[e486900] | Add SSLSessionInfo header to requests on server and responses on client |
[da12531] | model user-agent-header value as User-Agent to fail fast, fixes #458 |
spray-http
Access-Control-Allow-Origin
andOrigin
header models now have members of newly introduced typeHttpOrigin
instead of the previousUri
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 valueQuery.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 asSeq
to be able to model duplicate fields [ad593d1].HttpMessage.entityAccepted
was renamed toHttpMessage.isEntityAccepted
[5d78dae].- Replacement of HttpBody by HttpData [c6f49cc].
- Many charsets in
HttpCharsets
are not any more available as static values. UseHttpCharset.getForKey("windows-1252")
to access a particular charset [f625b5a].Uri.Query.apply
andUri.Host.apply
have a newcharset
parameter [88a25f7].Uri.Query
has a new subtypeUri.Query.Raw
which will be generated when parsing with modeUri.ParsingMode.RelaxedWithRawQuery
[d8a9ee4].MediaRanges.custom
was renamed toMediaRange.custom
[a915b8f].HttpSuccess
andHttpFailure
are not public API any more. UseStatusCode.isSuccess
instead [a9e0d2c].HttpIp
was replaced byRemoteAddress
which also supports “unknown” addresses.X-Forwarded-For.ips
member was renamed toaddresses
.Remote-Address.ip
member was renamed to address [443b0d8].
[015f3c6] | add HttpOrigin and use it for Access-Control-Allow-Origin and Origin headers, fixes #579 |
[e058a43] | allow creation of custom MediaTypes with ‘*’ as a subtype when called by the parser, fixes #529 |
[d2b8bba] | introduce a distinction between ”?key=” and ”?key” in queries, fixes #460 |
[ad593d1] | make multipart form-data more flexible but have it adhere to the RFC more strictly |
[5d78dae] | add CONNECT method and support for custom HTTP methods, closes #428 |
[c6f49cc] | introduce HttpData model replacing the byte array in HttpBody and MessageChunk, closes #365 |
[f625b5a] | add small extensions to Uri model |
[88a25f7] | make only standard charsets available as constants, fixes #340 |
[a915b8f] | fix raw queries still performing %-decoding and not being rendered as raw, fixes #330 |
[d8a9ee4] | add support for Accept-Header extensions and media-type parameters, closes #310 |
[a9e0d2c] | support for custom status codes, fixes #564 |
[443b0d8] | remodel HttpIp to RemoteAddress, fixes #638 |
spray-routing
RequestContext.complete
overloads were removed in favor of using the marshalling infrastructure (see (Un)marshalling) [4d787dc].CompletionMagnet
is gone in favor of the newToResponseMarshaller
infrastructure [7a36de5].FieldDefMagnetAux
,ParamDefMagnetAux
, andAnyParamDefMagnetAux
are gone and replaced by a simpler construct [d86cb80].RequestContext.marshallingContext
is gone.produce
directive loses itsstatus
andheader
parameter which can be replaced by using an appropriateToResponseMarshaller
[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
andfileSystemPath
are now private [ab35761].decompressRequest
andcompressResponse
now always need parentheses. Also, encoding directives like thecompressResponse
automatically use theautoChunkFileBytes
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 ofdetach()
which always needs parentheses. The underlying implementation is now Future-based and needs an (implicit or explicit)ExecutionContext
orActorRefFactory
in scope [ead4a70].PathMatcher.(flat)Map
were renamed toPathMatcher.h(flat)Map
.map
andflatMap
were reintroduced forPathMatcher1
instances [8c91851].AuthenticationFailedRejection
andAuthenticationRequiredRejection
were merged and remodelled. [034779d]PathMatchers.Empty
was renamed toPathMatchers.Neutral
[ee7fe47].Slash_!
is gone andSlash
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 toCachedUserPassAuthenticator.apply
[1326046].PathMatcher.apply
now takes aPath
prefix instead of aString
[3ff3471].PathMatcher.Segments
doesn’t match trailing slashes anymore. Implicit infrastructure forPathMatcher.?
was changed [8ee49d7].pathEnd
and pathEndOrSingleSlash were introduced to replace the formerpath("")
(see PathMatcher infrastructure) [f0cbf25].
[4d787dc] | remove superfluous RequestContext::complete overloads |
[1480e73] | improve PathMatcher infrastructure |
[7a36de5] | CompletionMagnet: gone, streamlining completion API: accomplished |
[d86cb80] | remove layer of *Aux classes by type aliases for simplicity |
[b145ced] | upgrade to new ToResponseMarshaller, closes #293 |
[9c9b976] | AuthenticationFailedRejection now directly contains challenge headers to return, fixes #538 |
[ab35761] | fix getFromDirectory and getFromResourceDirectory not working properly for URIs with encoded chars |
[e3defb4] | have encodeResponse automatically tie in autoChunkFileBytes |
[9c11228] | small improvement of require and hrequire modifiers on directives |
[ead4a70] | Added detach directive which executes its inner route in a future. Removed detachTo directive. Fixes #240. |
[8c91851] | PathMatcher.(flat)map => h(flat)map, introduce map/flatMap, fixes #274 |
[034779d] | Render WWW-Authenticate header also for rejected credentials, fixes #188 |
[ee7fe47] | redefine PathMatchers.Empty as PathMatchers.Neutral with explicit type annotation, fixes #339 |
[1326046] | move UserPassAuthenticator.cached to CachedUserPassAuthenticator.apply, fixes #352 |
[3ff3471] | change PathMatcher.apply, add PathMatcher.provide method, cosmetic improvements |
[8ee49d7] | add PathMatcher::repeated modifier, closes #636 |
[f0cbf25] | add pathEnd and pathEndOrSingleSlash directive, closes #628 |
spray-httpx
(TODO)
[ae17d18] | create FormFile as an easy way to access uploaded file information for forms, fixes #327 |
[9d27559] | rename BodyPart.getName -> BodyPart.name, add BodyPart.dispositionParameterValue |
[fad2ff2] | polish MediaType model, fix tests, smaller improvements |
[f8f5b6d] | support content negotiation, fixes #167 |
[ebaa580] | enable FEOU and FSOD to be interchanged in the usual cases, fixes #426 |
[ebe3e97] | remove MetaUnmarshallers.scala, fold only member into FormDataUnmarshallers.scala |
[dd51be5] | change default charset for application/x-www-form-urlencoded to utf8, fixes #526 |
[f5b1535] | decode should remove Content-Encoding header from message |
[adf9170] | move unmarshal and unmarshalUnsafe to Unmarshaller and add unmarshaller method |
[f5997f8] | flexibilize RequestBuilding and ResponseTransformation by generalizing the ~> operator |
spray-io
(TODO)
[01c4aa9] | major refactoring of SslTlsSupport, fixes #544 |
[5f23219] | improve DynamicPipelines trait |
[76345ba] | abort connection on idle-timeout, fixes #539 |
[2c77d8f] | add support for compound write commands (Tcp.CompoundWrite) |
spray-testkit
(TODO)
[6a99cb7] | move result.awaitResult call from injectIntoRoute into check, fixes #205 |
[72c9397] | in RouteTests always convert URIs into absolute ones, fixes #464 |
[680fde0] | enable custom ExceptionHandlers in routing tests |
[3b4ac55] | small clean-up, remove duplication with httpx RequestBuilding |