summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Network/BitTorrent/Tracker.hs43
-rw-r--r--src/Network/BitTorrent/Tracker/Protocol.hs23
2 files changed, 35 insertions, 31 deletions
diff --git a/src/Network/BitTorrent/Tracker.hs b/src/Network/BitTorrent/Tracker.hs
index e4bcf2cd..2319a551 100644
--- a/src/Network/BitTorrent/Tracker.hs
+++ b/src/Network/BitTorrent/Tracker.hs
@@ -8,6 +8,7 @@
8-- This module provides high level API for peer->tracker 8-- This module provides high level API for peer->tracker
9-- communication. 9-- communication.
10-- 10--
11{-# LANGUAGE RecordWildCards #-}
11module Network.BitTorrent.Tracker 12module Network.BitTorrent.Tracker
12 ( module Network.BitTorrent.Tracker.Scrape 13 ( module Network.BitTorrent.Tracker.Scrape
13 14
@@ -155,28 +156,26 @@ withTracker :: Progress -> TConnection -> (TSession -> IO a) -> IO a
155withTracker initProgress conn action = bracket start end (action . fst) 156withTracker initProgress conn action = bracket start end (action . fst)
156 where 157 where
157 start = do 158 start = do
158 res <- sendRequest (startedReq conn initProgress) 159 resp <- askTracker (startedReq conn initProgress)
159 case res of 160 se <- newSession initProgress (respInterval resp) (respPeers resp)
160 Left err -> ioError (userError err) 161 tid <- forkIO (syncSession se)
161 Right (Failure err) -> ioError (userError (show err)) 162 return (se, tid)
162 Right resp -> do 163
163 se <- newSession initProgress (respInterval resp) (respPeers resp) 164 syncSession se @ TSession {..} = forever $ do
164 tid <- forkIO (syncSession se) 165 waitInterval se
165 return (se, tid) 166 pr <- getProgress se
166 167 resp <- tryJust isIOException $ do
167 168 askTracker (regularReq defaultNumWant conn pr)
168 syncSession se = do 169 case resp of
169 waitInterval se 170 Right (OK {..}) -> do
170 pr <- getProgress se 171 writeIORef seInterval respInterval
171 eresp <- sendRequest (regularReq defaultNumWant conn pr) 172 atomically $ writeTVar sePeers respPeers
172 case eresp of 173 _ -> return ()
173 Right (OK { respInterval = i, respPeers = ps }) -> do 174 where
174 writeIORef (seInterval se) i 175 isIOException :: IOException -> Maybe IOException
175 atomically $ writeTVar (sePeers se) ps 176 isIOException = return
176 _ -> return ()
177 syncSession se
178
179 177
180 end (se, tid) = do 178 end (se, tid) = do
181 killThread tid 179 killThread tid
182 getProgress se >>= sendRequest . stoppedReq conn 180 pr <- getProgress se
181 askTracker $ stoppedReq conn pr
diff --git a/src/Network/BitTorrent/Tracker/Protocol.hs b/src/Network/BitTorrent/Tracker/Protocol.hs
index 0371a187..af48e3e9 100644
--- a/src/Network/BitTorrent/Tracker/Protocol.hs
+++ b/src/Network/BitTorrent/Tracker/Protocol.hs
@@ -24,7 +24,7 @@ module Network.BitTorrent.Tracker.Protocol
24 ( module Network.BitTorrent.Tracker.Scrape 24 ( module Network.BitTorrent.Tracker.Scrape
25 25
26 , Event(..), TRequest(..), TResponse(..) 26 , Event(..), TRequest(..), TResponse(..)
27 , sendRequest 27 , askTracker
28 28
29 -- * Defaults 29 -- * Defaults
30 , defaultPorts, defaultNumWant 30 , defaultPorts, defaultNumWant
@@ -220,16 +220,21 @@ defaultPorts = [6881..6889]
220defaultNumWant :: Int 220defaultNumWant :: Int
221defaultNumWant = 25 221defaultNumWant = 25
222 222
223-- | TODO rename to ask for peers 223-- | Send request and receive response from the tracker specified in
224-- announce list. This function throws 'IOException' if it couldn't
225-- send request or receive response or decode response.
224-- 226--
225sendRequest :: TRequest -> IO (Result TResponse) 227askTracker :: TRequest -> IO TResponse
226sendRequest req = do 228askTracker req = do
227 let r = mkHTTPRequest (encodeRequest req) 229 let r = mkHTTPRequest (encodeRequest req)
228
229 rawResp <- simpleHTTP r
230 respBody <- getResponseBody rawResp
231 return (decoded respBody)
232 230
231 rawResp <- simpleHTTP r
232 respBody <- getResponseBody rawResp
233 checkResult $ decoded respBody
233 where 234 where
234 mkHTTPRequest :: URI -> Request ByteString 235 mkHTTPRequest :: URI -> Request ByteString
235 mkHTTPRequest uri = Request uri GET [] "" 236 mkHTTPRequest uri = Request uri GET [] ""
237
238 checkResult (Left err) = ioError (userError err)
239 checkResult (Right (Failure err)) = ioError (userError (show err))
240 checkResult (Right resp) = return resp