diff options
author | Sam Truzjan <pxqr.sta@gmail.com> | 2014-02-04 05:13:57 +0400 |
---|---|---|
committer | Sam Truzjan <pxqr.sta@gmail.com> | 2014-02-04 05:13:57 +0400 |
commit | fe07542caf980e24d2e2fc4ec829ea2286f17367 (patch) | |
tree | 92c6d30677f69fbe64f1e4a2b4f0cecdf4683a86 /src/Network/BitTorrent | |
parent | db2a46723d2303093c2470f8409226051d69e3a3 (diff) |
[HTTP Tracker]: allow to specify path
Diffstat (limited to 'src/Network/BitTorrent')
-rw-r--r-- | src/Network/BitTorrent/Tracker/Message.hs | 24 | ||||
-rw-r--r-- | src/Network/BitTorrent/Tracker/Wai.hs | 64 |
2 files changed, 62 insertions, 26 deletions
diff --git a/src/Network/BitTorrent/Tracker/Message.hs b/src/Network/BitTorrent/Tracker/Message.hs index 54de44f7..dc8794b6 100644 --- a/src/Network/BitTorrent/Tracker/Message.hs +++ b/src/Network/BitTorrent/Tracker/Message.hs | |||
@@ -51,8 +51,6 @@ module Network.BitTorrent.Tracker.Message | |||
51 | , defaultNumWant | 51 | , defaultNumWant |
52 | , defaultMaxNumWant | 52 | , defaultMaxNumWant |
53 | , defaultReannounceInterval | 53 | , defaultReannounceInterval |
54 | , announceType | ||
55 | , parseFailureStatus | ||
56 | 54 | ||
57 | -- * Scrape | 55 | -- * Scrape |
58 | -- ** Query | 56 | -- ** Query |
@@ -64,6 +62,14 @@ module Network.BitTorrent.Tracker.Message | |||
64 | , ScrapeEntry (..) | 62 | , ScrapeEntry (..) |
65 | , ScrapeInfo | 63 | , ScrapeInfo |
66 | 64 | ||
65 | -- * HTTP specific | ||
66 | , RawPath | ||
67 | , defaultAnnouncePath | ||
68 | , defaultScrapePath | ||
69 | , announceType | ||
70 | , scrapeType | ||
71 | , parseFailureStatus | ||
72 | |||
67 | -- * Extra | 73 | -- * Extra |
68 | , queryToSimpleQuery | 74 | , queryToSimpleQuery |
69 | ) | 75 | ) |
@@ -615,6 +621,14 @@ defaultMaxNumWant = 200 | |||
615 | defaultReannounceInterval :: Int | 621 | defaultReannounceInterval :: Int |
616 | defaultReannounceInterval = 30 * 60 | 622 | defaultReannounceInterval = 30 * 60 |
617 | 623 | ||
624 | type RawPath = BS.ByteString | ||
625 | |||
626 | defaultAnnouncePath :: RawPath | ||
627 | defaultAnnouncePath = "announce" | ||
628 | |||
629 | defaultScrapePath :: RawPath | ||
630 | defaultScrapePath = "scrape" | ||
631 | |||
618 | missingOffset :: Int | 632 | missingOffset :: Int |
619 | missingOffset = 101 | 633 | missingOffset = 101 |
620 | 634 | ||
@@ -630,10 +644,14 @@ parseFailureMessage e = BS.concat $ case e of | |||
630 | Missing p -> ["Missing parameter: ", paramName p] | 644 | Missing p -> ["Missing parameter: ", paramName p] |
631 | Invalid p v -> ["Invalid parameter: ", paramName p, " = ", v] | 645 | Invalid p v -> ["Invalid parameter: ", paramName p, " = ", v] |
632 | 646 | ||
633 | -- | HTTP response /content type/. | 647 | -- | HTTP response /content type/ for announce info. |
634 | announceType :: ByteString | 648 | announceType :: ByteString |
635 | announceType = "text/plain" | 649 | announceType = "text/plain" |
636 | 650 | ||
651 | -- | HTTP response /content type/ for scrape info. | ||
652 | scrapeType :: ByteString | ||
653 | scrapeType = "text/plain" | ||
654 | |||
637 | -- | Get HTTP response status from a announce params parse failure. | 655 | -- | Get HTTP response status from a announce params parse failure. |
638 | -- | 656 | -- |
639 | -- For more info see: | 657 | -- For more info see: |
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 | ||