Here is my situation :
I'm trying to use a S3-compatible API, called from a PHP script. (Ionos : documentation here)
I want to do some API requests to get files from the S3 and buckets informations.
My working environment is :
- WAMP server 3.3.1 on a Windows 10 localhost
- cURL Version: 7.70.0
- SSL Version: OpenSSL/1.1.1s
- PHP 7.4.33
(I don't know what other configuration is relevant for this situation)
My problem is :
When I do a request to the API (e.g. a basic GET request which is supposed to return some XML with buckets informations), I sometimes get the correct response and most of the time get the following exception :
cURL error 35: OpenSSL SSL_connect: Connection was reset in connection to s3.eu-central-3.ionoscloud.com:443 (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for https://s3.eu-central-3.ionoscloud.com
Each time I refresh the page, it's either ok or not.
What I already tried :
I tried different methods in order to isolate the problem, find where this exception comes from and try to identify some pattern in randomness.
Method 0 : through Postman as a POC of the API :
I configured Postman with the AWS signature : no problem, it works 100% of the time, so I imagine that the problem doesn't come from the API itself.
1rst method : Through Guzzle
use Aws\Credentials\Credentials;
use Aws\Signature\SignatureV4;
use Psr\Http\Message\RequestInterface;
/**
* Function for signing the request created by Guzzle
*
* @param RequestInterface $request
* @param string $accessKeyId
* @param string $secretAccessKey
* @return RequestInterface
*/
function sign(RequestInterface $request, string $accessKeyId, string $secretAccessKey): RequestInterface
{
$signature = new SignatureV4('s3', 'eu-central-3');
$credentials = new Credentials($accessKeyId, $secretAccessKey);
return $signature->signRequest($request, $credentials);
}
// API Call informations
$url = "https://s3.eu-central-3.ionoscloud.com";
$public_key = 'my_public_key';
$secret_key = 'my_secret_key';
$request = new GuzzleHttp\Psr7\Request(
'GET',
$url,
[
'X-Amz-Content-Sha256' => hash('sha256', ''),
'Accept' => '*/*',
'Accept-Encoding' => 'gzip, deflate, br',
'User-Agent' => $_SERVER['HTTP_USER_AGENT'],
]
);
$signed_request = sign($request, $public_key, $secret_key);
$client = new \GuzzleHttp\Client();
try {
$response = $client->send($signed_request);
// XML response (if everything goes fine)
$body = $response->getBody();
$xml = simplexml_load_string($body);
if ($xml === false) {
echo 'XML parsing error :';
foreach(libxml_get_errors() as $error) {
echo "\t", $error->message;
}
} else {
echo '<pre>';
print_r($xml);
echo '</pre>';
}
}
catch (Exception $exception) {
echo $exception;
}
2nd method : Through the AWS PHP SDK
use Aws\Credentials\Credentials;
use Aws\Signature\SignatureV4;
use Psr\Http\Message\RequestInterface;
use Aws\Exception\AwsException;
use Aws\S3\S3Client;
// API Call informations
$url = "https://s3.eu-central-3.ionoscloud.com";
$public_key = 'my_public_key';
$secret_key = 'my_secret_key';
$s3Client = S3Client::factory([
'endpoint' => 'https://s3.eu-central-3.ionoscloud.com',
'credentials' => [
'key' => $public_key,
'secret' => $secret_key,
],
'region' => 'eu-central-3',
'version' => 'latest',
]);
try {
$contents = $s3Client->listObjectsV2([
'Bucket' => 'my-bucket-name',
]);
echo "The contents of your bucket are: \n";
foreach ($contents['Contents'] as $content) {
echo $content['Key'] . "\n";
}
} catch (Exception $exception) {
echo "Failed to list objects with error: " . $exception->getMessage();
}
Result :
For methods 1 & 2 I get the same random error 35 (although the success ratio seems slightly better with the AWS SDK, but it might just be a coincidence).
I also tried on differents LAN to see if the problem comes from my firewall or something :
on localhost on a LAN A (e.g. at home) : random error 35
on localhost on a LAN B (e.g. at office) : seems to work normally
on the prod server : seems to work normally (server config : Debian 11, cURL Version: 7.74.0, SSL Version: OpenSSL/1.1.1w, PHP 7.4.33)
Although it's working correctly on some LANs & on the prod server, the randomness is worrying me :
since I don't know what causes the problem, I'm not sure this won't happen in the future on prod server because of I-don't-know,
it's difficult to work properly on localhost if I have constantly a random exception
if the problem is due to the LAN configuration, why does it works correctly on Postman ?
I'm out of ideas now, I don't even know what kind of error could be random, I don't know what to test anymore.
I would be grateful if you could help me or at least give me some food for thought.
Thank you very much !