如何防止截获的Guzzle 3请求生成DNS请求?

时间:2015-01-22 17:59:31

标签: php guzzle goutte

我使用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获取数据的实际尝试,并且没有与example.com无法提供我要求的文档相关的故障异常(例如404)。所以,我的假响应似乎没问题。

有没有办法阻止Guzzle进行这些毫无意义的DNS调用?我确实考虑过使用MockPlugin,但我当时并不确定如何做到这一点,现在也不确定是否会解决这个问题。

(我更喜欢在插件中进行假装/模拟,所以虽然我使用MockPlugin没问题,但我想在其中进行拦截,而不是根据文档进行外部拦截。我想我可以延长它,也许?)

可能我需要转移到更高版本的Guzzle,如果这是唯一的方式,那就这样吧。我正在进行一个旧项目,当时最新的Goutte使用Guzzle 3.我打算升级,但如果可能的话,我宁愿稍后再做,因为我现在的版本可以做我想做的一切。


Post Script:我发现DNS调用可能来自Goutte,而不是Guzzle。我不确定如何进行调试,至少部分是因为Goutte被Composer作为.phar文件提取。像xdebug这样的调试器是否可以在这里看看网络调用是什么,以及在哪里?

1 个答案:

答案 0 :(得分:1)

啊哈:这既不是Guzzle,也不是Goutte。在我的代码中,为了HTTP日志记录,我拦截了request.success事件。在这里,我调用gethostbyname(),其目的明确是进行DNS查找。

现在这已被禁用,“神秘”的DNS调用已经消失。