我使用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
这样的调试器是否可以在这里看看网络调用是什么,以及在哪里?
答案 0 :(得分:1)
request.success
事件。在这里,我调用gethostbyname()
,其目的明确是进行DNS查找。
现在这已被禁用,“神秘”的DNS调用已经消失。