]> git.rkrishnan.org Git - functorrent.git/blobdiff - src/FuncTorrent/Tracker.hs
Tracker: refactor into http, udp and types modules
[functorrent.git] / src / FuncTorrent / Tracker.hs
index 178aa9719bbb870d0d2f5dbcf26f174a6d10b67a..64a2ce9d3e8c96a5a29c5176bd770be0ba05bb52 100644 (file)
@@ -1,57 +1,29 @@
+{-# LANGUAGE OverloadedStrings #-}
 module FuncTorrent.Tracker
-    (connect,
-     infoHash,
-     prepareRequest,
-     urlEncodeHash
+    (TState(..),
+     initialTrackerState,
+     trackerLoop
     ) where
 
-import Prelude hiding (lookup)
-import Crypto.Hash.SHA1 (hash)
-import Data.ByteString.Char8 (ByteString, pack, unpack)
-import Data.Char (chr)
-import Data.List (intercalate)
-import Data.Maybe (fromJust)
-import Data.Map as M (Map, (!))
-import Network.HTTP (simpleHTTP, defaultGETRequest_, getResponseBody)
-import Network.HTTP.Base (urlEncode)
-import Network.URI (parseURI)
-import qualified Data.ByteString.Base16 as B16 (encode)
+import Control.Concurrent.MVar (newEmptyMVar, newMVar)
+import Data.List (isPrefixOf)
 
-import FuncTorrent.Bencode (BVal(..), InfoDict, encode)
-import FuncTorrent.Utils (splitN)
+import FuncTorrent.Tracker.Http(trackerLoop)
+import FuncTorrent.Tracker.Types(TState(..), TrackerEventState(..), TrackerProtocol(..))
 
-type Url = String
+initialTrackerState :: Integer -> IO TState
+initialTrackerState sz = do
+  ps <- newEmptyMVar
+  up <- newMVar 0
+  down <- newMVar 0
+  return $ TState { currentState = None
+                  , connectedPeers = ps
+                  , uploaded = up
+                  , downloaded = down
+                  , left = sz }
 
--- | urlEncodeHash
---
--- >>> urlEncodeHash $ pack "123456789abcdef123456789abcdef123456789a"
--- "%124Vx%9a%bc%de%f1%23Eg%89%ab%cd%ef%124Vx%9a"
-urlEncodeHash :: ByteString -> String
-urlEncodeHash bs = concatMap (encode' . unpack) (splitN 2 bs)
-  where encode' b@[c1, c2] = let c =  chr (read ("0x" ++ b))
-                            in escape c c1 c2
-        encode' _ = ""
-        escape i c1 c2 | i `elem` nonSpecialChars = [i]
-                       | otherwise = "%" ++ [c1] ++ [c2]
+getTrackerType :: String -> TrackerProtocol
+getTrackerType url | isPrefixOf "http://" url = Http
+                   | isPrefixOf "udp://" url  = Udp
+                   | otherwise                = UnknownProtocol
 
-        nonSpecialChars = ['A'..'Z'] ++ ['a'..'z'] ++ ['0'..'9'] ++ "-_.~"
-
-infoHash :: Map BVal BVal -> ByteString
-infoHash m = let info = m ! Bstr (pack "info")
-             in (hash . pack . encode) info
-
-prepareRequest :: InfoDict -> String -> Integer -> String
-prepareRequest d peer_id len =
-  let p = [("info_hash", urlEncodeHash ((B16.encode . infoHash) d)),
-           ("peer_id", urlEncode peer_id),
-           ("port", "6881"),
-           ("uploaded", "0"),
-           ("downloaded", "0"),
-           ("left", show len),
-           ("compact", "1"),
-           ("event", "started")]
-  in intercalate "&" [f ++ "=" ++ s | (f,s) <- p]
-
-connect :: Url -> String -> IO ByteString
-connect baseurl qstr = simpleHTTP (defaultGETRequest_ url) >>= getResponseBody
-    where url = fromJust . parseURI $ (baseurl ++ "?" ++ qstr)