summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam T <pxqr.sta@gmail.com>2013-06-07 03:37:11 +0400
committerSam T <pxqr.sta@gmail.com>2013-06-07 03:37:11 +0400
commit095f22bba763aba8303322b104ae39e2ff2807c2 (patch)
tree2743e5c025e6934b247cee593fd693c23bb01892 /src
parent558616b7dcc8955ab08fe8b194cdd5e128aba3f4 (diff)
~ Fix bug in torrent bencode instance.
Also add encoding tests for torrent module.
Diffstat (limited to 'src')
-rw-r--r--src/Data/Torrent.hs59
1 files changed, 44 insertions, 15 deletions
diff --git a/src/Data/Torrent.hs b/src/Data/Torrent.hs
index 16b94828..3175e151 100644
--- a/src/Data/Torrent.hs
+++ b/src/Data/Torrent.hs
@@ -17,6 +17,7 @@
17-- <https://wiki.theory.org/BitTorrentSpecification#Metainfo_File_Structure> 17-- <https://wiki.theory.org/BitTorrentSpecification#Metainfo_File_Structure>
18-- 18--
19{-# OPTIONS -fno-warn-orphans #-} 19{-# OPTIONS -fno-warn-orphans #-}
20{-# LANGUAGE CPP #-}
20{-# LANGUAGE FlexibleInstances #-} 21{-# LANGUAGE FlexibleInstances #-}
21{-# LANGUAGE OverloadedStrings #-} 22{-# LANGUAGE OverloadedStrings #-}
22{-# LANGUAGE RecordWildCards #-} 23{-# LANGUAGE RecordWildCards #-}
@@ -24,6 +25,7 @@
24module Data.Torrent 25module Data.Torrent
25 ( -- * Torrent 26 ( -- * Torrent
26 Torrent(..), ContentInfo(..), FileInfo(..) 27 Torrent(..), ContentInfo(..), FileInfo(..)
28 , torrent, simpleTorrent
27 , fromFile 29 , fromFile
28 30
29 -- * Files layout 31 -- * Files layout
@@ -32,15 +34,21 @@ module Data.Torrent
32 , isSingleFile, isMultiFile 34 , isSingleFile, isMultiFile
33 35
34 -- * Info hash 36 -- * Info hash
35 , InfoHash, ppInfoHash 37#if defined (TESTING)
36 , hash, hashlazy 38 , InfoHash(..)
39#else
40 , InfoHash
41#endif
42 , ppInfoHash
37 , addHashToURI 43 , addHashToURI
38 44
39 -- * Extra 45 -- * Extra
40 , sizeInBase 46 , sizeInBase
41 47
48#if defined (TESTING)
42 -- * Internal 49 -- * Internal
43 , InfoHash(..) 50 , hash, hashlazy
51#endif
44 ) where 52 ) where
45 53
46import Prelude hiding (sum) 54import Prelude hiding (sum)
@@ -79,6 +87,10 @@ data Torrent = Torrent {
79 , tAnnounce :: URI 87 , tAnnounce :: URI
80 -- ^ The URL of the tracker. 88 -- ^ The URL of the tracker.
81 89
90 -- NOTE: out of lexicographic order!
91 , tInfo :: ContentInfo
92 -- ^ Info about each content file.
93
82 , tAnnounceList :: Maybe [[URI]] 94 , tAnnounceList :: Maybe [[URI]]
83 -- ^ Announce list add multiple tracker support. 95 -- ^ Announce list add multiple tracker support.
84 -- 96 --
@@ -97,9 +109,6 @@ data Torrent = Torrent {
97 -- ^ String encoding format used to generate the pieces part of 109 -- ^ String encoding format used to generate the pieces part of
98 -- the info dictionary in the .torrent metafile. 110 -- the info dictionary in the .torrent metafile.
99 111
100 , tInfo :: ContentInfo
101 -- ^ Info about each content file.
102
103 , tPublisher :: Maybe URI 112 , tPublisher :: Maybe URI
104 -- ^ Containing the RSA public key of the publisher of the torrent. 113 -- ^ Containing the RSA public key of the publisher of the torrent.
105 -- Private counterpart of this key that has the authority to allow 114 -- Private counterpart of this key that has the authority to allow
@@ -109,7 +118,26 @@ data Torrent = Torrent {
109 , tSignature :: Maybe ByteString 118 , tSignature :: Maybe ByteString
110 -- ^ The RSA signature of the info dictionary (specifically, 119 -- ^ The RSA signature of the info dictionary (specifically,
111 -- the encrypted SHA-1 hash of the info dictionary). 120 -- the encrypted SHA-1 hash of the info dictionary).
112 } deriving Show 121 } deriving (Show, Eq)
122
123{- note that info hash is actually reduntant field
124 but it's better to keep it here to avoid heavy recomputations
125-}
126
127-- | Smart constructor for 'Torrent' which compute info hash.
128torrent :: URI -> ContentInfo
129 -> Maybe [[URI]] -> Maybe Text -> Maybe ByteString
130 -> Maybe Time -> Maybe ByteString -> Maybe URI
131 -> Maybe URI -> Maybe ByteString
132 -> Torrent
133torrent announce info = Torrent (hashlazy (BE.encoded info)) announce info
134
135-- | A simple torrent contains only required fields.
136simpleTorrent :: URI -> ContentInfo -> Torrent
137simpleTorrent announce info = torrent announce info
138 Nothing Nothing Nothing
139 Nothing Nothing Nothing
140 Nothing Nothing
113 141
114-- | Info part of the .torrent file contain info about each content file. 142-- | Info part of the .torrent file contain info about each content file.
115data ContentInfo = 143data ContentInfo =
@@ -133,8 +161,9 @@ data ContentInfo =
133 -- ^ Concatenation of all 20-byte SHA1 hash values. 161 -- ^ Concatenation of all 20-byte SHA1 hash values.
134 162
135 , ciPrivate :: Maybe Bool 163 , ciPrivate :: Maybe Bool
136 -- ^ If set the client MUST publish its presence to get other peers ONLY 164 -- ^ If set the client MUST publish its presence to get other
137 -- via the trackers explicity described in the metainfo file. 165 -- peers ONLY via the trackers explicity described in the
166 -- metainfo file.
138 -- 167 --
139 -- BEP 27: <http://www.bittorrent.org/beps/bep_0027.html> 168 -- BEP 27: <http://www.bittorrent.org/beps/bep_0027.html>
140 } 169 }
@@ -162,10 +191,10 @@ data FileInfo = FileInfo {
162 -- Used by third-party tools, not by bittorrent protocol itself. 191 -- Used by third-party tools, not by bittorrent protocol itself.
163 192
164 , fiPath :: [ByteString] 193 , fiPath :: [ByteString]
165 -- ^ One or more string elements that together represent the path and 194 -- ^ One or more string elements that together represent the
166 -- filename. Each element in the list corresponds to either a directory 195 -- path and filename. Each element in the list corresponds to
167 -- name or (in the case of the last element) the filename. 196 -- either a directory name or (in the case of the last
168 -- For example, the file 197 -- element) the filename. For example, the file:
169 -- 198 --
170 -- > "dir1/dir2/file.ext" 199 -- > "dir1/dir2/file.ext"
171 -- 200 --
@@ -201,15 +230,15 @@ instance BEncodable Torrent where
201 fromBEncode (BDict d) | Just info <- M.lookup "info" d = 230 fromBEncode (BDict d) | Just info <- M.lookup "info" d =
202 Torrent <$> pure (hashlazy (BE.encode info)) -- WARN 231 Torrent <$> pure (hashlazy (BE.encode info)) -- WARN
203 <*> d >-- "announce" 232 <*> d >-- "announce"
233 <*> d >-- "info"
204 <*> d >--? "announce-list" 234 <*> d >--? "announce-list"
205 <*> d >--? "comment" 235 <*> d >--? "comment"
206 <*> d >--? "created by" 236 <*> d >--? "created by"
207 <*> d >--? "creation date" 237 <*> d >--? "creation date"
208 <*> d >--? "encoding" 238 <*> d >--? "encoding"
209 <*> d >-- "info"
210 <*> d >--? "publisher" 239 <*> d >--? "publisher"
211 <*> d >--? "publisher-url" 240 <*> d >--? "publisher-url"
212 <*> d >--? "singature" 241 <*> d >--? "signature"
213 242
214 fromBEncode _ = decodingError "Torrent" 243 fromBEncode _ = decodingError "Torrent"
215 244