From 1cc8e5407ac77fed52b8237f42fe2bf5cba61611 Mon Sep 17 00:00:00 2001
From: Ramakrishnan Muthukrishnan <ram@rkrishnan.org>
Date: Sat, 21 Feb 2015 08:11:42 +0530
Subject: [PATCH] refactor PeerID and associated functions.

Until now we were hashing peer id string to get a 20-byte hash. But
that's not needed. Peer ID is just a 20-byte string that needs to be
unique per client and sent to the tracker (and peers).
---
 functorrent.cabal |  3 ++-
 src/Main.hs       |  6 +++---
 src/Peer.hs       |  4 ++--
 src/Tracker.hs    | 18 ++++++++----------
 4 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/functorrent.cabal b/functorrent.cabal
index 77df828..b55644c 100644
--- a/functorrent.cabal
+++ b/functorrent.cabal
@@ -27,7 +27,8 @@ executable functorrent
                        base16-bytestring,
                        doctest,
                        HTTP,
-                       cryptohash
+                       cryptohash,
+                       binary
   hs-source-dirs:      src
   ghc-options:         -Wall -fwarn-incomplete-patterns
   default-language:    Haskell2010
\ No newline at end of file
diff --git a/src/Main.hs b/src/Main.hs
index 015c323..bb50a8b 100644
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -13,8 +13,8 @@ import Data.Functor
 printError :: Parsec.ParseError -> IO ()
 printError e = putStrLn $ "parse error: " ++ show e
 
-genPeerId :: String
-genPeerId = "-HS0001-20150215"
+peerId :: String
+peerId = "-HS0001-*-*-20150215"
 
 exit :: IO BC.ByteString
 exit = exitSuccess
@@ -37,7 +37,7 @@ main = do
             Nothing -> putStrLn "parse error"
             Just m -> do
               let len = MInfo.lengthInBytes (MInfo.info m)
-              body <- BC.pack <$> T.connect (MInfo.announce m) (T.prepareRequest d genPeerId len)
+              body <- BC.pack <$> T.connect (MInfo.announce m) (T.prepareRequest d peerId len)
               print (P.getPeers (P.getPeerResponse body))
       Left e -> printError e
     putStrLn "done"
diff --git a/src/Peer.hs b/src/Peer.hs
index 1660999..52cc03f 100644
--- a/src/Peer.hs
+++ b/src/Peer.hs
@@ -58,6 +58,6 @@ handShakeMsg m peer_id = let pstrlen = BC.concat $ BL.toChunks $ Bin.encode (19
                              pstr = BC.pack "BitTorrent protocol"
                              reserved = BC.replicate 8 '\0'
                              infoH = T.infoHash m
-                             peerH = T.peerHash peer_id
+                             peerID = BC.pack peer_id
                          in
-                          BC.concat [pstrlen, pstr, reserved, infoH, peerH]
+                          BC.concat [pstrlen, pstr, reserved, infoH, peerID]
diff --git a/src/Tracker.hs b/src/Tracker.hs
index c523683..599c293 100644
--- a/src/Tracker.hs
+++ b/src/Tracker.hs
@@ -4,22 +4,23 @@ import qualified Data.ByteString.Char8 as BC
 import qualified Data.Map as M
 import qualified Data.List as List
 import qualified Network.HTTP as HTTP
+import qualified Network.HTTP.Base as HB
 import qualified Bencode as Benc
 import qualified Crypto.Hash.SHA1 as SHA1
 import qualified Data.ByteString.Base16 as B16
 import qualified Utils as U
 import Data.Char
--- import Network.HTTP
+
 
 type Url = String
 
 
--- | urlEncode
+-- | urlEncodeHash
 --
--- >>> urlEncode $ BC.pack "123456789abcdef123456789abcdef123456789a"
+-- >>> urlEncodeHash $ BC.pack "123456789abcdef123456789abcdef123456789a"
 -- "%124Vx%9a%bc%de%f1%23Eg%89%ab%cd%ef%124Vx%9a"
-urlEncode :: BC.ByteString -> String
-urlEncode bs = concatMap (encode . BC.unpack) (U.splitN 2 bs)
+urlEncodeHash :: BC.ByteString -> String
+urlEncodeHash bs = concatMap (encode . BC.unpack) (U.splitN 2 bs)
   where encode b@[c1, c2] = let c =  chr (read ("0x" ++ b))
                                   in
                                    escape c c1 c2
@@ -35,13 +36,10 @@ infoHash :: M.Map Benc.BVal Benc.BVal -> BC.ByteString
 infoHash m = let info = m M.! Benc.Bstr (BC.pack "info")
              in (B16.encode . SHA1.hash . BC.pack . Benc.encode) info
 
-peerHash :: String -> BC.ByteString
-peerHash = B16.encode . SHA1.hash . BC.pack
-
 prepareRequest :: Benc.BVal -> String -> Integer -> String
 prepareRequest (Benc.Bdict d) peer_id len =
-  let p = [("info_hash", urlEncode (infoHash d)),
-           ("peer_id", urlEncode (peerHash peer_id)),
+  let p = [("info_hash", urlEncodeHash (infoHash d)),
+           ("peer_id", HB.urlEncode peer_id),
            ("port", "6881"),
            ("uploaded", "0"),
            ("downloaded", "0"),
-- 
2.45.2