]> git.rkrishnan.org Git - functorrent.git/blobdiff - src/Tracker.hs
refactor PeerID and associated functions.
[functorrent.git] / src / Tracker.hs
index 7d5525f4058d23d183deb024c56463bd543b0f3e..599c2938d8c0e8d8046768c2adcdb6d30b9b3275 100644 (file)
@@ -4,26 +4,24 @@ 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 as H
 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
 
-splitN :: Int -> BC.ByteString -> [BC.ByteString]
-splitN n bs | BC.null bs = []
-            | otherwise = (BC.take n bs) : splitN n (BC.drop n bs)
 
--- | 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) (splitN 2 bs)
-  where encode b@(c1 : c2 : []) = let c =  chr (read ("0x" ++ b))
+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
         encode _ = ""
@@ -32,28 +30,26 @@ urlEncode bs = concatMap (encode . BC.unpack) (splitN 2 bs)
           where nonSpecialChars = ['A'..'Z'] ++
                                   ['a'..'z'] ++
                                   ['0'..'9'] ++
-                                  ['-', '_', '.', '~']
+                                  "-_.~"
 
-infoHash :: (M.Map Benc.BVal Benc.BVal) -> BC.ByteString
-infoHash m = let info = m M.! (Benc.Bstr (BC.pack "info"))
+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 -> 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]
-
-connect :: Url -> String -> IO (String)
+prepareRequest :: Benc.BVal -> String -> Integer -> String
+prepareRequest (Benc.Bdict d) peer_id len =
+  let p = [("info_hash", urlEncodeHash (infoHash d)),
+           ("peer_id", HB.urlEncode peer_id),
+           ("port", "6881"),
+           ("uploaded", "0"),
+           ("downloaded", "0"),
+           ("left", show len),
+           ("compact", "1"),
+           ("event", "started")]
+  in
+   List.intercalate "&" [f ++ "=" ++ s | (f,s) <- p]
+
+connect :: Url -> String -> IO String
 connect baseurl qstr = let url = baseurl ++ "?" ++ qstr
                        in HTTP.simpleHTTP (HTTP.getRequest url) >>=
                           HTTP.getResponseBody