0

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 !

0

Browse other questions tagged or ask your own question.