|
Packit |
acf257 |
-----------------------------------------------------------------------------
|
|
Packit |
acf257 |
-- |
|
|
Packit |
acf257 |
-- Module : Network.Stream
|
|
Packit |
acf257 |
-- Copyright : See LICENSE file
|
|
Packit |
acf257 |
-- License : BSD
|
|
Packit |
acf257 |
--
|
|
Packit |
acf257 |
-- Maintainer : Ganesh Sittampalam <ganesh@earth.li>
|
|
Packit |
acf257 |
-- Stability : experimental
|
|
Packit |
acf257 |
-- Portability : non-portable (not tested)
|
|
Packit |
acf257 |
--
|
|
Packit |
acf257 |
-- An library for creating abstract streams. Originally part of Gray's\/Bringert's
|
|
Packit |
acf257 |
-- HTTP module.
|
|
Packit |
acf257 |
--
|
|
Packit |
acf257 |
-- * Changes by Robin Bate Boerop <robin@bateboerop.name>:
|
|
Packit |
acf257 |
-- - Removed unnecessary import statements.
|
|
Packit |
acf257 |
-- - Moved Debug code to StreamDebugger.hs
|
|
Packit |
acf257 |
-- - Moved Socket-related code to StreamSocket.hs.
|
|
Packit |
acf257 |
--
|
|
Packit |
acf257 |
-- * Changes by Simon Foster:
|
|
Packit |
acf257 |
-- - Split Network.HTTPmodule up into to separate
|
|
Packit |
acf257 |
-- Network.[Stream,TCP,HTTP] modules
|
|
Packit |
acf257 |
-----------------------------------------------------------------------------
|
|
Packit |
acf257 |
module Network.Stream
|
|
Packit |
acf257 |
( Stream(..)
|
|
Packit |
acf257 |
, ConnError(..)
|
|
Packit |
acf257 |
, Result
|
|
Packit |
acf257 |
, bindE
|
|
Packit |
acf257 |
, fmapE
|
|
Packit |
acf257 |
|
|
Packit |
acf257 |
, failParse -- :: String -> Result a
|
|
Packit |
acf257 |
, failWith -- :: ConnError -> Result a
|
|
Packit |
acf257 |
, failMisc -- :: String -> Result a
|
|
Packit |
acf257 |
) where
|
|
Packit |
acf257 |
|
|
Packit |
acf257 |
import Control.Monad.Error
|
|
Packit |
acf257 |
|
|
Packit |
acf257 |
data ConnError
|
|
Packit |
acf257 |
= ErrorReset
|
|
Packit |
acf257 |
| ErrorClosed
|
|
Packit |
acf257 |
| ErrorParse String
|
|
Packit |
acf257 |
| ErrorMisc String
|
|
Packit |
acf257 |
deriving(Show,Eq)
|
|
Packit |
acf257 |
|
|
Packit |
acf257 |
instance Error ConnError where
|
|
Packit |
acf257 |
noMsg = strMsg "unknown error"
|
|
Packit |
acf257 |
strMsg x = ErrorMisc x
|
|
Packit |
acf257 |
|
|
Packit |
acf257 |
-- in GHC 7.0 the Monad instance for Error no longer
|
|
Packit |
acf257 |
-- uses fail x = Left (strMsg x). failMisc is therefore
|
|
Packit |
acf257 |
-- used instead.
|
|
Packit |
acf257 |
failMisc :: String -> Result a
|
|
Packit |
acf257 |
failMisc x = failWith (strMsg x)
|
|
Packit |
acf257 |
|
|
Packit |
acf257 |
failParse :: String -> Result a
|
|
Packit |
acf257 |
failParse x = failWith (ErrorParse x)
|
|
Packit |
acf257 |
|
|
Packit |
acf257 |
failWith :: ConnError -> Result a
|
|
Packit |
acf257 |
failWith x = Left x
|
|
Packit |
acf257 |
|
|
Packit |
acf257 |
bindE :: Result a -> (a -> Result b) -> Result b
|
|
Packit |
acf257 |
bindE (Left e) _ = Left e
|
|
Packit |
acf257 |
bindE (Right v) f = f v
|
|
Packit |
acf257 |
|
|
Packit |
acf257 |
fmapE :: (a -> Result b) -> IO (Result a) -> IO (Result b)
|
|
Packit |
acf257 |
fmapE f a = do
|
|
Packit |
acf257 |
x <- a
|
|
Packit |
acf257 |
case x of
|
|
Packit |
acf257 |
Left e -> return (Left e)
|
|
Packit |
acf257 |
Right r -> return (f r)
|
|
Packit |
acf257 |
|
|
Packit |
acf257 |
-- | This is the type returned by many exported network functions.
|
|
Packit |
acf257 |
type Result a = Either ConnError {- error -}
|
|
Packit |
acf257 |
a {- result -}
|
|
Packit |
acf257 |
|
|
Packit |
acf257 |
-- | Streams should make layering of TLS protocol easier in future,
|
|
Packit |
acf257 |
-- they allow reading/writing to files etc for debugging,
|
|
Packit |
acf257 |
-- they allow use of protocols other than TCP/IP
|
|
Packit |
acf257 |
-- and they allow customisation.
|
|
Packit |
acf257 |
--
|
|
Packit |
acf257 |
-- Instances of this class should not trim
|
|
Packit |
acf257 |
-- the input in any way, e.g. leave LF on line
|
|
Packit |
acf257 |
-- endings etc. Unless that is exactly the behaviour
|
|
Packit |
acf257 |
-- you want from your twisted instances ;)
|
|
Packit |
acf257 |
class Stream x where
|
|
Packit |
acf257 |
readLine :: x -> IO (Result String)
|
|
Packit |
acf257 |
readBlock :: x -> Int -> IO (Result String)
|
|
Packit |
acf257 |
writeBlock :: x -> String -> IO (Result ())
|
|
Packit |
acf257 |
close :: x -> IO ()
|
|
Packit |
acf257 |
closeOnEnd :: x -> Bool -> IO ()
|
|
Packit |
acf257 |
-- ^ True => shutdown the connection when response has been read / end-of-stream
|
|
Packit |
acf257 |
-- has been reached.
|