diff options
Diffstat (limited to 'src/Network/BitTorrent/Tracker/Wai.hs')
-rw-r--r-- | src/Network/BitTorrent/Tracker/Wai.hs | 64 |
1 files changed, 41 insertions, 23 deletions
diff --git a/src/Network/BitTorrent/Tracker/Wai.hs b/src/Network/BitTorrent/Tracker/Wai.hs index 69510fa0..29e0e952 100644 --- a/src/Network/BitTorrent/Tracker/Wai.hs +++ b/src/Network/BitTorrent/Tracker/Wai.hs | |||
@@ -16,6 +16,7 @@ module Network.BitTorrent.Tracker.Wai | |||
16 | , tracker | 16 | , tracker |
17 | ) where | 17 | ) where |
18 | 18 | ||
19 | import Control.Applicative | ||
19 | import Control.Monad.Trans.Resource | 20 | import Control.Monad.Trans.Resource |
20 | import Data.BEncode as BE | 21 | import Data.BEncode as BE |
21 | import Data.ByteString | 22 | import Data.ByteString |
@@ -30,9 +31,12 @@ import Network.BitTorrent.Tracker.Message | |||
30 | 31 | ||
31 | -- | Various configuration settings used to generate tracker response. | 32 | -- | Various configuration settings used to generate tracker response. |
32 | data TrackerSettings = TrackerSettings | 33 | data TrackerSettings = TrackerSettings |
33 | { -- | If peer did not specified the "numwant" then this value is | 34 | { announcePath :: !RawPath |
35 | , scrapePath :: !RawPath | ||
36 | |||
37 | -- | If peer did not specified the "numwant" then this value is | ||
34 | -- used. | 38 | -- used. |
35 | defNumWant :: {-# UNPACK #-} !Int | 39 | , defNumWant :: {-# UNPACK #-} !Int |
36 | 40 | ||
37 | -- | If peer specified too big numwant value. | 41 | -- | If peer specified too big numwant value. |
38 | , maxNumWant :: {-# UNPACK #-} !Int | 42 | , maxNumWant :: {-# UNPACK #-} !Int |
@@ -63,7 +67,9 @@ data TrackerSettings = TrackerSettings | |||
63 | -- | Conservative tracker settings compatible with any client. | 67 | -- | Conservative tracker settings compatible with any client. |
64 | instance Default TrackerSettings where | 68 | instance Default TrackerSettings where |
65 | def = TrackerSettings | 69 | def = TrackerSettings |
66 | { defNumWant = defaultNumWant | 70 | { announcePath = defaultAnnouncePath |
71 | , scrapePath = defaultScrapePath | ||
72 | , defNumWant = defaultNumWant | ||
67 | , maxNumWant = defaultMaxNumWant | 73 | , maxNumWant = defaultMaxNumWant |
68 | , reannounceInterval = defaultReannounceInterval | 74 | , reannounceInterval = defaultReannounceInterval |
69 | , reannounceMinInterval = Nothing | 75 | , reannounceMinInterval = Nothing |
@@ -73,34 +79,46 @@ instance Default TrackerSettings where | |||
73 | , noPeerId = False | 79 | , noPeerId = False |
74 | } | 80 | } |
75 | 81 | ||
82 | |||
83 | |||
84 | {----------------------------------------------------------------------- | ||
85 | -- Handlers | ||
86 | -----------------------------------------------------------------------} | ||
87 | |||
76 | getAnnounceR :: TrackerSettings -> AnnounceRequest -> ResourceT IO AnnounceInfo | 88 | getAnnounceR :: TrackerSettings -> AnnounceRequest -> ResourceT IO AnnounceInfo |
77 | getAnnounceR = undefined | 89 | getAnnounceR = undefined |
78 | 90 | ||
79 | getScrapeR :: TrackerSettings -> ScrapeQuery -> ResourceT IO ScrapeInfo | 91 | getScrapeR :: TrackerSettings -> ScrapeQuery -> ResourceT IO ScrapeInfo |
80 | getScrapeR = undefined | 92 | getScrapeR = undefined |
81 | 93 | ||
94 | {----------------------------------------------------------------------- | ||
95 | -- Routing | ||
96 | -----------------------------------------------------------------------} | ||
97 | |||
98 | announceResponse :: AnnounceInfo -> Response | ||
99 | announceResponse info = responseLBS ok200 headers $ BE.encode info | ||
100 | where | ||
101 | headers = [(hContentType, announceType)] | ||
102 | |||
103 | scrapeResponse :: ScrapeInfo -> Response | ||
104 | scrapeResponse info = responseLBS ok200 headers $ BE.encode info | ||
105 | where | ||
106 | headers = [(hContentType, scrapeType)] | ||
107 | |||
82 | -- content-type: "text/plain"! | 108 | -- content-type: "text/plain"! |
83 | tracker :: TrackerSettings -> Application | 109 | tracker :: TrackerSettings -> Application |
84 | tracker settings Request {..} | 110 | tracker settings @ TrackerSettings {..} Request {..} |
85 | | requestMethod /= methodGet | 111 | | requestMethod /= methodGet |
86 | = return $ responseLBS methodNotAllowed405 [] "" | 112 | = return $ responseLBS methodNotAllowed405 [] "" |
87 | 113 | ||
88 | | otherwise = do | 114 | | rawPathInfo == announcePath = do |
89 | case pathInfo of | 115 | case parseAnnounceRequest $ queryToSimpleQuery queryString of |
90 | ["announce"] -> | 116 | Right query -> announceResponse <$> getAnnounceR settings query |
91 | case parseAnnounceRequest $ queryToSimpleQuery queryString of | 117 | Left msg -> return $ responseLBS (parseFailureStatus msg) [] "" |
92 | Right query -> do | 118 | |
93 | info <- getAnnounceR settings query | 119 | | rawPathInfo == scrapePath = do |
94 | return $ responseLBS ok200 [] $ BE.encode info | 120 | case Right $ parseScrapeQuery $ queryToSimpleQuery queryString of -- TODO |
95 | Left msg -> | 121 | Right query -> scrapeResponse <$> getScrapeR settings query |
96 | return $ responseLBS (parseFailureStatus msg) [] "" | 122 | Left msg -> return $ responseLBS badRequest400 [] "" |
97 | 123 | ||
98 | ["scrape"] -> | 124 | | otherwise = undefined --badPath |
99 | case Right $ parseScrapeQuery $ queryToSimpleQuery queryString of -- TODO | ||
100 | Right query -> do | ||
101 | info <- getScrapeR settings query | ||
102 | return $ responseLBS ok200 [] $ BE.encode info | ||
103 | Left _ -> | ||
104 | return $ responseLBS badRequest400 [] "" | ||
105 | |||
106 | _ -> undefined --badPath | ||