implemented high-level logic for strFromConn

This commit is contained in:
Jonathan Lamothe 2021-11-19 19:30:54 -05:00
parent 489d0fdb78
commit 4a99e5cb0b
2 changed files with 63 additions and 12 deletions

View File

@ -34,10 +34,16 @@ time.
module Network.Gemini.Capsule.Internal ( module Network.Gemini.Capsule.Internal (
readURL, readURL,
sendResponse sendResponse,
strFromConn,
readMax,
stripCRLF
) where ) where
import qualified Data.ByteString as BS
import Data.Connection (Connection) import Data.Connection (Connection)
import qualified Data.Text as T
import Data.Text.Encoding (decodeUtf8')
import Network.Gemini.Capsule.Encoding import Network.Gemini.Capsule.Encoding
import Network.Gemini.Capsule.Types import Network.Gemini.Capsule.Types
@ -76,6 +82,28 @@ strFromConn
-> Connection a -> Connection a
-- ^ The connection to read from -- ^ The connection to read from
-> IO (Maybe String) -> IO (Maybe String)
strFromConn = undefined strFromConn maxLen conn = do
mbs <- readMax maxLen conn
return $ do
bs <- mbs
txt <- case decodeUtf8' bs of
Left _ -> Nothing
Right s -> Just s
stripCRLF $ T.unpack txt
-- | Reads from a connection up to a maximum number of bytes,
-- returning 'Nothing' if the limit is exceeded
readMax
:: Int
-- ^ the maximum number of bytes
-> Connection a
-- ^ the 'Connection' to read from
-> IO (Maybe BS.ByteString)
readMax = undefined
-- | Strips the CR/LF characters from the end of a string, retuning
-- Nothing if they are not present
stripCRLF :: String -> Maybe String
stripCRLF = undefined
--jl --jl

View File

@ -38,6 +38,8 @@ spec = describe "Internal" $ do
readURLSpec readURLSpec
sendResponseSpec sendResponseSpec
strFromConnSpec strFromConnSpec
readMaxSpec
stripCRLFSpec
readURLSpec :: Spec readURLSpec :: Spec
readURLSpec = describe "readURL" $ mapM_ readURLSpec = describe "readURL" $ mapM_
@ -56,10 +58,10 @@ readURLSpec = describe "readURL" $ mapM_
] ]
where where
validConn = mkConn "gemini://example.com/\r\n" validConn = mkInConn ["gemini://example.com/\r\n"]
longConn = mkConn longBS longConn = mkInConn [longBS]
tooLongConn = mkConn tooLongBS tooLongConn = mkInConn [tooLongBS]
gibConn = mkConn "aosidjfwoeinboijwefr" gibConn = mkInConn ["aosidjfwoeinboijwefr"]
longBS = BS.pack (take 1024 bytes) <> "\r\n" longBS = BS.pack (take 1024 bytes) <> "\r\n"
tooLongBS = BS.pack (take 1025 bytes) <> "\r\n" tooLongBS = BS.pack (take 1025 bytes) <> "\r\n"
bytes = BS.unpack prefix ++ repeat (fromIntegral $ ord 'A') bytes = BS.unpack prefix ++ repeat (fromIntegral $ ord 'A')
@ -67,14 +69,32 @@ readURLSpec = describe "readURL" $ mapM_
longExp = validExp { gemPath = [longDir] } longExp = validExp { gemPath = [longDir] }
longDir = replicate (1024 - BS.length prefix) 'A' longDir = replicate (1024 - BS.length prefix) 'A'
prefix = "gemini://example.com/" prefix = "gemini://example.com/"
mkConn bs = do
s <- nullInput
unRead bs s
return sampleConnection { source = s }
sendResponseSpec :: Spec sendResponseSpec :: Spec
sendResponseSpec = describe "sendResponse" $ return () sendResponseSpec = describe "sendResponse" $ return ()
strFromConnSpec :: Spec
strFromConnSpec = describe "strFromConn" $ mapM_
( \(desc, maxLen, ioConn, expect) -> context desc $
xit ("should return " ++ show expect) $ do
conn <- ioConn
strFromConn maxLen conn `shouldReturn` expect
)
-- description, max size, connection, expected
[ ( "valid string", 100, mkInConn ["foo\r\n"], Just "foo" )
, ( "long string", 5, mkInConn ["too long\r\n"], Nothing )
, ( "no CR/LF", 100, mkInConn ["foo"], Nothing )
, ( "bad UTF-8", 100, mkInConn ["foo\xff\r\n"], Nothing )
, ( "non-ASCII", 100, mkInConn ["\xc3\xa9\r\n"], Just "\xe9" )
]
mkInConn :: [BS.ByteString] -> IO (Connection a)
mkInConn bss = do
s <- nullInput
mapM_ (`unRead` s) (reverse bss)
return sampleConnection { source = s }
sampleConnection :: Connection a sampleConnection :: Connection a
sampleConnection = Connection sampleConnection = Connection
{ source = undefined { source = undefined
@ -83,7 +103,10 @@ sampleConnection = Connection
, connExtraInfo = undefined , connExtraInfo = undefined
} }
strFromConnSpec :: Spec readMaxSpec :: Spec
strFromConnSpec = describe "strFromConn" $ return () readMaxSpec = describe "readMax" $ return ()
stripCRLFSpec :: Spec
stripCRLFSpec = describe "stripCRLF" $ return ()
--jl --jl