When using an http encoding, a good way to enable the compression of responses (only) is by using the dynamic compression built-in to IIS7 and higher.
but I don't get how the client knows to compress the requests and to decompress the response?
What follows is a description of what HTTP offers out of the box, which can be used together with the WCF HTTP(S) encodings. In addition to that, WCF 4.5 provides gzip and deflate compression of its binary encoding.
Compressed responses are part of the HTTP standard. In its request, the client signals to the server which compression methods (gzip, deflate, ...) it supports by means of the following header:
Accept-Encoding: gzip, deflate
The server, in its sole discretion, infinite wisdom and mysterious ways, is free to ignore that header and send the response uncompressed, or it may choose any one of the algorithms offered by the client, answering, say, with the following header and compress the response body.
Content-Encoding: gzip
To make matters more complicated, the server will probably also set the following header:
Transfer-Encoding: chunked
This allows the server to omit the otherwise mandatory Content-Length
header that, as HTTP headers in general, has to precede the HTTP body. (Setting the chunked
encoding affects the way the body gets encoded.) So now it can compress the response body on-the-fly, i.e. spitting out bytes as they are compressed, without having to wait for the compression of the whole body to finish, just to be able to determine the content length of the compressed result. This can save a lot of memory on the server side. (The client side, however, is now left in the dark as to the total size of the compressed response, until it finished receiving the whole response, making it's decompression slightly less efficient)
Note however that using Accept-Encoding
and Content-Encoding
, as I just described, to transparently compress responses was actually a stupid idea, according to http co-author Roy Fielding and what should have been used instead is the following header in the request:
TE: gzip, deflate
And the server, if it chooses to perform compression, would add the following header to its response:
Transfer-Encoding: gzip, chunked
As before, chunked
is necessary if the server wants to omit the Content-Length
.
Otherwise, the TE
/Transfer-Encoding
combo is syntactically identical to the Accept-Encoding
/Content-Encoding
combo, but the meaning is different, as can be gleaned from this longish discussion.
The gist of the problem: TE/Transfer-Encoding makes compression a transportation detail, whereas Accept-Encoding/Content-Encoding denotes the compressed version as the actual data (entity in HTTP parlance), with a number of unfortunate ramifications regarding caching of requests, proxy-ing, etc. of the latter.
However, the TE/Transfer-Encoding ship sailed long time ago, and we are stuck with the AE/CE combo, which is supported by most clients and servers with a meaning that is in actuality closer to that of TE/TE
When it comes to compressed requests in HTTP, they are rarely used in practice, and there is no standard way for the client to figure out if a server supports it. Either you tell the client out-of-band (e.g. hard-coding) that the server understands compressed requests (and configure the server appropriately). Or you have your client proactively try compression once, and if it yields a 400 Bad Request
(at least that's what an IIS 7.5 would return), you fall back to non-compressed requests.