【问题标题】:Is uri validation really important in Zend_Http_Client?uri 验证在 Zend_Http_Client 中真的很重要吗?
【发布时间】:2014-05-19 14:14:42
【问题描述】:

我正在使用 Zend_Http_Client (Zend Framework 1) 从网络上抓取一些数据。 在请求之前,Zend_Http_Client 通过 Zend_Uri::validate() 验证给定的 URI。 Zend_Uri::validate() 中的验证规则非常严格,所以我不能抓取很多页面。 例如。

我尝试将这个特殊字符添加到 Zend_Uri 规则中,但是有太多特殊字符,我宁愿禁用 Zend_Uri 中的整个验证过程。也许这样的解决方案并不优雅,但我不知道为什么 Zend 强迫我验证 URI...

我担心的是:如果我使用没有 URI 验证的 zend_http_client 从未经验证的 URI 中获取 html,它会不安全吗?

【问题讨论】:

    标签: php security url zend-framework web-crawler


    【解决方案1】:

    是的,您可以使用例如您自己的扩展Zend_Http_Client的类。

    只需使用您自己的 Uri 对象并重新声明 setUrigetUrirequest

    Header Host: 部分应该在选项中手动设置,我想如果在选项数组中设置了此标头,则不需要 Zend_Uri。

    但也许你只是没有以正确的方式使用 Zend_Uri 或 Zend_Client_Http。

    作为一个无效的 Zend_Uri 根本就无效。

    你可以尝试做你的浏览器在从浏览器地址栏发送 url 到服务器时所做的同样的事情,它 urlencode url...

    所以,像 这样的符号会变成:

    http://www.investing.com/.../euro-banknotes-%E2%82%AC-a-means-of-payment-recognised-worldwide-213287
    

    符号将成为编码值 %E2%82%AC

    今天的大多数浏览器都不会更改 url,因为大多数用户不会理解为什么他们的 url 会更改。

    一些疯狂的浏览器开始只在其浏览器地址栏中显示网页的域,例如移动 safari 或 chrome。

    在将其发送到 Zend_Http_Client 之前尝试对您的 url 进行 urlencode,我想您可以使用 Zend_Uri 的有效 Uri 实例!

    $url = urlencode($url);
    
    $client = new Zend_Http_Client($url);
    
    $response = $client->request(Zend_Http_Client::GET);
    

    玩得开心!

    【讨论】:

      【解决方案2】:

      让我们先看看当你将一个 URL string 传递给 Zend_Http_Client 时发生了什么:

      1. Zend_Http_Client::__construct() 将 URL 传递给 Zend_Http_Client::setUri()
      2. Zend_Http_Client::setUri() 将 URL 传递给 Zend_Uri::factory()
      3. Zend_Uri::factory() 调用 Zend_Uri_Http::__construct()
      4. Zend_Uri_Http::__construct() 调用 Zend_Uri_Http::valid()
      5. Zend_Uri_Http::valid() 调用多个 Zend_Uri_Http::validate*() 方法

      但是,将 Zend_Uri_Http 的实例传递给 Zend_Http_Client 将导致 setUri() 克隆并使用它,因此 可以通过创建 URI 类并将其实例传递给 Zend_Http_Client 来跳过 Zend_Uri 的验证 .

      创建一个扩展 Zend_Uri_Http 的 URI 类,并覆盖您的情况所需的属性和方法(但不是常量,更多内容见下文):

      class My_Uri_Http extends Zend_Uri_Http
      {
          public function valid()
          {
              return TRUE;
          }
      
          // or
      
          public function validatePath($path = null)
          {
              $this->_regex['path'] = '...';
              return parent::validatePath($path);
          }
      }
      

      然后告诉 Zend_Uri::factory()'s 使用你的类并将结果(My_Uri_Http 和 Zend_Uri_Http 的扩展实例)传递给 Zend_Http_Client:

      $uri = Zend_Uri::factory($url, 'My_Uri_Http');
      
      $client = new Zend_Http_Client($uri);
      

      为什么不用常量?

      Zend_Uri_Http::__construct() 使用 self::CONSTANT 来创建它在其 validate*() 方法中使用的正则表达式。覆盖 My_Uri_Http 中的那些常量不会有任何效果,因为 self:: 引用 Zend_Uri_Http。 (如果使用 static:: 代替,您可以覆盖子类中的常量。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-31
        • 2011-04-13
        • 1970-01-01
        • 2017-04-11
        相关资源
        最近更新 更多