Encoding Decoding

Johannes Rudolph edited this page Aug 14, 2013 · 7 revisions

. . . Deprecation Note

This documentation is for release 0.9.0 (from 03/2012), which is built against Scala 2.9.1 and Akka 1.3.1 (see Requirements for more information). Most likely, this is not the place you want to look for information. Please turn to the main spray site at http://spray.io for more information about other available versions.

. . .

HTTP defines several "encodings" for request and response entity bodies. Most importantly these encodings are used for compression and decompression of larger content with one of several common compression algorithms.

Even though the web server / servlet container that you deploy your spray application in might support request decompression and/or response compression as well, an implementation at the spray routing level gives you much more flexibility and control over when and how to employ encodings.

spray defines two directives for working with HTTP encodings: decodeRequest and encodeResponse. Both take one argument of type Decoder or Encoder respectively and transparently apply the codec logic to the incoming request or the outgoing response.

spray comes with codec implementations for the three most common HTTP encodings: NoEncoding, Gzip and Deflate.

Note that encodeResponse transparently applies its logic not only to "regular" responses but also to streamed responses being started from anywhere in its inner route. You can find more information about this in the chapter about Streaming.

Encoding Errors

If the decodeRequest directive is confronted with a request that doesn't match the expected encoding the request is rejected with an UnsupportedRequestEncodingRejection. If no subsequent route successfully handles the request the client will receive a 400 Bad Request error response with an informational text listing the supported encodings. If there is an error while decoding the request content the request is rejected with a CorruptRequestEncodingRejection which, by default, also triggers a 400 Bad Request error response.

If the encodeResponse directive is confronted with a request that has an Accept-Encoding header which doesn't match the respective encoding the request is rejected with an UnacceptedResponseEncodingRejection. If no subsequent route successfully handles the request the client will receive a 406 Not Acceptable error response with an informational text listing the supported encodings.

Examples

Only accept GZIP encoded requests:

decodeRequest(Gzip) {
  ... // the inner routes will only "see" decoded requests
}

Accept GZIP encoded requests or requests without encoding:

(decodeRequest(Gzip) | decodeRequest(NoEncoding)) {
  ... // the inner routes will only "see" decoded requests
}

Support GZIP, DEFLATE or unencoded responses:

(encodeResponse(Gzip) | encodeResponse(Deflate) | encodeResponse(NoEncoding)) {
  ...
}

Note that the order of the directives determines what should happen if the client accepts several encodings (e.g. because it didn't include an explicit Accept-Encoding header. The first matching encoding "wins".