From 1b0fa30d388b258caca0902f46dbca40b6593535 Mon Sep 17 00:00:00 2001
From: Ramakrishnan Muthukrishnan <ram@rkrishnan.org>
Date: Sun, 15 Feb 2015 21:49:18 +0530
Subject: [PATCH] WIP: tracker protocol

---
 src/Main.hs     |  8 +++++++-
 src/Metainfo.hs |  4 ----
 src/Tracker.hs  | 25 ++++++++++++++++++++++++-
 3 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/src/Main.hs b/src/Main.hs
index 12d3515..a8a8d1f 100644
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -4,11 +4,16 @@ import System.Environment (getArgs)
 import qualified Data.ByteString.Char8 as BC
 import qualified Bencode as Benc
 import qualified Metainfo as MInfo
+import qualified Tracker as T
+
 import Text.ParserCombinators.Parsec
 
 printError :: ParseError -> IO ()
 printError e = putStrLn "parse error"
 
+genPeerId :: String
+genPeerId = "-HS0001-20150215"
+
 main :: IO ()
 main = do
   args <- getArgs
@@ -19,6 +24,7 @@ main = do
                Just m -> do
                  let (Benc.Bdict d') = d
                  putStrLn (show m)
-                 putStrLn (MInfo.infoHash d')
+--                 putStrLn (T.infoHash d')
+                 putStrLn (T.prepareRequest d genPeerId)
    Left e -> printError e
   putStrLn "done"
diff --git a/src/Metainfo.hs b/src/Metainfo.hs
index a153384..47a134c 100644
--- a/src/Metainfo.hs
+++ b/src/Metainfo.hs
@@ -65,7 +65,3 @@ mkMetaInfo (Benc.Bdict m) = let (Just info') = mkInfo (m M.! (Benc.Bstr (BC.pack
                                              , encoding = maybeBstrToString encoding'
                                              }
 mkMetaInfo _ = Nothing
-
-infoHash :: (M.Map Benc.BVal Benc.BVal) -> String
-infoHash m = let info = m M.! (Benc.Bstr (BC.pack "info"))
-             in show $ SHA1.hash $ BC.pack $ Benc.encode info
diff --git a/src/Tracker.hs b/src/Tracker.hs
index 51877d7..d388039 100644
--- a/src/Tracker.hs
+++ b/src/Tracker.hs
@@ -1,8 +1,12 @@
 module Tracker where
 
--- import qualified Bencode as Benc
 import qualified Data.ByteString.Char8 as BC
+import qualified Data.Map as M
+import qualified Data.List as List
 import qualified Network.HTTP.Base as HB
+import qualified Bencode as Benc
+import qualified Crypto.Hash as H
+import qualified Crypto.Hash.SHA1 as SHA1
 import Data.Char
 -- import Network.HTTP
 
@@ -29,6 +33,25 @@ urlEncode bs = concatMap (encode . BC.unpack) (splitN 2 bs)
                                   ['0'..'9'] ++
                                   ['-', '_', '.', '~']
 
+infoHash :: (M.Map Benc.BVal Benc.BVal) -> BC.ByteString
+infoHash m = let info = m M.! (Benc.Bstr (BC.pack "info"))
+             in SHA1.hash $ BC.pack $ Benc.encode info
+
+peerHash :: String -> BC.ByteString
+peerHash peer_id = SHA1.hash (BC.pack peer_id)
+
+prepareRequest :: Benc.BVal -> String -> String
+prepareRequest (Benc.Bdict d) peer_id = let p = [("info_hash", urlEncode (infoHash d)),
+                                                 ("peer_id", urlEncode (peerHash peer_id)),
+                                                 ("port", "6881"),
+                                                 ("uploaded", "0"),
+                                                 ("downloaded", "0"),
+                                                 ("left", "0"),
+                                                 ("compact", "1"),
+                                                 ("event", "started")]
+                                        in
+                                         List.intercalate "&" [f ++ "=" ++ s | (f,s) <- p]
+
 -- (chr . read . ("0x" ++) . BC.unpack)
 -- connect :: Url -> String -> IO (Benc.BVal)
 -- connect url infoHash = case (parseUrl url) of
-- 
2.45.2