summaryrefslogtreecommitdiff
path: root/src/Data/Torrent
diff options
context:
space:
mode:
authorSam Truzjan <pxqr.sta@gmail.com>2013-10-31 17:58:44 +0400
committerSam Truzjan <pxqr.sta@gmail.com>2013-10-31 17:58:44 +0400
commit7fdfc614afb912539aa4597882067b1779f661a6 (patch)
treeb2428c43b4d2fc873162f4f2f06e89c90760edb3 /src/Data/Torrent
parente03b2165b7e88c70751780ec35b79bdb5e3a2adb (diff)
Fix InfoHash json encoding
Diffstat (limited to 'src/Data/Torrent')
-rw-r--r--src/Data/Torrent/InfoHash.hs29
-rw-r--r--src/Data/Torrent/Magnet.hs15
2 files changed, 28 insertions, 16 deletions
diff --git a/src/Data/Torrent/InfoHash.hs b/src/Data/Torrent/InfoHash.hs
index 71ea0260..5ec429b5 100644
--- a/src/Data/Torrent/InfoHash.hs
+++ b/src/Data/Torrent/InfoHash.hs
@@ -3,10 +3,10 @@
3module Data.Torrent.InfoHash 3module Data.Torrent.InfoHash
4 ( -- * Info hash 4 ( -- * Info hash
5 InfoHash(..) 5 InfoHash(..)
6 , textToInfoHash
6 , addHashToURI 7 , addHashToURI
7 , ppInfoHash 8 , ppInfoHash
8 9
9
10 , Data.Torrent.InfoHash.hash 10 , Data.Torrent.InfoHash.hash
11 , Data.Torrent.InfoHash.hashlazy 11 , Data.Torrent.InfoHash.hashlazy
12 ) where 12 ) where
@@ -20,6 +20,7 @@ import Data.ByteString as BS
20import Data.ByteString.Char8 as BC 20import Data.ByteString.Char8 as BC
21import Data.ByteString.Lazy as BL 21import Data.ByteString.Lazy as BL
22import Data.ByteString.Base16 as Base16 22import Data.ByteString.Base16 as Base16
23import Data.ByteString.Base32 as Base32
23import qualified Data.ByteString.Lazy.Builder as B 24import qualified Data.ByteString.Lazy.Builder as B
24import qualified Data.ByteString.Lazy.Builder.ASCII as B 25import qualified Data.ByteString.Lazy.Builder.ASCII as B
25import Data.Char 26import Data.Char
@@ -28,6 +29,8 @@ import Data.Hashable as Hashable
28import Data.URLEncoded as URL 29import Data.URLEncoded as URL
29import Data.Serialize 30import Data.Serialize
30import Data.String 31import Data.String
32import Data.Text
33import Data.Text.Encoding as T
31import Network.URI 34import Network.URI
32import Numeric 35import Numeric
33import Text.ParserCombinators.ReadP as P 36import Text.ParserCombinators.ReadP as P
@@ -36,7 +39,7 @@ import Text.PrettyPrint
36 39
37-- | Exactly 20 bytes long SHA1 hash of the info part of torrent file. 40-- | Exactly 20 bytes long SHA1 hash of the info part of torrent file.
38newtype InfoHash = InfoHash { getInfoHash :: BS.ByteString } 41newtype InfoHash = InfoHash { getInfoHash :: BS.ByteString }
39 deriving (Eq, Ord, ToJSON, FromJSON) 42 deriving (Eq, Ord)
40 43
41-- | for hex encoded strings 44-- | for hex encoded strings
42instance Show InfoHash where 45instance Show InfoHash where
@@ -74,9 +77,31 @@ instance Serialize InfoHash where
74 put = putByteString . getInfoHash 77 put = putByteString . getInfoHash
75 get = InfoHash <$> getBytes 20 78 get = InfoHash <$> getBytes 20
76 79
80-- | Represented as base16 encoded string.
81instance ToJSON InfoHash where
82 toJSON (InfoHash ih) = String $ T.decodeUtf8 $ Base16.encode ih
83
84-- | Can be base16 or base32 encoded string.
85instance FromJSON InfoHash where
86 parseJSON = withText "JSON" $
87 maybe (fail "could not parse InfoHash") pure . textToInfoHash
88
77instance URLShow InfoHash where 89instance URLShow InfoHash where
78 urlShow = show 90 urlShow = show
79 91
92-- | Tries both base16 and base32 while decoding info hash.
93textToInfoHash :: Text -> Maybe InfoHash
94textToInfoHash text
95 | hashLen == 32 = Just $ InfoHash $ Base32.decode hashStr
96 | hashLen == 40 = let (ihStr, inv) = Base16.decode hashStr
97 in if BS.length inv == 0
98 then Just $ InfoHash ihStr
99 else Nothing
100 | otherwise = Nothing
101 where
102 hashLen = BS.length hashStr
103 hashStr = T.encodeUtf8 text
104
80-- | Hash strict bytestring using SHA1 algorithm. 105-- | Hash strict bytestring using SHA1 algorithm.
81hash :: BS.ByteString -> InfoHash 106hash :: BS.ByteString -> InfoHash
82hash = InfoHash . C.hash 107hash = InfoHash . C.hash
diff --git a/src/Data/Torrent/Magnet.hs b/src/Data/Torrent/Magnet.hs
index df928b66..34a7bbc5 100644
--- a/src/Data/Torrent/Magnet.hs
+++ b/src/Data/Torrent/Magnet.hs
@@ -27,16 +27,12 @@ module Data.Torrent.Magnet
27 27
28import Control.Applicative 28import Control.Applicative
29import Control.Monad 29import Control.Monad
30import Data.ByteString as BS
31import Data.ByteString.Base16 as Base16
32import Data.ByteString.Base32 as Base32
33import Data.Map as M 30import Data.Map as M
34import Data.Maybe 31import Data.Maybe
35import Data.List as L 32import Data.List as L
36import Data.URLEncoded as URL 33import Data.URLEncoded as URL
37import Data.String 34import Data.String
38import Data.Text as T 35import Data.Text as T
39import Data.Text.Encoding as T
40import Network.URI 36import Network.URI
41import Text.Read 37import Text.Read
42 38
@@ -90,16 +86,7 @@ renderURN URN {..}
90urnToInfoHash :: URN -> Maybe InfoHash 86urnToInfoHash :: URN -> Maybe InfoHash
91urnToInfoHash (URN {..}) 87urnToInfoHash (URN {..})
92 | urnNamespace /= btih = Nothing 88 | urnNamespace /= btih = Nothing
93 | hashLen == 20 = Just $ InfoHash hashStr 89 | otherwise = textToInfoHash urnString
94 | hashLen == 32 = Just $ InfoHash $ Base32.decode hashStr
95 | hashLen == 40 = let (ihStr, inv) = Base16.decode hashStr
96 in if BS.length inv == 0
97 then Just $ InfoHash ihStr
98 else Nothing
99 | otherwise = Nothing
100 where
101 hashLen = BS.length hashStr
102 hashStr = T.encodeUtf8 urnString
103 90
104infoHashToURN :: InfoHash -> URN 91infoHashToURN :: InfoHash -> URN
105infoHashToURN = URN btih . T.pack . show 92infoHashToURN = URN btih . T.pack . show