summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam T <pxqr.sta@gmail.com>2013-06-07 19:14:41 +0400
committerSam T <pxqr.sta@gmail.com>2013-06-07 19:14:41 +0400
commit13819af69d4a99f97eaf8ae439baeb6de37a1f5f (patch)
tree25710835624effca5d87a633cecdfbc3667e9836
parent7f299646b8c761f28b101b6232cc183712dcfa2e (diff)
~ Throw exception in askTracker.
HTTP client functions throws an exception. If we unable to decode result we return BEncode.Result.Left. So user of this function should check both kinds of errors and this complicate usage. Instead of this we throw IOException too.
-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