Issues

ZF-1853: Zend_Rest_Client doesn't clean params before create the Zend_Http_Client request

Description


$rest1 = new Zend_Rest_Client('http://rest.server.com');
$rest1->test('test');
$rest->get();    // -> http://rest.server.com?arg1=test&test=test&rest=1

$rest2 = clone $rest1;
$rest2->test2('test2');
$rest2->get();    // -> http://rest.server.com//…

$rest3 = new Zend_Rest_Client('http://rest.server.com');
$rest3->test3('test3');
$rest3->get();    // -> http://rest.server.com//…

Zend_Rest_Client use a static Zend_Http_Client object but this only add all given params


    // Zend_Rest_Client (Line 130 - 136)
    final public function restGet($path, array $query = null)
    {
        $this->_prepareRest($path);
        $client = self::getHttpClient();
        $client->setParameterGet($query);
        return $client->request('GET');
    }

    // Zend_Rest_Client (Line 100 - 120)
    final private function _prepareRest($path)
    {
        // Get the URI object and configure it
        if (!$this->_uri instanceof Zend_Uri_Http) {
            require_once 'Zend/Rest/Client/Exception.php';
            throw new Zend_Rest_Client_Exception('URI object must be set before performing call');
        }

        $uri = $this->_uri->getUri();

        if ($path[0] != '/' && $uri[strlen($uri)-1] != '/') {
            $path = '/' . $path;
        }

        $this->_uri->setPath($path);

        /**
         * Get the HTTP client and configure it for the endpoint URI.  Do this each time
         * because the Zend_Http_Client instance is shared among all Zend_Service_Abstract subclasses.
         */
        self::getHttpClient()->resetParameters();    // <- This line is missing
        self::getHttpClient()->setUri($this->_uri);
    }


    // Zend_Http_Client  (Line 377 - 387)
    public function setParameterGet($name, $value = null)
    {
        if (is_array($name)) {
            foreach ($name as $k => $v)
                $this->_setParameter('GET', $k, $v);
        } else {
            $this->_setParameter('GET', $name, $value);
        }

        return $this;
    }

    // Zend_Http_Client  (Line 415 - 433)
    protected function _setParameter($type, $name, $value)
    {
        $parray = array();
        $type = strtolower($type);
        switch ($type) {
            case 'get':
                $parray = &$this->paramsGet;
                break;
            case 'post':
                $parray = &$this->paramsPost;
                break;
        }

        if ($value === null) {
            if (isset($parray[$name])) unset($parray[$name]);
        } else {
            $parray[$name] = $value;
        }
    }

Comments

Assigned to Davey

I agree with the original report. Each request made by Zend_Rest_Client is "inheriting" parameters from previous requests made with that Zend_Rest_Client instance. I don't believe this is intuitive given that Zend_Rest_Client doesn't provide methods for parameter handling as Zend_Http_Client does, which implies that parameters will be specific to the request being executed and will not be retained in subsequent requests made with that Zend_Rest_Client instance. This needs to be fixed. I'll attach a patch shortly that makes use of the fluent API to apply the fix suggested in the bug report.

Proposed patch.

Fixed in 1.0.x and trunk

  • Davey

This bug is not entirely fixed.

Sending more requests after each other produces wrong requests on the server.

$client = new Zend_Rest_Client('http://127.0.0.1/rest.php'); $res = $client->add(0,0,0,0,0,0)->get(); var_dump($res);

$client = new Zend_Rest_Client('http://127.0.0.1/rest.php'); $res = $client->find(16)->get(); var_dump($res);

GET /rest.php?method=add&arg0=0&arg1=0&arg2=0&arg3=0&arg4=0&arg5=0&rest=1 HTTP/1.1" 200 175 "-" "Zend_Http_Client" GET /rest.php?find=16&arg1=16&rest=1 HTTP/1.1" 404 202 "-" "Zend_Http_Client"

As you can see, the 2nd request is incorrect, and contains no "method" argument, resulting in an error from the server.

I tried to reproduce the bug described in the last comment, but I can't. The opposite is true, it is working allright now.