Как запретить перехваченному запросу Guzzle 3 генерировать DNS-запросы?

Я использую Goutte 1.0.6 (последний, кто использует Guzzle 3) для создания веб-скребка. Для тестирования я хочу загрузить HTTP-ответ и использовать его вместо реального ответа cURL, и это в основном работает нормально. В настоящее время вариант использования - это модульное тестирование, но я ожидаю, что я хочу использовать это и для производственного кэширования.

Интересно, что я иногда замечал, что, если я отключен от сети, мои модульные тесты замедляются. Я немного покопался в Wireshark и обнаружил, что мои звонки http://example.com/something генерируют запросы DNS, даже если они не нужны.

Вот соответствующий фрагмент моего плагина Guzzle для предоставления поддельного ответа. Соответствующие биты являются захваченными request.before_send событие, а также тот факт, что запрос заполняется в конце, если в таблице Propel найден элемент кэша:

class SavedPageLoaderPlugin extends HttpPluginBase
{
    public static function getSubscribedEvents()
    {
        return array(
            'request.before_send' => 'onRequestBeforeSend',
        );
    }

    /**
     * Handles a Guzzle event before an HTTP op is attempted
     * 
     * @param \Guzzle\Common\Event $event
     * @throws \WebScraper\PauseException
     */
    public function onRequestBeforeSend(Event $event)
    {
        // @var $request Guzzle\Http\Message\Response
        $request = $event['request'];

        // Decide if we are caching for this run
        if (!$this->isLoadEnabled())
        {
            return;
        }

        // Decide if we have a URL for this request
        $url = $request->getUrl();
        $httpPage = HttpPageQuery::create()->
            filterByUrl($url)->
            findOne();
        if (!$httpPage)
        {
            return;
        }

        // Set a notification message for all subscribers, then set response
        $this->setContainerMessage(self::MESSAGE_USES_SAVED_PAGE);
        $response = new Response(
            200,
            $this->convertHeadersIntoKeyedArray($httpPage->getHeaders()),
            $httpPage->getBody()
        );

        $request->setResponse($response);
    }

Напомним, сам код работает. Wireshark не показывает фактических попыток получения данных через порт 80, и нет исключений по сбоям (например, 404), связанных с неспособностью example.com предоставить запрашиваемые документы. Итак, мои фальшивые ответы кажутся нормальными.

Есть ли способ для меня, чтобы запретить Guzzle делать эти бессмысленные DNS-звонки? Я действительно думал об использовании MockPlugin, но я не был уверен, как это сделать в то время, и не сейчас, решит ли это эту оставшуюся проблему.

(Я предпочитаю делать подделку / издеваться внутри плагина, так что пока у меня нет проблем с использованием MockPluginЯ хотел бы сделать перехват внутри него, а не снаружи, в соответствии с документами. Я думаю, я мог бы расширить это, возможно?)

Может быть, мне нужно перейти на более позднюю версию Guzzle, и если это единственный путь, пусть будет так. Я работаю над старым проектом, в котором последняя версия Goutte в то время использовала Guzzle 3. Я собираюсь обновиться, но предпочел бы сделать это позже, если это возможно, так как мои текущие версии делают все, что я хочу.


Post Script: мне приходит в голову, что DNS-вызов мог исходить от Goutte, а не от Guzzle. Я не уверен, как отладить это, по крайней мере, отчасти потому, что Goutte выбирается Composer как .phar файл. Может ли отладчик как xdebug быть полезным здесь, чтобы увидеть, что делает сетевой вызов и где?

1 ответ

Решение

Ага: это не было ни Жра, ни Гутта. В другом месте моего кода я перехватываю request.success событие для целей ведения журнала HTTP. Здесь я звоню gethostbyname(), чья цель явно сделать поиск DNS.

Теперь это отключено, "таинственные" DNS-звонки исчезли.

Другие вопросы по тегам