myFMbutler/myFMApiLibrary-for-PHP

cURL issues with PHP7

Opened this issue · 3 comments

I have run into an issue with the cURL requests when running version 1.1.0 under PHP 7.3.

When calling login(), CurlClient does not set a request body and sets the header Content-Length: 0. The problem is that when there's no request body, PHP7 (or the cURL lib itself) will add the header Transfer-Encoding: chunked. From my reading, it looks like Content-Length is supposed to be omitted when using chunked encoding.

The combination of Content-Length and chunked encoding headers seems to cause the FM Data API endpoint to return an HTTP 502 error.

I tried a few different things. The simplest that got it to work was commenting out the line that sets the Content-Length header:

$options['headers']['Content-Length'] = $contentLength;

I also experimented with setting the body as {} as the FileMaker docs describe (though it does not seem to be required; login requests with no body do work) and removing the same line above. cURL correctly calculated and added the Content-Length header automatically.

Original, faulty headers that result in HTTP 502:

POST /endpoint
Host: hostname
Accept: */*
Transfer-Encoding: chunked
Authorization: Basic [credential]
Content-Type: application/json
Content-Length: 0

Removing the line above generates these headers, which work:

POST /endpoint
Host: hostname
Accept: */*
Transfer-Encoding: chunked
Authorization: Basic [credential]
Content-Type: application/json

Or, removing that line above and adding an else condition that defaults the body to empty JSON...

} else {
    curl_setopt($ch, CURLOPT_POSTFIELDS, '{}');
}

...generates these headers which also work:

POST /endpoint
Host: hostname
Accept: */*
Authorization: Basic [credential]
Content-Type: application/json
Content-Length: 2

I lean towards the second one to be in line with the FileMaker docs, though I'm not sure if that causes issues with earlier PHP / cURL lib versions, especially since it looks like you're still supporting PHP 5.6.

Bumping to make sure this was seen. cc @lguilbert

This local fix appears to be working and I think is less hacky than my earlier suggestions:

At line 71, added:

/**
 * Workaround for HTTP 502 issue on login, when body is empty.
 * Set body to empty {}
 * @see https://help.claris.com/en/data-api-guide/#connect-database_log-in
 * @see https://github.com/myFMbutler/myFMApiLibrary-for-PHP/issues/11
 */
if ($method === 'POST' && isset($options['json']) && empty($options['json'])) {
    curl_setopt($ch, CURLOPT_POSTFIELDS, '{}');
    $contentLength = false;
}

Hi.

Thanks for the review but: I'm no longer a part of Lesterius anymore; my access is closed. I'm not able to accept/declined this and I don't think this will happen from someone else.

I did a fork for myself. I added your fix here lguilbert@dbecfec

Or you could do your own Fork too. Have a nice day.