diff options
author | Sam Truzjan <pxqr.sta@gmail.com> | 2013-10-31 17:58:44 +0400 |
---|---|---|
committer | Sam Truzjan <pxqr.sta@gmail.com> | 2013-10-31 17:58:44 +0400 |
commit | 7fdfc614afb912539aa4597882067b1779f661a6 (patch) | |
tree | b2428c43b4d2fc873162f4f2f06e89c90760edb3 /src | |
parent | e03b2165b7e88c70751780ec35b79bdb5e3a2adb (diff) |
Fix InfoHash json encoding
Diffstat (limited to 'src')
-rw-r--r-- | src/Data/Torrent/InfoHash.hs | 29 | ||||
-rw-r--r-- | src/Data/Torrent/Magnet.hs | 15 |
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 @@ | |||
3 | module Data.Torrent.InfoHash | 3 | module 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 | |||
20 | import Data.ByteString.Char8 as BC | 20 | import Data.ByteString.Char8 as BC |
21 | import Data.ByteString.Lazy as BL | 21 | import Data.ByteString.Lazy as BL |
22 | import Data.ByteString.Base16 as Base16 | 22 | import Data.ByteString.Base16 as Base16 |
23 | import Data.ByteString.Base32 as Base32 | ||
23 | import qualified Data.ByteString.Lazy.Builder as B | 24 | import qualified Data.ByteString.Lazy.Builder as B |
24 | import qualified Data.ByteString.Lazy.Builder.ASCII as B | 25 | import qualified Data.ByteString.Lazy.Builder.ASCII as B |
25 | import Data.Char | 26 | import Data.Char |
@@ -28,6 +29,8 @@ import Data.Hashable as Hashable | |||
28 | import Data.URLEncoded as URL | 29 | import Data.URLEncoded as URL |
29 | import Data.Serialize | 30 | import Data.Serialize |
30 | import Data.String | 31 | import Data.String |
32 | import Data.Text | ||
33 | import Data.Text.Encoding as T | ||
31 | import Network.URI | 34 | import Network.URI |
32 | import Numeric | 35 | import Numeric |
33 | import Text.ParserCombinators.ReadP as P | 36 | import 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. |
38 | newtype InfoHash = InfoHash { getInfoHash :: BS.ByteString } | 41 | newtype 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 |
42 | instance Show InfoHash where | 45 | instance 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. | ||
81 | instance ToJSON InfoHash where | ||
82 | toJSON (InfoHash ih) = String $ T.decodeUtf8 $ Base16.encode ih | ||
83 | |||
84 | -- | Can be base16 or base32 encoded string. | ||
85 | instance FromJSON InfoHash where | ||
86 | parseJSON = withText "JSON" $ | ||
87 | maybe (fail "could not parse InfoHash") pure . textToInfoHash | ||
88 | |||
77 | instance URLShow InfoHash where | 89 | instance URLShow InfoHash where |
78 | urlShow = show | 90 | urlShow = show |
79 | 91 | ||
92 | -- | Tries both base16 and base32 while decoding info hash. | ||
93 | textToInfoHash :: Text -> Maybe InfoHash | ||
94 | textToInfoHash 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. |
81 | hash :: BS.ByteString -> InfoHash | 106 | hash :: BS.ByteString -> InfoHash |
82 | hash = InfoHash . C.hash | 107 | hash = 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 | ||
28 | import Control.Applicative | 28 | import Control.Applicative |
29 | import Control.Monad | 29 | import Control.Monad |
30 | import Data.ByteString as BS | ||
31 | import Data.ByteString.Base16 as Base16 | ||
32 | import Data.ByteString.Base32 as Base32 | ||
33 | import Data.Map as M | 30 | import Data.Map as M |
34 | import Data.Maybe | 31 | import Data.Maybe |
35 | import Data.List as L | 32 | import Data.List as L |
36 | import Data.URLEncoded as URL | 33 | import Data.URLEncoded as URL |
37 | import Data.String | 34 | import Data.String |
38 | import Data.Text as T | 35 | import Data.Text as T |
39 | import Data.Text.Encoding as T | ||
40 | import Network.URI | 36 | import Network.URI |
41 | import Text.Read | 37 | import Text.Read |
42 | 38 | ||
@@ -90,16 +86,7 @@ renderURN URN {..} | |||
90 | urnToInfoHash :: URN -> Maybe InfoHash | 86 | urnToInfoHash :: URN -> Maybe InfoHash |
91 | urnToInfoHash (URN {..}) | 87 | urnToInfoHash (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 | ||
104 | infoHashToURN :: InfoHash -> URN | 91 | infoHashToURN :: InfoHash -> URN |
105 | infoHashToURN = URN btih . T.pack . show | 92 | infoHashToURN = URN btih . T.pack . show |