summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Truzjan <pxqr.sta@gmail.com>2013-11-22 19:11:18 +0400
committerSam Truzjan <pxqr.sta@gmail.com>2013-11-22 19:11:18 +0400
commit1c8361e1a8fb9c1c9bb703958eebddfc204b223a (patch)
tree9f1067cc863cbb352cd91c0cce1c1b82959d758c
parentf8c8ee7ab66e3cf9202e14970757a2d8a94acdac (diff)
Add announce query parsing
-rw-r--r--src/Network/BitTorrent/Tracker/HTTP.hs2
-rw-r--r--src/Network/BitTorrent/Tracker/Message.hs90
2 files changed, 86 insertions, 6 deletions
diff --git a/src/Network/BitTorrent/Tracker/HTTP.hs b/src/Network/BitTorrent/Tracker/HTTP.hs
index 2d49436d..b466b49e 100644
--- a/src/Network/BitTorrent/Tracker/HTTP.hs
+++ b/src/Network/BitTorrent/Tracker/HTTP.hs
@@ -69,7 +69,7 @@ mkGET uri = Request uri GET [] ""
69-- 69--
70announceHTTP :: HTTPTracker -> AnnounceQuery -> IO AnnounceInfo 70announceHTTP :: HTTPTracker -> AnnounceQuery -> IO AnnounceInfo
71announceHTTP HTTPTracker {..} req = do 71announceHTTP HTTPTracker {..} req = do
72 let r = mkGET (encodeRequest announceURI req) 72 let r = mkGET (renderAnnounceQuery announceURI req)
73 73
74 rawResp <- simpleHTTP r 74 rawResp <- simpleHTTP r
75 respBody <- getResponseBody rawResp 75 respBody <- getResponseBody rawResp
diff --git a/src/Network/BitTorrent/Tracker/Message.hs b/src/Network/BitTorrent/Tracker/Message.hs
index 508ff4c5..22733a51 100644
--- a/src/Network/BitTorrent/Tracker/Message.hs
+++ b/src/Network/BitTorrent/Tracker/Message.hs
@@ -28,12 +28,15 @@ module Network.BitTorrent.Tracker.Message
28 -- ** Request 28 -- ** Request
29 Event(..) 29 Event(..)
30 , AnnounceQuery(..) 30 , AnnounceQuery(..)
31 , encodeRequest 31 , renderAnnounceQuery
32 , ParamParseFailure
33 , parseAnnounceQuery
32 34
33 -- ** Response 35 -- ** Response
34 , PeerList (..) 36 , PeerList (..)
35 , AnnounceInfo(..) 37 , AnnounceInfo(..)
36 , defaultNumWant 38 , defaultNumWant
39 , paramFailureCode
37 40
38 -- * Scrape 41 -- * Scrape
39 , ScrapeQuery 42 , ScrapeQuery
@@ -209,10 +212,73 @@ instance Serialize AnnounceQuery where
209 , reqEvent = ev 212 , reqEvent = ev
210 } 213 }
211 214
212encodeRequest :: URI -> AnnounceQuery -> URI 215-- | Encoding announce query and add it to the base tracker URL.
213encodeRequest announceURI req = URL.urlEncode req 216renderAnnounceQuery :: URI -> AnnounceQuery -> URI
214 `addToURI` announceURI 217renderAnnounceQuery announceURI req
215 `addHashToURI` reqInfoHash req 218 = URL.urlEncode req
219 `addToURI` announceURI
220 `addHashToURI` reqInfoHash req
221
222data QueryParam
223 = ParamInfoHash
224 | ParamPeerId
225 | ParamPort
226 | ParamProgress
227 | ParamIP
228 | ParamNumWant
229 | ParamEvent
230 deriving (Show, Eq, Ord, Enum)
231
232data ParamParseFailure
233 = Missing QueryParam -- ^ param not found in query string
234 | Invalid QueryParam -- ^ param present but not valid.
235
236type ParamResult = Either ParamParseFailure
237
238textToPeerId :: Text -> Maybe PeerId
239textToPeerId = undefined
240
241textToPortNumber :: Text -> Maybe PortNumber
242textToPortNumber = undefined
243
244textToHostAddress :: Text -> Maybe HostAddress
245textToHostAddress = undefined
246
247textToNumWant :: Text -> Maybe Int
248textToNumWant = undefined
249
250textToEvent :: Text -> Maybe Event
251textToEvent = undefined
252
253paramName :: QueryParam -> Text
254paramName ParamInfoHash = "info_hash"
255paramName ParamPeerId = "peer_id"
256paramName ParamPort = "port"
257
258-- | Parse announce request from a query string.
259parseAnnounceQuery :: [(Text, Text)] -> Either ParamParseFailure AnnounceQuery
260parseAnnounceQuery params = AnnounceQuery
261 <$> reqParam ParamInfoHash textToInfoHash params
262 <*> reqParam ParamPeerId textToPeerId params
263 <*> reqParam ParamPort textToPortNumber params
264 <*> progress params
265 <*> optParam ParamIP textToHostAddress params
266 <*> optParam ParamNumWant textToNumWant params
267 <*> optParam ParamEvent textToEvent params
268 where
269 withError e = maybe (Left e) Right
270 reqParam param p = withError (Missing param) . L.lookup (paramName param)
271 >=> withError (Invalid param) . p
272
273 optParam param p ps
274 | Just x <- L.lookup (paramName param) ps
275 = pure <$> withError (Invalid param) (p x)
276 | otherwise = pure Nothing
277
278 progress = undefined
279 ip = undefined
280 numwant = undefined
281 event = undefined
216 282
217{----------------------------------------------------------------------- 283{-----------------------------------------------------------------------
218-- Announce response 284-- Announce response
@@ -336,6 +402,20 @@ instance Serialize AnnounceInfo where
336defaultNumWant :: Int 402defaultNumWant :: Int
337defaultNumWant = 50 403defaultNumWant = 50
338 404
405missingOffset :: Int
406missingOffset = 101
407
408invalidOffset :: Int
409invalidOffset = 150
410
411-- | Get
412--
413-- For more info see:
414-- <https://wiki.theory.org/BitTorrent_Tracker_Protocol#Response_Codes>
415paramFailureCode :: ParamParseFailure -> Int
416paramFailureCode (Missing param) = missingOffset + fromEnum param
417paramFailureCode (Invalid param) = invalidOffset + fromEnum param
418
339{----------------------------------------------------------------------- 419{-----------------------------------------------------------------------
340 Scrape message 420 Scrape message
341-----------------------------------------------------------------------} 421-----------------------------------------------------------------------}