back to all blogsSee all blog posts

Faster responses with HTTP response compression on Open Liberty

image of author
Manuel Saldana on Apr 22, 2020
Post available in languages:

You can now configure Open Liberty (20.0.0.4+) to compress HTTP responses. Compressing the sizes of HTTP responses reduces bandwidth which, in turn, decreases the time taken for HTTP clients to get responses. Open Liberty first determines whether the response should be compressed then, if so, checks whether there is an encoding algorithm to perform the compression that is supported by the HTTP client.

Determining whether a response should be compressed

When Open Liberty is configured to compress HTTP responses, it first determines whether it should compress a response by checking the headers in the response:

Content-Encoding header

If the response is not already encoded, it will be considered for compression. If the response is already encoded, no further attempts are made to encode the body.

Content-Length header

If the body of the response is 2048 bytes or larger, it can be compressed. If it is smaller than 2048 bytes, it is too small to benefit from compression and no attempt will be made to compress it.

Content-Type header

If the type of content in the response body is in the list of types configured in the Open Liberty server as being valid candidates for compression, it can be compressed. Otherwise, no attempt will be made to compress it.

If Open Liberty determines that the response should be compressed, it then verifies whether there is an acceptable algorithm available to compress it.

Verifying whether a response can be compressed

The Open Liberty server can use the gzip, x-gzip, deflate, zlib, or identity encoding algorithms to compress responses before returning them to the HTTP client that made the request. However, an HTTP client does not necessarily support all these encoding algorithms, so the client can indicate which algorithms it supports and even which algorithm it prefers to be used.

Open Liberty chooses which algorithm to use according to the following criteria, which it evaluates in order until an encoding algorithm is identified that is supported by both the HTTP client and the Open Liberty server:

  1. The value of the $WSZIP private header

    The value for this header in the response indicates the desired encoding algorithm.

  2. The server’s preferred algorithm

    A preferred algorithm can be configured in the Open Liberty server using the serverPreferredAlgorithm attribute. The value indicated by this attribute is used as long as the Accept-Encoding header in the HTTP request indicates that this algorithm is supported by the client, regardless of whether the client has indicated in the Accept-Encoding header that it prefers other algorithms more.

  3. The HTTP client’s preferred algorithm

    The HTTP client can indicate which algorithms are supported and its preferred algorithms in the Accept-Encoding header of the HTTP request. The Accept-Encoding header specifies which algorithms the HTTP client supports or does not support, and can also indicate order of preference (its quality; from 0.000 - 1.000, where 0.000 means the algorithm is not supported by the client) for each encoding algorithm.

    The encoding algorithms listed in the Accept-Encoding header are sorted in descending order by the server and each value is evaluated until a valid encoding is found. The highest ranked valid algorithm is chosen. If the gzip algorithm is tied among the highest ranked, it is chosen as the algorithm to use. If there are no explicitly named encoding algorithms, and an asterisk (*) is used, gzip is used if possible. If gzip cannot be used, deflate is used. If both are declared as unsupported by means of a quality value of 0.000, no content encoding algorithm is chosen.

    For example, assuming the $WSZIP header and the server’s preferred algorithm are not specified:

    • The HTTP client can specify the preferred encoding algorithm as gzip by giving it the highest quality value:

      Accept-Encoding: deflate;q=0.5, gzip;q=1.0
    • The HTTP client can specify multiple encoding algorithms with the highest quality value. In such cases, the server picks the gzip algorithm if possible:

      Accept-Encoding: deflate;q=1.0, gzip;q=1.0
    • The HTTP client may also indicate all encodings are supported. As the gzip algorithm is supported, the server chooses it:

      Accept-Encoding: *
    • The HTTP client can specify the gzip algorithm is not supported. In this case, the deflate algorithm is used instead.

      Accept-Encoding: gzip;q=0, *
    • The HTTP client can specify it does not support either the gzip or deflate algorithms. In this case, no compression algorithm will be chosen.

      Accept-Encoding: gzip;q=0, deflate;q=0, *

If an appropriate encoding algorithm is not found, or if the encoding algorithm is identity, no compression is attempted.

Additionally, as the Accept-Encoding header influences the Open Liberty’s process for selecting and representing the response, a Vary header with the value of Accept-Encoding is also added to the response. This header informs cache intermediaries that this response’s content may change in a subsequent request if the Accept-Encoding header changes. The header is added regardless of whether the response is ultimately compressed or not, as long as compression is configured in the server.xml.

Try it out

To use HTTP response compression, configure the server.xml with a new element called <compression>. You can configure compression for individual HTTP endpoints or for all endpoints at once. See Compression Options (compression) for more details of the attributes.

Configuring compression for individual HTTP endpoints:

<httpEndpoint id="defaultHttpEndpoint"
                        httpPort="9080"
                        httpsPort="9443">
    <compression serverPreferredAlgorithm="deflate|gzip|x-gzip|zlib|identity|none">
          <types>+application/*</types>
          <types>-text/plain</types>
    </compression>
</httpEndpoint>

Configuring compression for all HTTP endpoints:

    <httpEndpoint id="defaultHttpEndpoint"
                        httpPort="9080"
                        httpsPort="9443"
                        compressionRef="myCompressionID">
    </httpEndpoint>

    <httpEndpoint id="otherHttpEndpoint"
                        httpPort="9081"
                        httpsPort="9444"
                        compressionRef="myCompressionID">
    </httpEndpoint>

    <compression id="myCompressionID" serverPreferredAlgorithm="deflate|gzip|x-gzip|zlib|identity|none">
              <types>+application/*</types>
              <types>-text/plain</types>
    </compression>

The types attribute in the examples adds all application content types and removes the text/plain content type from the text/* default.

With this new <compression> configuration option, you can configure Open Liberty to compress HTTP responses before returning them to clients. This reduces bandwidth and the time taken for HTTP clients to get responses.