HTTP_Requestで空パスでリクエストするのはバグだろうか

v1.4.1で、LocationヘッダをallowRedirectsオプションで自動的に処理する場合、パスが空だと"GET HTTP/1.1"のようなリクエストラインでリクエストするようです。

Locationヘッダのフォローの際、setURLメソッドを使わないでリクエスト先のURLをセットしていますが、このときにパスについて何もしていません。なので、パスが空だった場合(http://www.example.comとか)、パスは空のままです。

パスが空だとしても、リクエストラインに使うRequestURIを正しく組み立てればよいのですが、ここ(_buildRequestメソッド)でもパスはそのまま使われてしまいます。v1.3.0だと、空の場合は'/'で置き換えているんですが、v1.4.1ではその処理が消えています。

先ほども書きましたが、通常のリクエストとリダイレクトのフォローとで何が違うかといえば、setURLメソッドを使うか否かです。つまり、パスが空だったときに'/'で置き換えるか否かです。

以下、テストコード。

<?php
 
/**
 * 'http://lab.koshigoe.jp/pear_http_request_141_redirect.php'
 *   --> http://pear.php.net
 */
 
require_once 'HTTP/Request.php';
 
$url  = 'http://lab.koshigoe.jp/pear_http_request_141_redirect.php';

$http = new HTTP_Request($url, array('allowRedirects' => true));
 
$res  = $http->sendRequest();

if (PEAR::isError($res)) {
    echo $http->_buildRequest() . "\n";
    echo $res->getMessage() . "\n";

}
 
/** (output)
 * GET  HTTP/1.1
 * Host: pear.php.net
 * User-Agent: PEAR HTTP_Request class ( http://pear.php.net/ )
 * Connection: close
 * Accept-Encoding: gzip
 * 
 * 
 * Malformed response.
 */
 
?>

ひとまず、以下のようなパッチでごまかしてみました。

--- Request.php 2007-05-19 04:24:29.000000000 +0900
+++ Request.php-new     2007-08-09 16:39:07.000000000 +0900

@@ -761,8 +761,7 @@
 
             // Absolute URL
             if (preg_match('/^https?:\/\//i', $redirect)) {

-                $this->_url = &new Net_URL($redirect);
-                $this->addHeader('Host', $this->_generateHostHeader());
+                $this->setURL($redirect); // Bugfix: 2007/08/09, set '/' if path was empty.

             // Absolute path
             } elseif ($redirect{0} == '/') {
                 $this->_url->path = $redirect;
@@ -877,7 +876,7 @@

 
         $host = isset($this->_proxy_host) ? $this->_url->protocol . '://' . $this->_url->host : '';
         $port = (isset($this->_proxy_host) AND $this->_url->port != 80) ? ':' . $this->_url->port : '';

-        $path = $this->_url->path . $querystring;
+        $path = (empty($this->_url->path)? '/': $this->_url->path) . $querystring; // Bugfix: 2007/08/09, set '/' if path was empty.

         $url  = $host . $port . $path;
 
         $request = $this->_method . ' ' . $url . ' HTTP/' . $this->_http . "\r\n";

リダイレクトURLが絶対URLだった場合に、setURLメソッドを使って情報を更新し、リクエストを作る際にパスが空だったら'/'に置き換えるだけです。リクエストを作るときだけを直せばよいはずですが、一応。

で、バグか分からないながらもバグ報告を出そうと思ったわけですが、気づいてしまいました。英語書けません!どうしましょう。

プロフィール

このブログ記事について

このページは、koshigoeが2007年8月 9日 19:04に書いたブログ記事です。

ひとつ前のブログ記事は「やってしまった」です。

次のブログ記事は「ドタキャンすべきだろうか」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。