This is related to another open question of mine. While there aren’t any actual answers, dtb started me down this track so if it bears fruit I’ll be accepting his answer.
I’m generating an announce url for a BitTorrent tracker in some (fairly hairy) C# code.
The end result is something like:
http://208.106.250.207:8192/announce?info_hash=-%CA8%C1%C9rDb%ADL%ED%B4%2A%15i%80Z%B8%F%C&peer_id=01234567890123456789&port=6881&uploaded=0&downloaded=0&left=0&compact=0&no_peer_id=0&event=started
If I copy paste this into an address bar, I get a valid response from the tracker. However, my code is getting an error message back (invalid info_hash).
The code dispatching the request:
... Code building the URI ...
String uri = BuildURI(); //This results in the above URI string.
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
req.Proxy = new WebProxy(); //Some examples online suggest this is required, so WARNING: here be voodoo (determine if necessary later)
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
... Code parsing the stream ...
If I debug and pull out the string version of req.RequestUri, I get:
http://208.106.250.207:8192/announce?info_hash=-Ê8ÁÉrDbLí´*iZ¸%25F%25C&peer_id=01234567890123456789&port=6881&uploaded=0&downloaded=0&left=0&compact=0&no_peer_id=0&event=started
I can’t actually tell what’s being sent to the tracker “on the line”, but it looks like I’m doing something dumb with regard to URIs. Anyone know what?
Use .AbsoluteUri from a System.Uri (being the Type of Request.RequestUri) to get your original url without it being “munged”
The “problem” here is the way the .Net System.Uri class works (I say “problem” in quotes, because it is actually behaving correctly).
Your original info_hash querystring is a load of url-encoded bytes. When you retrieve the Uri instance using Uri.ToString(), it helpfully decodes these (by doing a url-decode) and converts these bytes (e.g. %CA) into their respective characters (in your case Ê, but this is probably dependent on your local code page settings as this is an “upper-half” ANSI character and will change depending on code-page).
Internally, the querystring is actually being stored correctly; the System.Uri class is just trying to be helpful.
This bit of code should illustrate it better:
I’d guess that, on the wire, things are fine and this is just an artifact of how you’re retrieving the url from System.Uri.