1
votes

I'm using Guzzle 5.3 via Guzzle Services (via https://github.com/ticketevolution/ticketevolution-php) to attempt to POST to an API endpoint with a JSON body that includes a PDF encoded as base64. When the body is less than ~1MB it works fine. When the body is larger it seems that the body is never sent.

I have tested this with and without the Expect: 100 header and it does not seem to make a difference.

I have tested with Transfer-Encoding: chunked, but because the API needs the entire POST body in order to authenticate using chunked does not work.

We have tested with and without the load balance between the client and the appservers.

From everything we can tell the body just doesn't get sent when it is larger than ~1MB.

Does anyone have any ideas on how to get Guzzle 5.3 to send the body even when it is larger than 1MB?

Below is the log output

[2015-09-01 16:15:43] TEvoAPIClientLogger.CRITICAL: 
>>>>>>>> 
POST /v9/orders/2100732/deliver_etickets HTTP/1.1 
Host: api.ticketevolution.com 
User-Agent: ticketevolution-php/3.0.0dev Guzzle/5.3.0 curl/7.44.0 PHP/5.5.28 
Content-Type: application/json 
Content-Length: 1387036 
X-Token: b47dsd8c0ab80a1e2bc24sc341415a2f 
X-Signature: SwBOkdUOqG3SDtjVwi2etosdP+gppwuV5dCq8yMw9lM=  


{"etickets":[{"item_id":1513651,"eticket":"JVBERi0xLjQKJeLjz9MKNCAwIG9iaiBbXQplb… [a whole lot of base64 snipped] …NwolJUVPRgo="}]}
<<<<<<<<  -------- 
cURL error 52: Empty reply from server
1

1 Answers

3
votes

Running into the same problem, a bit of debugging resulted in ending up at GuzzleHttp\Ring\Client\CurlFactory::applyBody(), and then this fixed the problem for me:

Setting a default configuration on the client

$client = new \GuzzleHttp\Client([
    'defaults' => [
        'config' => [
            'curl' => [
                'body_as_string' => true,
            ],
        ],
    ],
]);

Setting the configuration when issuing the request

$client->post('https://example.com', [
    'json' => $json,
    'config' => [
        'curl' => [
            'body_as_string' => true,
        ],
    ],
]);

Rewinding the previously fetched actual content stream

Since I'm fetching content from a remote server, this article by Matt Downling helped me in finding out that I need to rewind the actual stream before using it as a part of the multipart/form-data request:

$response->getBody()->seek(0);