]> _ Git - cubist_net.git/commitdiff
wait #7819 @1
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Thu, 20 Nov 2025 12:48:23 +0000 (13:48 +0100)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Thu, 20 Nov 2025 12:48:23 +0000 (13:48 +0100)
composer.json
src/HTTP.php

index 4995098f8a6fb6cea6f44d52c91096a1dca125dd..05faa31070d8300b43dda057f8bd09dfd96947db 100644 (file)
@@ -26,7 +26,7 @@
         "ext-ssh2": "*",
         "cubist/util": "dev-master",
         "ext-ftp": "*",
-        "aws/aws-sdk-php": "^3.325",
+        "aws/aws-sdk-php": "^3.343",
         "google/cloud-storage": "*",
         "ext-json": "*",
         "ext-curl": "*"
index d97234c94d9e485cb6dd45de2845bf1137804ed8..2fb460e32ce08a36dca1f4d37d40f9be340d5878 100644 (file)
 
 namespace Cubist\Net;
 
+
+use GuzzleHttp\Client;
+use GuzzleHttp\Cookie\FileCookieJar;
+use GuzzleHttp\Cookie\SetCookie;
+
 class HTTP
 {
+    protected static $_redirectionCodes = [301, 302, 307, 308];
+    /** @var FileCookieJar */
+    protected static $_cookiesJar = null;
+    protected static $_cookiesFile = null;
+
+    public static function setCookieFile($file)
+    {
+        self::$_cookiesFile = $file;
+        self::$_cookiesJar = new FileCookieJar($file, TRUE);
+    }
+
+    public static function getResponseCode($url, $timeout = 30, $flaresolverr = null): array
+    {
+        $res = [];
+
+        try {
+            $response = self::_request($url, $timeout);
+            if ($response->getHeader('X-Guzzle-Redirect-Status-History')) {
+                $codes = $response->getHeader('X-Guzzle-Redirect-Status-History');
+                $urls = $response->getHeader('X-Guzzle-Redirect-History');
+                $res['http_code'] = array_pop($codes);
+                $res['target_code'] = $response->getStatusCode();
+                $res['target_url'] = array_pop($urls);
+            } else {
+                $res['http_code'] = $response->getStatusCode();
+            }
+
+        } catch (\Exception $e) {
+            $res['http_code'] = self::handleException($e);
+        }
+
+        $flaresolverrCodes = [401, 403, 622];
+
+        if ($flaresolverr && in_array($res['http_code'], $flaresolverrCodes) /*&& in_array('cloudflare', $response->getHeader('Server'))*/) {
+            try {
+                $cloudflareRes = self::getHttpCodeCloudflare($url, $flaresolverr, $timeout);
+                if ($cloudflareRes) {
+                    $res = $cloudflareRes;
+                }
+            } catch (\Exception $e) {
+                $res['http_code'] = self::handleException($e);
+                if ($res['http_code'] === 622) {
+                    $res['http_code'] = 628;
+                }
+            }
+        }
+
+        if (self::$_cookiesJar) {
+            self::$_cookiesJar->save(self::$_cookiesFile);
+        }
+
+        return $res;
+    }
+
+    public static function handleException(\Throwable $e): int
+    {
+        $map = ['GuzzleHttp\Exception\ConnectException' => 622,
+            'GuzzleHttp\Psr7\Exception\MalformedUriException' => 629];
+        $messageMap = ['Undefined array key "solution"' => 603];
+        $startMap = ['cURL error 60: SSL: no alternative certificate subject name matches target host name' => 695];
+
+        $exceptionClass = get_class($e);
+        $message = $e->getMessage();
+
+        if (isset($map[$exceptionClass])) {
+            return $map[$exceptionClass];
+        } elseif (isset($messageMap[$message])) {
+            return $messageMap[$message];
+        } else {
+            foreach ($startMap as $str => $code) {
+                if (str_starts_with($message, $str)) {
+                    return $code;
+                }
+            }
+            dd($exceptionClass, $message);
+        }
+    }
+
     /**
-     * @param string $url
-     * @param string|null $flaresolverr
-     * @return array
+     * @param $url
+     * @return \Psr\Http\Message\ResponseInterface
+     * @throws \GuzzleHttp\Exception\GuzzleException
      */
-    public static function getResponseCode(string $url, $timeout = 30, string $flaresolverr = null): array
+    public static function _request($url, $timeout, $method = "GET", $options = [], $browserHeaders = true)
     {
-        if (null !== $flaresolverr) {
-            $headers = get_headers($url, 1);
-            if ($headers['Server'] === "cloudflare") {
-                return self::getHttpCodeCloudflare($url, $flaresolverr, $timeout);
-            }
+        $client = new Client();
+        $headers = ($options['headers'] ?? []);
+        if ($browserHeaders) {
+            $headers = $headers + [
+                    'Connection' => 'keep-alive',
+                    'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
+                    'Accept-Encoding' => 'gzip, deflate, br, zstd',
+                    'Accept-Language' => 'fr-FR,fr;q=0.9,en-GB;q=0.8,en;q=0.7,en-US;q=0.6',
+                    'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36',
+                    'Upgrade-Insecure-Requests' => '1',
+                    'Cache-Control' => 'no-cache',
+                    'Pragma' => 'no-cache',
+                    'Priority' => 'u=0, i',
+                    'Dnt' => '1',
+                ];
+        }
+        $options = ['timeout' => $timeout, 'http_errors' => false, 'headers' => $headers, 'allow_redirects' => ['track_redirects' => true]] + $options;
+        if (self::$_cookiesJar) {
+            $options["cookies"] = self::$_cookiesJar;
         }
-        return self::getHttpCode($url, $timeout);
+
+        return $client->request($method, $url, $options);
     }
 
     public static function getHttpCodeCloudflare($url, $apiUrl, $timeout = 30)
     {
-        $payload = json_encode([
+        $timeout = max($timeout, 60);
+
+        $payload = [
             'cmd' => 'request.get',
             'url' => $url,
             'maxTimeout' => $timeout * 1000,
-        ]);
-
+        ];
 
-        $ch = curl_init($apiUrl);
-        self::setCurlOpt($ch, $timeout, [CURLOPT_POST => true,
-            CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
-            CURLOPT_POSTFIELDS => $payload]);
-        $response = curl_exec($ch);
+        $response = self::_request($apiUrl, $timeout, 'POST', ['json' => $payload, 'headers' => ['Content-Type' => 'application/json']], false);
+        $body = json_decode($response->getBody(), true);
+        $httpcode = $body['solution']['status'];
 
-        if (preg_match('/(error|code) \b(301|302|308|404|401|403|405|500|502|503)\b/', $response, $matches)) {
-            $httpcode = $matches[2] ?? '';
-            $finalUrl = '';
-            $finalHttpCode = '';
+        if (self::$_cookiesJar && isset($body['solution']['cookies'])) {
+            foreach ($body['solution']['cookies'] as $cookie) {
+                self::$_cookiesJar->setCookie(new SetCookie($cookie));
+            }
         }
 
-        curl_close($ch);
-
-        return ['httpcode' => $httpcode, 'finalurl' => $finalUrl, 'finalHttpCode' => $finalHttpCode];
+        return ['http_code' => $httpcode];
     }
 
-    protected static function setCurlOpt($ch, $timeout = 30, $moreOptions = [])
-    {
-        curl_setopt_array($ch, array_merge([
-                CURLOPT_RETURNTRANSFER => true,
-                CURLOPT_HEADER => true,
-                CURLOPT_NOBODY => true,
-                CURLOPT_TIMEOUT => $timeout], $moreOptions)
-        );
-    }
-
-
     public static function getHttpCodeComment($httpcode)
     {
         switch ($httpcode) {