1
votes

I have to make a HTTP call to send data compressed data. I'm developing in Symfony2. For HTTP calls I'm using Guzzle client (version 3.8.1). Also, I am using Guzzle Service Descriptions to decribe the operations allowed on each command.

I know that I have to add the header "Content-Encoding: gzip" in the request, but the request body is not compressed.

Is there a way to specify in the Guzzle client that the request needs to be compressed? (maybe specify this in the Service Description)

Thank you!

2

2 Answers

3
votes

To tell the server to give you compressed version, you have to inform it that you understand how to decompress the data.

For that purpose, you send a header during request which is called Accept-Encoding.

Example of accept-encoding header and values (those are the compression schemes that your client knows to use):

accept-encoding:gzip, deflate, sdch, br

The RESPONSE header Content-Encoding is sent by the server. IF that header is set, then your client asserts that the content is compressed and uses the algorithm that the server sent as value of Content-Encoding.

The server doesn't have to respond with compressed page.

Therefore, these are the steps:

  1. Tell the server you know how to deal with compressed pages. You send accept-encoding header and then you specify which compression algorithms your client knows how to deal with.

  2. Inspect whether the server sent Content-Encoding header. If not, content isn't compressed

  3. If yes, check the value of the header. That tells you which algorithm was used for compression, it doesn't have to be gzip, but usually is.

  4. The server doesn't have to respond with compressed page. You are merely informing the server you understand how to deal with compressed pages.

So, for you, what you should do is verify that your server sends gzipped responses and then you should set the request header accept-encoding. You got it the wrong way around.

1
votes

I found a solution to send data compressed using Guzzle client with Operation Command and Service Description.

In the JSON file containing the service description I have specified that data sent in body is a string:

{
  ...
  "operations": {
    "sendCompressedData": {
      "httpMethod": "POST",
      "uri": ...,
      "parameters": {
        "Content-Type": {
          "location": "header",
          "required": true,
          "type": "string",
          "default": "application/json"
        },
        "Content-Encoding": {
          "location": "header",
          "required": true,
          "type": "string",
          "default": "gzip"
        },
        "data": {
          "location": "body",
          "required": true,
          "type": "string"
        }
      }
    }
  }
}  

As mentioned by @Mjh, Guzzle doesn't compress data automatically if "Content-Encoding" header is set, so data needs to be compressed before sending it to the Guzzle client to execute the command. I have serialized the object and used "gzencode($string)" for compressions.

$serializedData = SerializerBuilder::create()->build()->serialize($request, 'json');
$compressedData = gzencode($serializedData);
...
$command = $this->client->getCommand('sendCompressedData', array('data' => $compressedData));
$result = $command->execute();