From 1f707b2dc36f4b5d9c083c57de71906663f1c313 Mon Sep 17 00:00:00 2001
From: Ramakrishnan Muthukrishnan <ram@rkrishnan.org>
Date: Tue, 17 Feb 2015 16:35:00 +0530
Subject: [PATCH] Handle the `left' parameter for the tracker request.

Tracker initial request includes a parameter called `left' to indicate
the size of the file left to be downloaded. When we contact the tracker
initially, we haven't downloaded anything yet. So, the left parameter
should be the length parameter. For now, we handle only single file
torrent files, so we just pick the length param from Metainfo and shove
it in into the tracker http request.
---
 src/Main.hs    |  4 +++-
 src/Tracker.hs | 23 ++++++++++++-----------
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/src/Main.hs b/src/Main.hs
index b0f594a..482b433 100644
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -8,6 +8,7 @@ import qualified Metainfo as MInfo
 import qualified Tracker as T
 import qualified Text.ParserCombinators.Parsec as Parsec
 import qualified Peer as P
+import qualified Data.Map as M
 import Data.Functor
 
 printError :: Parsec.ParseError -> IO ()
@@ -35,7 +36,8 @@ main = do
    Right d -> case MInfo.mkMetaInfo d of
                Nothing -> putStrLn "parse error"
                Just m -> do
-                 body <- BC.pack <$> T.connect (MInfo.announce m) (T.prepareRequest d genPeerId)
+                 let length = MInfo.lengthInBytes (MInfo.info m)
+                 body <- BC.pack <$> T.connect (MInfo.announce m) (T.prepareRequest d genPeerId length)
                  print (P.getPeers (P.getPeerResponse body))
    Left e -> printError e
   putStrLn "done"
diff --git a/src/Tracker.hs b/src/Tracker.hs
index 52dccdd..68cf28c 100644
--- a/src/Tracker.hs
+++ b/src/Tracker.hs
@@ -38,17 +38,18 @@ infoHash m = let info = m M.! Benc.Bstr (BC.pack "info")
 peerHash :: String -> BC.ByteString
 peerHash = B16.encode . SHA1.hash . BC.pack
 
-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]
+prepareRequest :: Benc.BVal -> String -> Integer -> String
+prepareRequest (Benc.Bdict d) peer_id length =
+  let p = [("info_hash", urlEncode (infoHash d)),
+           ("peer_id", urlEncode (peerHash peer_id)),
+           ("port", "6881"),
+           ("uploaded", "0"),
+           ("downloaded", "0"),
+           ("left", show length),
+           ("compact", "1"),
+           ("event", "started")]
+  in
+   List.intercalate "&" [f ++ "=" ++ s | (f,s) <- p]
 
 connect :: Url -> String -> IO String
 connect baseurl qstr = let url = baseurl ++ "?" ++ qstr
-- 
2.45.2