Hello,
i started to write this e-mail as a bug report. For the record, the bug is:
--- code ---
$uri = "http://www.google.com/";;
$client = new Zend_Http_Client();
$client->setUri($uri);
$client->request('POST');
echo $client->getLastRequest();
$client->request('GET');
echo $client->getLastRequest();
--- end code ---
--- output ---
POST / HTTP/1.1
Host: www.google.com
Connection: close
Content-type: application/x-www-form-urlencoded
User-agent: Zend_Http_Client

GET / HTTP/1.1
Host: www.google.com
Connection: close
Content-type: application/x-www-form-urlencoded <== !!! SHOULD NOT BE HERE !!!
User-agent: Zend_Http_Client
--- end output ---

ok, there're problems with cleaning between requests, btw solvable userland by this ugly fix
--- code ---
$client->setEncType(null);
--- end code ---
before second request().

Then i dig a bit into the code and found also that
--- code ---
$uri1 = "http://www.google.com/";;
$uri2 = "http://www.yahoo.com/";;
$client = new Zend_Http_Client();
$client->setUri($uri1);
$client->setAuth("myuser","mypass");
$client->request('GET');
echo $client->getLastRequest();
$client->setUri($uri2);
$client->request('GET');
echo $client->getLastRequest();
--- end code ---
--- output ---
GET / HTTP/1.1
Host: www.google.com
Connection: close
User-agent: Zend_Http_Client
Authorization: Basic bXl1c2VyOm15cGFzcw==

GET / HTTP/1.1
Host: www.yahoo.com
Connection: close
User-agent: Zend_Http_Client
Authorization: Basic bXl1c2VyOm15cGFzcw== <== !!! ARGH !!!
--- end output ---
Wow, now that could be the intended behavior but it feels so wrong to me,
that i started thinking about how Zend_Http_Client is supposed to work.
My conclusion is component's architecture is not completely clear and interface
has some inconsistencies. Let me explain.

Afaik, there are two kinds of "http clients":
- a) web browser (à la firefox) who can work with multiple requests by user and keep state of them in memory(stateful) - b) command line (à la wget) who can work with just one user request and then exits. If more are needed,
the program is restarted with a clean environment (stateless)

It appears to me that Zend_Http_Client is a mix of the two.
Documentation, support of features like cookie persistency across requests and presence of methods like resetParameters(), which is supposed to clean the environment, indicate it's a), but all the rest works like it's b) just without the internal cleaning between requests needed to make the component reliable. Take setAuth(), if it was a) it would work at "client level" indicating an authentication rule with user, password, domain and path
valid for all the requests (but matching only certain requests):
---code---
$client->setAuth($user,$password,$type,$domain,$path)
---end code---
the set of auth rules would persist until the client is shut down. that's how browser works. If it was b) it would be just like now but for the next request you would have to set it again, it's not remembered. As it is now, setAuth() really targets a Zend_Http_Request (a class strangely missing btw) object hidden inside the client, which represents the current request, so the component ends up blindly sending the same auth header to
all requests unless careful handmade cleaning by user.
Same thing for setMethod(), the http method is relevant for a single request, not for the whole client to send it over and over again. Working on the internal "current request" global object makes the internal cleaning difficult so stuff like the first bug i ran into happens (in fact enctype is set to form urlencoded inside setMethod())

In conclusion, i think a more clear architectural approach should be taken and stated in the documentation. if it's browser-like the component should be revamped. If it's wget- like the environment should be completely cleaned after a request except for the cookiejar, or a new client object should be instantiated for each new request.
In both case i'd suggest to add a Zend_Http_Request class:
if a) to be used by users to make new requests
if b) to be used internally to keep the "current request" data and make cleaning easier.

just my 2 cents,
Federico

Reply via email to