Files
ms1inscription-v5/php/chronotrack_api/fx_chronotrack_http.php

156 lines
5.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* MSIN API ChronoTrack — client HTTP bas niveau (cURL).
*/
function fxChronotrackApiHttpRequest($strMethod, $strUrl, $arrOptions = array()) {
$intMaxAttempts = max(1, intval($arrOptions['retries'] ?? 1));
// MSIN-4574 — 502/503/429 = surcharge CT ou proxy : backoff, pas abandon immédiat
$tabRetryCodes = array(429, 502, 503, 504);
$arrLast = null;
for ($intAttempt = 1; $intAttempt <= $intMaxAttempts; $intAttempt++) {
$arrLast = fxChronotrackApiHttpRequestOnce($strMethod, $strUrl, $arrOptions);
if (($arrLast['state'] ?? '') === 'ok') {
$arrLast['attempts'] = $intAttempt;
return $arrLast;
}
$intCode = intval($arrLast['http_code'] ?? 0);
$blnRetry = ($intAttempt < $intMaxAttempts) && (
in_array($intCode, $tabRetryCodes, true)
|| (!empty($arrLast['curl_error']) && (
stripos((string)$arrLast['curl_error'], 'timed out') !== false
|| stripos((string)$arrLast['curl_error'], 'reset') !== false
))
);
if (!$blnRetry) {
$arrLast['attempts'] = $intAttempt;
return $arrLast;
}
// Backoff : 1s, 2s, 4s…
usleep((int)(1000000 * pow(2, $intAttempt - 1)));
}
if (is_array($arrLast)) {
$arrLast['attempts'] = $intMaxAttempts;
}
return $arrLast;
}
/**
* Une seule tentative cURL (sans retry).
*/
function fxChronotrackApiHttpRequestOnce($strMethod, $strUrl, $arrOptions = array()) {
$arrResult = array(
'state' => 'error',
'http_code' => 0,
'body' => '',
'json' => null,
'curl_error' => '',
);
if (!function_exists('curl_init')) {
$arrResult['curl_error'] = 'cURL indisponible';
return $arrResult;
}
$ch = curl_init();
$arrHeaders = isset($arrOptions['headers']) && is_array($arrOptions['headers']) ? $arrOptions['headers'] : array();
$intTimeout = max(30, intval($arrOptions['timeout'] ?? 90));
curl_setopt($ch, CURLOPT_URL, $strUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_TIMEOUT, $intTimeout);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $arrHeaders);
$strMethod = strtoupper(trim($strMethod));
if ($strMethod === 'GET') {
curl_setopt($ch, CURLOPT_HTTPGET, true);
} else {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $strMethod);
if (isset($arrOptions['body'])) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $arrOptions['body']);
} elseif ($strMethod === 'POST') {
curl_setopt($ch, CURLOPT_POSTFIELDS, '');
}
}
if (!empty($arrOptions['basic_user']) || !empty($arrOptions['basic_pass'])) {
curl_setopt($ch, CURLOPT_USERPWD, $arrOptions['basic_user'] . ':' . $arrOptions['basic_pass']);
}
$strBody = curl_exec($ch);
$arrResult['http_code'] = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($strBody === false) {
$arrResult['curl_error'] = curl_error($ch);
} else {
$arrResult['body'] = $strBody;
$tabJson = json_decode($strBody, true);
if (is_array($tabJson)) {
$arrResult['json'] = $tabJson;
}
}
curl_close($ch);
if ($arrResult['curl_error'] !== '') {
return $arrResult;
}
if ($arrResult['http_code'] >= 200 && $arrResult['http_code'] < 300) {
$arrResult['state'] = 'ok';
}
return $arrResult;
}
function fxChronotrackApiHttpGetJsonErrorMessage($arrHttp) {
if (!empty($arrHttp['curl_error'])) {
return $arrHttp['curl_error'];
}
$arrParts = array();
if (is_array($arrHttp['json'])) {
foreach (array('errorMessage', 'message', 'error_description', 'errorCode', 'error') as $strKey) {
if (empty($arrHttp['json'][$strKey])) {
continue;
}
// MSIN-4574 — restauré : CT renvoie souvent error = string OU liste dobjets
if ($strKey === 'error' && is_array($arrHttp['json']['error'])) {
foreach ($arrHttp['json']['error'] as $mixErr) {
if (is_string($mixErr) && trim($mixErr) !== '') {
$arrParts[] = $mixErr;
} elseif (is_array($mixErr)) {
if (!empty($mixErr['errorMessage'])) {
$arrParts[] = (string)$mixErr['errorMessage'];
} elseif (!empty($mixErr['message'])) {
$arrParts[] = (string)$mixErr['message'];
}
}
}
continue;
}
if (is_string($arrHttp['json'][$strKey]) || is_numeric($arrHttp['json'][$strKey])) {
$arrParts[] = (string)$arrHttp['json'][$strKey];
}
}
}
$strBody = trim((string)($arrHttp['body'] ?? ''));
if (count($arrParts) > 0) {
return 'HTTP ' . intval($arrHttp['http_code']) . ' — ' . implode(' | ', array_unique($arrParts));
}
if ($strBody !== '') {
// Page HTML 503 CT / proxy
if (stripos($strBody, '503') !== false || stripos($strBody, 'Service Unavailable') !== false) {
return 'HTTP ' . intval($arrHttp['http_code'])
. ' — Service Unavailable (surcharge CT/proxy — lot trop gros ou trop rapide)';
}
return 'HTTP ' . intval($arrHttp['http_code']) . ' — ' . substr($strBody, 0, 400);
}
return 'HTTP ' . intval($arrHttp['http_code']);
}