diff options
author | Sam Truzjan <pxqr.sta@gmail.com> | 2013-12-27 05:36:45 +0400 |
---|---|---|
committer | Sam Truzjan <pxqr.sta@gmail.com> | 2013-12-27 05:36:45 +0400 |
commit | e06b3dbd76a0a76c872ca27b4ea33b4465d14da3 (patch) | |
tree | f797719a25bce95a95a3b30e02b50af7a7e7520a /src/Network/BitTorrent/DHT/Message.hs | |
parent | 89151d4315631243840fcae54244c144ff42329d (diff) |
Fix get_peers response encoding
Diffstat (limited to 'src/Network/BitTorrent/DHT/Message.hs')
-rw-r--r-- | src/Network/BitTorrent/DHT/Message.hs | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/src/Network/BitTorrent/DHT/Message.hs b/src/Network/BitTorrent/DHT/Message.hs index 0733a85d..15d1099c 100644 --- a/src/Network/BitTorrent/DHT/Message.hs +++ b/src/Network/BitTorrent/DHT/Message.hs | |||
@@ -31,6 +31,7 @@ import Control.Applicative | |||
31 | import Data.BEncode as BE | 31 | import Data.BEncode as BE |
32 | import Data.BEncode.BDict | 32 | import Data.BEncode.BDict |
33 | import Data.ByteString as BS | 33 | import Data.ByteString as BS |
34 | import Data.List as L | ||
34 | import Data.Monoid | 35 | import Data.Monoid |
35 | import Data.Serialize as S | 36 | import Data.Serialize as S |
36 | import Data.Typeable | 37 | import Data.Typeable |
@@ -138,7 +139,7 @@ binary k = field (req k) >>= either (fail . format) return . | |||
138 | 139 | ||
139 | instance (Typeable ip, Serialize ip) => BEncode (NodeFound ip) where | 140 | instance (Typeable ip, Serialize ip) => BEncode (NodeFound ip) where |
140 | toBEncode (NodeFound ns) = toDict $ | 141 | toBEncode (NodeFound ns) = toDict $ |
141 | nodes_key .=! S.encode ns | 142 | nodes_key .=! runPut (mapM_ put ns) |
142 | .: endDict | 143 | .: endDict |
143 | 144 | ||
144 | fromBEncode = fromDict $ NodeFound <$> binary nodes_key | 145 | fromBEncode = fromDict $ NodeFound <$> binary nodes_key |
@@ -154,7 +155,7 @@ instance (Serialize ip, Typeable ip) | |||
154 | 155 | ||
155 | -- | Get peers associated with a torrent infohash. | 156 | -- | Get peers associated with a torrent infohash. |
156 | newtype GetPeers = GetPeers InfoHash | 157 | newtype GetPeers = GetPeers InfoHash |
157 | deriving Typeable | 158 | deriving (Show, Eq, Typeable) |
158 | 159 | ||
159 | info_hash_key :: BKey | 160 | info_hash_key :: BKey |
160 | info_hash_key = "info_hash" | 161 | info_hash_key = "info_hash" |
@@ -172,7 +173,7 @@ data GotPeers ip = GotPeers | |||
172 | -- | The token value is a required argument for a future | 173 | -- | The token value is a required argument for a future |
173 | -- announce_peer query. | 174 | -- announce_peer query. |
174 | , grantedToken :: Token | 175 | , grantedToken :: Token |
175 | } deriving Typeable | 176 | } deriving (Show, Eq, Typeable) |
176 | 177 | ||
177 | peers_key :: BKey | 178 | peers_key :: BKey |
178 | peers_key = "values" | 179 | peers_key = "values" |
@@ -182,17 +183,25 @@ token_key = "token" | |||
182 | 183 | ||
183 | instance (Typeable ip, Serialize ip) => BEncode (GotPeers ip) where | 184 | instance (Typeable ip, Serialize ip) => BEncode (GotPeers ip) where |
184 | toBEncode GotPeers {..} = toDict $ | 185 | toBEncode GotPeers {..} = toDict $ |
185 | putPeerList peers | 186 | case peers of |
186 | .: token_key .=! grantedToken | 187 | Left ns -> |
187 | .: endDict | 188 | nodes_key .=! runPut (mapM_ put ns) |
188 | where | 189 | .: token_key .=! grantedToken |
189 | putPeerList (Right ps) = peers_key .=! S.encode ps | 190 | .: endDict |
190 | putPeerList (Left ns) = nodes_key .=! S.encode ns | 191 | Right ps -> |
192 | token_key .=! grantedToken | ||
193 | .: peers_key .=! L.map S.encode ps | ||
194 | .: endDict | ||
191 | 195 | ||
192 | fromBEncode = fromDict $ GotPeers <$> getPeerList <*>! token_key | 196 | fromBEncode = fromDict $ do |
193 | where | 197 | mns <- optional (binary nodes_key) -- "nodes" |
194 | getPeerList = Right <$> binary peers_key | 198 | tok <- field (req token_key) -- "token" |
195 | <|> Left <$> binary nodes_key | 199 | mps <- optional (field (req peers_key) >>= decodePeers) -- "values" |
200 | case (Right <$> mps) <|> (Left <$> mns) of | ||
201 | Nothing -> fail "get_peers: neihter peers nor nodes key is valid" | ||
202 | Just xs -> pure $ GotPeers xs tok | ||
203 | where | ||
204 | decodePeers = either fail pure . mapM S.decode | ||
196 | 205 | ||
197 | instance (Typeable ip, Serialize ip) => | 206 | instance (Typeable ip, Serialize ip) => |
198 | KRPC (Query GetPeers) (Response (GotPeers ip)) where | 207 | KRPC (Query GetPeers) (Response (GotPeers ip)) where |
@@ -213,7 +222,7 @@ data Announce = Announce | |||
213 | 222 | ||
214 | -- | received in response to a previous get_peers query. | 223 | -- | received in response to a previous get_peers query. |
215 | , sessionToken :: Token | 224 | , sessionToken :: Token |
216 | } deriving Typeable | 225 | } deriving (Show, Eq, Typeable) |
217 | 226 | ||
218 | port_key :: BKey | 227 | port_key :: BKey |
219 | port_key = "port" | 228 | port_key = "port" |
@@ -235,6 +244,7 @@ instance BEncode Announce where | |||
235 | -- port number under the infohash in its store of peer contact | 244 | -- port number under the infohash in its store of peer contact |
236 | -- information. | 245 | -- information. |
237 | data Announced = Announced | 246 | data Announced = Announced |
247 | deriving (Show, Eq, Typeable) | ||
238 | 248 | ||
239 | instance BEncode Announced where | 249 | instance BEncode Announced where |
240 | toBEncode _ = toBEncode Ping | 250 | toBEncode _ = toBEncode Ping |