46

I see lots of information about enabling http compression for server responses but what about for incoming requests. Wouldn't it make sense for the browsers to compress large form posts before sending them to the server?

Another example is a REST web service that we use. We have to send frequent PUT requests with large XML files (10+ MB) and would definitely see some bandwidth/speed benefits on both sides.

So is this a solved problem on the server side or does each web application have to handle it individually?

Mike L
  • 669
  • 1
  • 6
  • 11

5 Answers5

36

To PUT data to the server compressed you must compress the request body and set the Content-Encoding: gzip header. The header itself must be uncompressed. It's documented in mod_deflate:

The mod_deflate module also provides a filter for decompressing a gzip compressed request body. In order to activate this feature you have to insert the DEFLATE filter into the input filter chain using SetInputFilter or AddInputFilter.

...

Now if a request contains a Content-Encoding: gzip header, the body will be automatically decompressed. Few browsers have the ability to gzip request bodies. However, some special applications actually do support request compression, for instance some WebDAV clients.

And an article describing it is here:

So how do you do it? Here is a blurb, again from the mod_deflate source code: only work on main request/no subrequests. This means that the whole body of the request must be gzip compressed if we chose to use this, it is not possible to compress only the part containing the file for example in a multipart request.

Separately, a browser can request server response content to be compressed by setting Accept-Encoding header as per here:

GET /index.html HTTP/1.1
Host: www.http-compression.com
Accept-Encoding: gzip
User-Agent: Firefox/1.0

This will return compressed data to the browser.

Andy
  • 5,190
  • 23
  • 34
  • 5
    +1 N.B. You write `you must compress the whole request, inclusive of header`. However, the **http headers must not be compressed**. The only thing that has to be compressed (in full, as the article you quote correctly states), is the http body. – Evgeniy Berezovsky Apr 08 '14 at 06:22
  • 1
    This is wrong: `Accept-Encoding` tells the server, what compression the client supports. The header `Content-Encoding` describes the compression of the body. – maaartinus Aug 12 '14 at 15:46
  • @maaartinus see first quote second paragraph. I've reorganised the answer for clarity. – Andy Aug 13 '14 at 10:15
  • "Separately, a browser can request server response content to be compressed" - that's not quite right, in the sense that the server is free to send an uncompressed body (unless `identity;q=0` is also sent). https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding – jberryman Sep 15 '22 at 16:22
4

Answering the part about compressed requests, not responses: yes, it is possible, even if it does not seem in widespread usage. The client-side app needs to set the appropriate content-encoding header. As for the server-side app, there are 2 choices:

  1. the app supports reinflating the request body by itself. An example library which can do this is the phpxmlrpc one.

  2. the webserver inflates the response body before passing it to the app. This is possible using f.e. the mod_deflate filter of Apache and setting up an inputFilter

longneck
  • 22,793
  • 4
  • 50
  • 84
gggeek
  • 41
  • 1
2

Not natively from any browser I know of, you'd have to find a plugin that would do it for you. You basically have to set the content-encoding HTTP header to let the server know how the request is coming in. The server, of course, needs to be able to handle that encoding.

squillman
  • 37,618
  • 10
  • 90
  • 145
0

Below code is setup the custom header and pass this header in api call as http options :

getCustomHeaders() {
    return new HttpHeaders({
      'Accept-Encoding': 'gzip, deflate'
    });
}

After that while you calling the API to get the data , pass the options with url:

searchData(title: string, type: SearchType): Observable<any> {
    const headersSpl = this.getCustomHeaders();
    const httpOptions = {
      headers : headersSpl
    };
    const url = `${this.url}?s=${encodeURI(title)}&type=${type}&apiKey=${this.apiKey}`;
    return this.httpClient.get(url, httpOptions)
    .pipe(
      map( results => results['data']),
      catchError( error => { console.log(error); return EMPTY })
    )
  }
-2

This is NOT allowed. According to the HTTP specification (RFC 2616), Content-Encoding is NOT one of the possible request header fields, therefore it is not possible to compress the request entity body as there is no legal way to let the server know this has occurred. Any compression of the request body is done only as a non-standard extension.

Steve
  • 21
  • 1
  • 13
    This answer is wrong [RFC 2616](https://tools.ietf.org/html/rfc2616#page-118) specifically mentions that `If the content-coding of an entity in a request message is not acceptable to the origin server, the server SHOULD respond with a status code of 415 (Unsupported Media Type).` furthermore indicated by `Request and Response messages MAY transfer an entity if not otherwise restricted by the request method` and `Content-Encoding` being listed as a option in `entity-header` – PeterT Jan 17 '17 at 10:00