Lets talk for a moment about bittorrent. It is a highly useful method of relaying data from a user with little bandwidth to a swarm of other users. Bittorrent has had a nifty little extension added a while back called "webseeding". This allowed you to, in addition to the standard bittorrent connections, have one or more "fallback" locations wherein users could pull via http. This is a great idea for people who want to set up a handful of legal torrent, but don't want to necessarily have to make sure that they continuously are running their bittorrent client.
I happen to be in this category of people. I looked around for a while to try to find a free, open source implementation of a webseeding client, but was unable to find one that wasn't deeply tied into another system (such as Drupal). Failing there, and being a programmer by education and trade, I decided to write my own. It turns out that both the specification (insomuch as there is one) for the .torrent file format and the specification for the webseeding extension are very simple. I coded up a very simple client over the course of the last few days and got it working successfully an hour or so ago.
During this, I found several incredibly annoying things. Firstly, it appears that ktorrent
(my favorite bt client), despite listing webseeds as supported, doesn't support them correctly. They fail to load when embedded in the torrent itself, and when manually added, behave badly. By behave badly, I mean that they connect to the address and specify no arguemnts (like an info_hash or desired block number). Ktorrent then complains when it can't download any data a few times before giving up and accusing the server of being bad. I ended up doing my testing with bittornado, it helped me realize that I had misread the specification. I had thought that info_hashes were to be provided as 40-bit hex strings rather than as 20-bit raw strings. Once I realized what was going on, I wrote some wrapper code to do the 20 to 40 bit conversion (I didn't want to use the 20 bit version because of my caching scheme). This was about 8 lines of PHP code. I ran it again and it still seemed to be unable to locate the file. After adding some debug output, I found that the conversion was producing a string which, rather than being the conversion of the 20 bytes was the string '00' prepended to the first 19 bytes of the 20 byte version. This I found absolutely bizarre. Digging deeper, I discovered that PHP's unpack
function is deeply broken. Rather than acting like perl's unpack
and producing an array as its return value, it instead produces a hash (insofar as all PHP arrays are hashes). It does this by having you include with each specifier a slash and a name for the previous specifier. Here is where the trick comes: if, like me, you include no specifier, it places those elements into the returned array/hash with numeric keys incrementing for each unnamed specifier and starting at 1. Not zero. Arrays in PHP start at zero. Everywhere. Always. Unless, apparently, if you are using unpack.
(Also, apparently tumblr is down and that fact will cause xpost to crash when it attempts to authenticate a tumblr blog. I should fix this. Guy: remember to fix this)
Published by XPostcurses