diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Network/BitTorrent/Tracker.hs | 43 | ||||
-rw-r--r-- | src/Network/BitTorrent/Tracker/Protocol.hs | 23 |
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 #-} | ||
11 | module Network.BitTorrent.Tracker | 12 | module 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 | |||
155 | withTracker initProgress conn action = bracket start end (action . fst) | 156 | withTracker 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] | |||
220 | defaultNumWant :: Int | 220 | defaultNumWant :: Int |
221 | defaultNumWant = 25 | 221 | defaultNumWant = 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 | -- |
225 | sendRequest :: TRequest -> IO (Result TResponse) | 227 | askTracker :: TRequest -> IO TResponse |
226 | sendRequest req = do | 228 | askTracker 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 | ||