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