CURLOPT_STDERR всегда выполняется? - PullRequest
1 голос
/ 20 февраля 2020

Ну, у меня проблемы с отправкой запросов в Discord API, я не понимаю, как работает curl.

Это мой код:

function make_request($mixed, $token, $get_json = true) {
    $url = is_string($mixed) ? $mixed : getApiUrl($mixed);
    // TODO: Check for valid url!

    $log_file = __DIR__.'/../logs/request.txt';
    if(!is_readable($log_file)) printError("File '$log_file' is not readable!");
    if(!is_writable($log_file)) printError("File '$log_file' is not writable!");

    $ch = curl_init();
    $f = fopen($log_file, 'w+');

    if($f === false) printError("There was an error opening '$log_file'!");
    ftruncate($f, 0);

    curl_setopt_array($ch, array(
        CURLOPT_URL            => $url, 
        CURLOPT_HTTPHEADER     => array('Authorization: Bot ' . $token), 
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_FOLLOWLOCATION => 1,
        CURLOPT_VERBOSE        => 1,
        CURLOPT_SSL_VERIFYPEER => 0,
        CURLOPT_STDERR         => $f,
    ));

    $response = curl_exec($ch);
    fclose($f);
    curl_close($ch);

    $contents = file_get_contents($log_file);
    if($contents != '') 
    {
        // Censor bot key!
        $contents = preg_replace("/^Authorization: Bot.+?$/", "Authorization: Bot xxx", $contents);
        printError($contents);
    }

    if($get_json) {
        $pretty = isset($_GET["pretty"]);

        if($pretty) {
            $json = json_decode($response);
            return json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        }

        return $response;
    }

    return json_decode($response, true);
}

И это мой вывод:

[OuterException] System.Exception: * Hostname in DNS cache was stale, zapped
*   Trying 162.159.135.233...
* TCP_NODELAY set
* Connected to discordapp.com (162.159.135.233) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-ECDSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=ssl711320.cloudflaressl.com
*  start date: Feb 13 00:00:00 2020 GMT
*  expire date: Aug 21 23:59:59 2020 GMT
*  subjectAltName: host "discordapp.com" matched cert's "discordapp.com"
*  issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO ECC Domain Validation Secure Server CA 2
*  SSL certificate verify ok.
> GET /api/guilds/479096180601782274 HTTP/1.1
Host: discordapp.com
Accept: */*
Authorization: Bot ...

< HTTP/1.1 200 OK
< Date: Thu, 20 Feb 2020 17:49:15 GMT
< Content-Type: application/json
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: __cfduid=ddfc25d7448507e06474f24ff3e8352381582220955; expires=Sat, 21-Mar-20 17:49:15 GMT; path=/; domain=.discordapp.com; HttpOnly; SameSite=Lax
< Strict-Transport-Security: max-age=31536000; includeSubDomains
< Via: 1.1 google
< Alt-Svc: clear
< CF-Cache-Status: DYNAMIC
< Set-Cookie: __cfruid=66721d8d16cd42e4884dc62afe94705cbf1e21df-1582220955; path=/; domain=.discordapp.com; HttpOnly; Secure; SameSite=None
< Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< Server: cloudflare
< CF-RAY: 568250ea9fe2a861-CDG
<
* Curl_http_done: called premature == 0
* Connection #0 to host discordapp.com left intact

   en DiscordIdCrawler.Lib.Core.ApiWorker.CheckForErrors(Object response) en E:\PHP\discord-flooder-bot\client\DiscordIdCrawler\DiscordIdCrawler.Lib\Core\ApiWorker.cs:línea 152
   en DiscordIdCrawler.Lib.Core.ApiWorker.GetServerName(Int64 serverId) en E:\PHP\discord-flooder-bot\client\DiscordIdCrawler\DiscordIdCrawler.Lib\Core\ApiWorker.cs:línea 312
   en DiscordIdCrawler.Lib.Core.DriverWorker.GoToServer(IWebDriver web, Int32 serverNum, Boolean storeOnDB) en E:\PHP\discord-flooder-bot\client\DiscordIdCrawler\DiscordIdCrawler.Lib\Core\DriverWorker.cs:línea 141

Мой вопрос заключается в том, что, возможно, я печатаю ошибку, когда curl просто показывает подробный журнал, но я не уверен, используется ли CURLOPT_STDERR для печати ошибок или весь журнал.

В документах: https://www.php.net/manual/en/function.curl-setopt.php

Альтернативное расположение для вывода ошибок вместо STDERR.

Возможно, потому что CURLOPT_VERBOSE включено.

TRUE для вывода подробной информации. Записывает вывод в STDERR или в файл, указанный с помощью CURLOPT_STDERR.

В этом случае мне нужно знать, когда происходит ошибка. Любой совет здесь?

1 Ответ

1 голос
/ 20 февраля 2020

Вы на правильном пути. Если вы хотите вывод диагностических данных c, вы должны организовать его захват до того, как вы отправите запрос. Обычный способ сделать это - сохранить его в оперативной памяти, проверить наличие ошибок скручивания и правильно обработать.

Этот код выглядит следующим образом:

$ch = curl_init();
curl_setopt_array($ch, [
    // ... other options here
    CURLOPT_RETURNTRANSFER => 1,
    CURLOPT_VERBOSE => 1,
    CURLOPT_STDERR => ($log = fopen('php://temp', 'w')),
]);
$response = curl_exec($ch);
if (false === $response) {
    $errno = curl_error($ch);
    $errmsg = curl_strerror($errno);
    $logtext = stream_get_contents($log, -1, 0);
    // ... log the info above, take action, etc.
} else {
    // ... $response is your HTTP response
}
curl_close($ch);
...