Snoopy bug, or not?
This certainly feels like a bug in Snoopy, the HTTP client class for PHP, but I hate to have my first contact with a project be filing a bug that turns out to be just my stupidity. (So, instead, I’ll wave the bug around in public, because you don’t feel like public to me: if I had an office, you would be asking my officemates.)
$snoopy->fetch("http://user:pass@example.com") will do Basic authentication with the username “user” and password “pass” at example.com. That’s good. However, it breaks up the URL with PHP’s url_parse(), which either naively or strictly says that everything after the scheme up to the first instance of “@” is a username or a username and password, and everything after that first “@” is host and path. If your username happens to be me@example.org then properly you should use http://me%40example%2Eorg:pass@example.com. However, Snoopy doesn’t urldecode() what url_parse() passes it, and putting me%40example%2Eorg (base64_encode()ed) in the Authorization: Basic header doesn’t work. So, finally, my question is, shouldn’t Snoopy be saying
134 if (!empty($URI_PARTS["user"]))
135 $this->user = urldecode($URI_PARTS["user"]);
136 if (!empty($URI_PARTS["pass"]))
137 $this->pass = urldecode($URI_PARTS["pass"]);
even though that’s going to be a nasty surprise to anyone who has a username or password that’s something like foo%20 that they’ve been putting in without URL encoding the % sign? After all, they’re doing the wrong thing, and I just don’t see any way to push a username including an at, colon, or full stop through otherwise.
I ever used urlencode to encode the username without thinking about this ;) In the browsers and FTP-clients you too need to encode special signs like ?, @, = and spaces in the username. So this seems more a usability-question than a bug to me.
At least in my browser, you do not need to encode your username: give Firefox http://me@example.org:pass@example.com and it will correctly realize that you meant to visit example.com.
However, that either points out a bug in Firefox, or in Bloglines, where I was trying to authenticate: when you type that URL in Firefox, it puts up a ”did you mean to log in to this site?” warning, in case you are being spoofed with a long username that you might think is the domain you are visiting, but it shows the username you are going to log in with as ”me%40example%23com” rather than ”me@example.com”. So, does Basic authentication say that the server is supposed to first base64_decode the username passed in the header, and then url_decode it, that it should actually go over the wire as base64_encode(urlencode(me@example.com))? That seems odd.
Hmm. The ssh client here on my OS X box doesn’t parse that, and RFC3986 seems to say that the ”userinfo” production doesn’t allow the ”@” symbol, which is part of the ”gen-delims” production.
Sounds to me like you should parse for the first @ from the other end. Or to say it another way use everything before the LAST @ as the username and/or passwd.