Рубрики
Uncategorized

Странная поездка в http curl

предыстория Когда я пишу проект, мне нужно выполнить простую постоянную задачу, поэтому я использую swole (в конце концов, phper, а планирование плотное, скорость разработки swoole выше, чем java и go). wool 4 swoole 4 полностью поддерживает автоматическую совместную работу, что имеет большие преимущества для php developerUTF-8…

фон

Когда я пишу проект, мне нужно выполнить простую постоянную задачу, поэтому я использую swole (в конце концов, phper и плотное планирование, скорость разработки swoole выше, чем java и go).

свул 4

swoole 4 полностью поддерживает автоматическую совместную работу, что имеет большие преимущества для разработчиков php.

Дай мне каштан.

$http->on('request',function (Swoole\Http\Request $req, Swoole\Http\Response $res) {
    //todo: it's already scheduling.
});

Если вы используете swoole, вам лучше использовать последнюю версию (конечно, документы могут не успевать, что должно быть решено друзьями аудитории. Это не рекомендуется для новичков php).

4.4 – это версия с долгосрочной поддержкой, целью которой является переход на промышленный уровень (сейчас: 23 октября 2019 года)

Внешность

Я использовал guzzlehttp/guzzle в своем проекте, версия ^ 6.3.

Затем, начиная с одного дня, появляется странная ошибка.

Could not resolve: oapi.dingtalk.com (Successful completion)

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

        $client = new \GuzzleHttp\Client([
		'base_uri'  => 'https://oapi.dingtalk.com',
		'timeout'  => 5.0,
		'verify' => false,
        ]);

        try{
		$response = $client->request('POST', PATH, [
			 ......
		]);

		unset($client);
		$code = $response->getStatusCode();
		if ($code == 200) {
			$data = json_decode($response->getBody()->getContents(), true);
			return $data;
		}
		Logs::writeErrorLog('xxxx Failure timeout code:' . $code, false);
		return [];
	}catch(Exception $e) {
		Logs::writeErrorLog('xxxx Failure timeout error:' . $e->getMessage());
	}

catch всегда улавливает ошибки? И dns не может быть разрешен?

Диагностика

  1. Браузер https://oapi.dingtalk.com нормальный

  2. завиток https://oapi.dingtalk.com .

  3. Тот же параметр, отправка почтальоном, нормальный.

  4. Но он не может быть перезапущен. (прости меня, перезапусти Дафа). Это нормально в первый раз после перезагрузки, и gg Smecta

  5. Если тайм-аут удален, происходит ли сбой разрешения dns?

  6. Рукописный завиток

Волшебное время настало. Посмотрите на код.

        $ch = curl_init($url); // Start a CURL session
        $useragent="Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1";

        curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4);
        curl_setopt($ch, CURLOPT_TIMEOUT, 8);
        curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, 10);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Skip certificate check
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);  // Check if SSL encryption algorithm exists from certificate
        curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false );
        curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 2 );

        $tmpInfo = curl_exec($ch);     //Return the json object of the api
        $code = curl_errno($ch);
        $error = '';
        if($code != '') {
            $error = curl_error($ch);
        }
        $httpCode = curl_getinfo($ch,CURLINFO_HTTP_CODE);

        curl_close($ch);
        var_dump($tmpInfo, $code, $httpCode);

ложь , 6 ????

Да, код 6

error : CURLE_COULDNT_RESOLVE_HOST (6)
Couldn't resolve host. The given remote host was not resolved.

Похоже, что весь dns исчез.

Повторите попытку несколько раз, все нормально, но есть проблема с хостом разрешения.

Решение

Поскольку узел не может быть разрешен, вручную разрешите dns и соедините узел узла.

Поскольку узел не может быть разрешен, вручную разрешите dns и соедините узел узла.

Было замечено, что curl поддерживает разрешение curlopt “.

Керлопт? Решительность? Предоставляет пользовательский адрес, который определяет хост и порт.

Строка, содержащая хост, порт и IP-адрес. Каждый элемент массива разделяется двоеточием.

Формат: массив(“example.com:80:127.0.0.1”): добавлен в cURL 7.21.3, доступен с PHP 5.5.0.

Прежде всего, нам нужно получить ip-адрес хоста. Код выглядит следующим образом:

function getIp($host) : string{
        $ip = gethostbyname('oapi.dingtalk.com');
        if($ip == 'oapi.dingtalk.com') {
            return $ip;
        }

        $dns = dns_get_record('oapi.dingtalk.com');
        if(is_array($dns)) {
            foreach ($dns as $dn) {
                if(isset($dn['type']) and $dn['type'] == 'A') {
                    if(isset($dn['ip'])) {
                        return $dn['ip'];
                    }
                }
            }
        }
	return '';
}

Затем добавьте параметры к приведенному выше завитку.

$ip = getIp('oapi.dingtalk.com');
if($ip != '') {
 curl_setopt($ch, CURLOPT_RESOLVE, ['oapi.dingtalk.com:443:'.$ip]);
}

Полные примечания к разрешению

  1. В настоящее время эта проблема обнаруживается только во всем процессе.
  2. Curlopt ﹣ resolve может быть полностью применен в системе интрасети (для решения проблем dns, требующих много времени)

Оригинал: “https://programmer.help/blogs/a-strange-trip-to-http-curl.html”