]> git.rkrishnan.org Git - functorrent.git/blobdiff - src/FuncTorrent/Tracker.hs
preparations to introduce Metainfo as an environment
[functorrent.git] / src / FuncTorrent / Tracker.hs
index 749f75d2780a9ee9214df4c7614964ead14303e7..206e1b8294c290e84605cbe611a82968fe616f6f 100644 (file)
@@ -1,30 +1,26 @@
 {-# LANGUAGE OverloadedStrings #-}
 module FuncTorrent.Tracker
     (TrackerResponse(..),
-     connect,
      mkArgs,
-     mkParams,
-     mkTrackerResponse,
+     getTrackerResponse,
      urlEncodeHash
     ) where
 
-import Prelude hiding (lookup, concat, replicate, splitAt)
+import Prelude hiding (lookup, splitAt)
 
 import Data.ByteString (ByteString)
-import Data.ByteString.Char8 as BC (pack, unpack, splitAt, concat, intercalate)
+import Data.ByteString.Char8 as BC (pack, unpack, splitAt)
 import Data.Char (chr)
 import Data.List (intercalate)
 import Data.Map as M (lookup)
-import Network.HTTP (simpleHTTP, defaultGETRequest_, getResponseBody)
 import Network.HTTP.Base (urlEncode)
-import Network.URI (parseURI)
 import qualified Data.ByteString.Base16 as B16 (encode)
 
-import FuncTorrent.Bencode (BVal(..))
+import FuncTorrent.Bencode (BVal(..), decode)
+import FuncTorrent.Metainfo (Info(..), Metainfo(..))
+import FuncTorrent.Network (get)
 import FuncTorrent.Peer (Peer(..))
 import FuncTorrent.Utils (splitN)
-import FuncTorrent.Metainfo (Info(..), Metainfo(..))
-
 
 -- | Tracker response
 data TrackerResponse = TrackerResponse {
@@ -65,12 +61,19 @@ mkTrackerResponse resp =
                  splitN 2 . B16.encode
 
       makePeer :: ByteString -> Peer
-      makePeer peer = Peer (toIP ip') (toPort port')
+      makePeer peer = Peer "" (toIP ip') (toPort port')
           where (ip', port') = splitAt 4 peer
 
 -- | Connect to a tracker and get peer info
-connect :: Metainfo -> String -> IO ByteString
-connect m peer_id = get (head . announceList $ m) $ mkArgs m peer_id
+tracker :: String -> Metainfo -> IO ByteString
+tracker peer_id m = get (head . announceList $ m) $ mkArgs peer_id m
+
+getTrackerResponse ::  String -> Metainfo -> IO (Either ByteString TrackerResponse)
+getTrackerResponse peerId m = do
+  resp <- tracker peerId m
+  case decode resp of
+   Right trackerInfo -> return $ mkTrackerResponse trackerInfo
+   Left e -> return $ Left (pack (show e))
 
 --- | URL encode hash as per RFC1738
 --- TODO: Add tests
@@ -88,8 +91,8 @@ urlEncodeHash bs = concatMap (encode' . unpack) (splitN 2 bs)
 
 -- | Make arguments that should be posted to tracker.
 -- This is a separate pure function for testability.
-mkArgs :: Metainfo -> String -> [(String, ByteString)]
-mkArgs m peer_id = [("info_hash", pack . urlEncodeHash . B16.encode . infoHash $ m),
+mkArgs :: String -> Metainfo -> [(String, ByteString)]
+mkArgs peer_id m = [("info_hash", pack . urlEncodeHash . B16.encode . infoHash $ m),
                     ("peer_id", pack . urlEncode $ peer_id),
                     ("port", "6881"),
                     ("uploaded", "0"),
@@ -97,15 +100,3 @@ mkArgs m peer_id = [("info_hash", pack . urlEncodeHash . B16.encode . infoHash $
                     ("left", pack . show . lengthInBytes $ info m),
                     ("compact", "1"),
                     ("event", "started")]
-
--- | Make a query string from a alist of k, v
--- TODO: Url encode each argument
-mkParams :: [(String, ByteString)] -> ByteString
-mkParams params = BC.intercalate "&" [concat [pack f, "=", s] | (f,s) <- params]
-
-get :: String -> [(String, ByteString)] -> IO ByteString
-get url args = simpleHTTP (defaultGETRequest_ url') >>= getResponseBody
-    where url' = case parseURI $ unpack $ concat [pack url, "?", qstr] of
-                   Just x -> x
-                   _ -> error "Bad tracker URL"
-          qstr = mkParams args