diff --git a/.github/workflows/haskell-ci.yml b/.github/workflows/haskell-ci.yml index 8002136..b496a25 100644 --- a/.github/workflows/haskell-ci.yml +++ b/.github/workflows/haskell-ci.yml @@ -32,6 +32,11 @@ jobs: strategy: matrix: include: + - compiler: ghc-9.14.0.20250819 + compilerKind: ghc + compilerVersion: 9.14.0.20250819 + setup-method: ghcup-prerelease + allow-failure: false - compiler: ghc-9.12.2 compilerKind: ghc compilerVersion: 9.12.2 @@ -126,6 +131,21 @@ jobs: HCKIND: ${{ matrix.compilerKind }} HCNAME: ${{ matrix.compiler }} HCVER: ${{ matrix.compilerVersion }} + - name: Install GHC (GHCup prerelease) + if: matrix.setup-method == 'ghcup-prerelease' + run: | + "$HOME/.ghcup/bin/ghcup" config add-release-channel prereleases + "$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false) + HC=$("$HOME/.ghcup/bin/ghcup" whereis ghc "$HCVER") + HCPKG=$(echo "$HC" | sed 's#ghc$#ghc-pkg#') + HADDOCK=$(echo "$HC" | sed 's#ghc$#haddock#') + echo "HC=$HC" >> "$GITHUB_ENV" + echo "HCPKG=$HCPKG" >> "$GITHUB_ENV" + echo "HADDOCK=$HADDOCK" >> "$GITHUB_ENV" + env: + HCKIND: ${{ matrix.compilerKind }} + HCNAME: ${{ matrix.compiler }} + HCVER: ${{ matrix.compilerVersion }} - name: Set PATH and environment variables run: | echo "$HOME/.cabal/bin" >> $GITHUB_PATH @@ -136,7 +156,7 @@ jobs: echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV" echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV" echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV" - echo "HEADHACKAGE=false" >> "$GITHUB_ENV" + if [ $((HCNUMVER >= 91400)) -ne 0 ] ; then echo "HEADHACKAGE=true" >> "$GITHUB_ENV" ; else echo "HEADHACKAGE=false" >> "$GITHUB_ENV" ; fi echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV" env: HCKIND: ${{ matrix.compilerKind }} @@ -164,6 +184,18 @@ jobs: repository hackage.haskell.org url: http://hackage.haskell.org/ EOF + if $HEADHACKAGE; then + cat >> $CABAL_CONFIG <> $CABAL_CONFIG <= 80200)) -ne 0 ] ; then echo " ghc-options: -Werror=missing-methods -Werror=missing-fields" >> cabal.project ; fi if [ $((HCNUMVER >= 90400)) -ne 0 ] ; then echo "package happstack-server" >> cabal.project ; fi if [ $((HCNUMVER >= 90400)) -ne 0 ] ; then echo " ghc-options: -Werror=unused-packages" >> cabal.project ; fi - if [ $((HCNUMVER >= 90000)) -ne 0 ] ; then echo "package happstack-server" >> cabal.project ; fi cat >> cabal.project <> cabal.project + fi $HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: any.$_ installed\n" unless /^(happstack-server)$/; }' >> cabal.project.local cat cabal.project cat cabal.project.local diff --git a/attic/Examples/AllIn.hs b/attic/Examples/AllIn.hs index 98cc22f..0f52611 100644 --- a/attic/Examples/AllIn.hs +++ b/attic/Examples/AllIn.hs @@ -16,7 +16,7 @@ import Happstack.Data.IxSet import qualified Data.Map as M ------------------------------------------------ --- Define a component of state +-- Define a component of state -- -- Real examples are HelpReqs, FlashMsgs, and sessions -- really you should put components in their own modules. @@ -29,15 +29,13 @@ import qualified Data.Map as M -- Lets start with defining a simple state component: Session type SesKey = Integer type ETime = Integer -newtype OldSession val = OldSession {old_unsession::[(SesKey,(ETime,val))]} - deriving (Typeable) +newtype OldSession val = OldSession {old_unsession::[(SesKey,(ETime,val))]} instance Version (OldSession val) $(deriveSerialize ''OldSession) newtype Session val = Session { unsession :: M.Map SesKey (ETime,val) } - deriving (Typeable) instance Migrate (OldSession val) (Session val) where migrate (OldSession sess) = Session (M.fromList sess) @@ -71,7 +69,7 @@ getSession :: SesKey -> Query (Session val) (Maybe val) getSession key = do val <- liftM (M.lookup key) askSession return (liftM snd val) -setSession key val = do +setSession key val = do t <- getTime modSession $ M.insert key (t,val) return () @@ -97,30 +95,30 @@ numSessions = proxyQuery $ liftM M.size askSession -- Declare these as methods. So you can access them from any IO via (query $ -- GetSession key) or (update $ setSession key val). When we can have --- Data for phantom types in 6.8.2 this will look nicer +-- Data for phantom types in 6.8.2 this will look nicer -$(mkMethods ''Session - ['newSession,'setSession, 'cleanSessions,'numSessions ,'getSession]) +$(mkMethods ''Session + ['newSession,'setSession, 'cleanSessions,'numSessions ,'getSession]) -- Sometimes you want maintenance on your component that the user -- doesn't want to worry about. maintainSessions v = do update $ CleanSessions 3600000 v threadDelay (10^6 * 10) -- Once every 10 seconds - maintainSessions v + maintainSessions v instance (Serialize a) => Component (Session a) where type Dependencies (Session a) = End initialValue = Session M.empty --- All components need an atStart declaration though the list can be empty +-- All components need an atStart declaration though the list can be empty -- Now we repeat the above for a more trivial example so we have --- multiple components in state. But we'll use the more concise deriveAll syntax +-- multiple components in state. But we'll use the more concise deriveAll syntax -- so you don't deal with the boilerplate of a zillion deriving declarations on each type. -data UserComponent key = UserComponent {unUserComponent :: key} deriving (Typeable) -data SingletonComponent = SingletonComponent {unSingleton :: String} deriving (Typeable) +data UserComponent key = UserComponent {unUserComponent :: key} +data SingletonComponent = SingletonComponent {unSingleton :: String} instance Version (UserComponent key) $(deriveSerialize ''UserComponent) @@ -183,7 +181,7 @@ $(deriveAll [''Show,''Default, ''Read] data State = State { privateInt :: Int , privateString :: String - } deriving (Typeable) + } instance Version State $(deriveSerialize ''State) @@ -227,7 +225,7 @@ impl = dir "setGet" $ msum mbComp <- getData comp <- maybe mzero return mbComp liftIO $ update $ SetComponent (comp :: Int) - ok comp -- returned as blah. + ok comp -- returned as blah. -- add the xslt wrapper to style the xml -- or write your own ToMessage instance for your return types ] diff --git a/attic/Examples/DistributedChat/DistributedChat.hs b/attic/Examples/DistributedChat/DistributedChat.hs index 6ec701d..d2d0efb 100644 --- a/attic/Examples/DistributedChat/DistributedChat.hs +++ b/attic/Examples/DistributedChat/DistributedChat.hs @@ -4,7 +4,6 @@ module Main (main) where import Happstack.State import Happstack.Server -import Data.Typeable ( Typeable ) import System.Environment ( getArgs, getProgName ) import System.Exit ( exitWith, ExitCode(ExitFailure) ) import Control.Monad.State ( put, get) @@ -21,7 +20,7 @@ type MessageId = Int data User = User { userNick :: Nick , userLastSeen :: MessageId } -data ChatState = ChatState MessageId [ (Nick, Message, MessageId) ] deriving (Typeable) +data ChatState = ChatState MessageId [ (Nick, Message, MessageId) ] instance Version ChatState $(deriveSerialize ''ChatState) @@ -73,7 +72,7 @@ main = bracket (startSystemStateMultimaster rootState) closeTxControl $ \ctl -> [ do mbUser <- getDataFn getUserFromCookie user <- maybe mzero return mbUser - msum + msum [ dir "send" $ do msg <- getDataFn (look "msg") >>= maybe mzero return update $ AddMessage (userNick user) msg @@ -82,14 +81,14 @@ main = bracket (startSystemStateMultimaster rootState) closeTxControl $ \ctl -> (newLast, msgs) <- liftIO $ getMessages (userLastSeen user) addCookie (-1) (mkCookie "last" (show newLast)) ok (toResponse (format msgs)) - + , dir "clear" $ do addCookie (-1) (mkCookie "last" (show 0)) ok (toResponse "") , fileServe [] "ChatRun.html" ] , dir "login" $ do - nick <- getDataFn (look "nick") >>= maybe mzero return + nick <- getDataFn (look "nick") >>= maybe mzero return addCookie (-1) (mkCookie "nick" nick) addCookie (-1) (mkCookie "last" (show 0)) seeOther "/" (toResponse "") diff --git a/attic/Examples/MultimasterTest1.hs b/attic/Examples/MultimasterTest1.hs index ae11e9b..8811ea6 100644 --- a/attic/Examples/MultimasterTest1.hs +++ b/attic/Examples/MultimasterTest1.hs @@ -1,14 +1,13 @@ -{-# LANGUAGE TemplateHaskell, DeriveDataTypeable, MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-} +{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-} module Main where import Happstack.Server import Happstack.State -import Data.Typeable import Control.Monad.State import Control.Monad.Reader -data MyState = MyState Int deriving (Typeable) +data MyState = MyState Int instance Version MyState $(deriveSerialize ''MyState) @@ -42,4 +41,3 @@ main = do ctl <- startSystemStateMultimaster rootState seeOther "/" "" , do val <- query GetVal ok $ "Value is: " ++ show val ] - diff --git a/attic/Examples/MultimasterTest2.hs b/attic/Examples/MultimasterTest2.hs index 63776ae..0ce0921 100644 --- a/attic/Examples/MultimasterTest2.hs +++ b/attic/Examples/MultimasterTest2.hs @@ -1,14 +1,13 @@ -{-# LANGUAGE TemplateHaskell, DeriveDataTypeable, MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-} +{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-} module Main where import Happstack.Server import Happstack.State -import Data.Typeable import Control.Monad.State import Control.Monad.Reader -data MyState = MyState Int deriving (Typeable) +data MyState = MyState Int instance Version MyState $(deriveSerialize ''MyState) @@ -41,4 +40,3 @@ main = do ctl <- startSystemStateMultimaster rootState seeOther "/" "" , do val <- query GetVal ok $ "Value is: " ++ show val ] - diff --git a/attic/Examples/Timer.hs b/attic/Examples/Timer.hs index 2fa091c..b72d666 100644 --- a/attic/Examples/Timer.hs +++ b/attic/Examples/Timer.hs @@ -3,12 +3,11 @@ module Timer where import Happstack.State import Happstack.Data -import Data.Typeable import Data.Generics import Control.Monad.State (modify) import Control.Concurrent -newtype Timer = Timer Int deriving (Typeable) +newtype Timer = Timer Int instance Version Timer $(deriveSerialize ''Timer) diff --git a/attic/Examples/dist-newstyle/cache/config b/attic/Examples/dist-newstyle/cache/config deleted file mode 100644 index c15a644..0000000 --- a/attic/Examples/dist-newstyle/cache/config +++ /dev/null @@ -1,38 +0,0 @@ -packages: ./*.cabal -optional-packages: ./*/*.cabal -remote-repo-cache: /home/ramiro/.cabal/packages -logs-dir: /home/ramiro/.cabal/logs -world-file: /home/ramiro/.cabal/world -verbose: 1 -solver: choose -build-summary: /home/ramiro/.cabal/logs/build.log -doc-index-file: $datadir/doc/$arch-$os-$compiler/index.html -max-backjumps: 2000 -reorder-goals: False -strong-flags: False -remote-build-reporting: anonymous -report-planning-failure: False -one-shot: False -jobs: $ncpus -offline: False -extra-prog-path: /home/ramiro/.cabal/bin -compiler: ghc -compiler: ghc -documentation: False -haddock-keep-temp-files: False -haddock-hoogle: False -haddock-html: False -haddock-executables: False -haddock-tests: False -haddock-benchmarks: False -haddock-internal: False -haddock-hyperlink-source: False - -repository hackage.haskell.org - url: http://hackage.haskell.org/ - root-keys: fe331502606802feac15e514d9b9ea83fee8b6ffef71335479a2e68d84adc6b0 - 1ea9ba32c526d1cc91ab5e5bd364ec5e9e8cb67179a471872f6e26f0ae773d42 - 2c6c3627bd6c982990239487f1abd02e08a02e6cf16edb105a8012d444d870c3 - 0a5c7ea47cd1b15f01f5f51a33adda7e655bc0f0b0615baa8e271f4c3351e21d - 51f0161b906011b52c6613376b1ae937670da69322113a246a09f807c62f6921 - key-threshold: 3 diff --git a/cabal.haskell-ci b/cabal.haskell-ci index e1f1b77..5c23f74 100644 --- a/cabal.haskell-ci +++ b/cabal.haskell-ci @@ -1 +1,3 @@ branches: master + +error-incomplete-patterns: False \ No newline at end of file diff --git a/happstack-server.cabal b/happstack-server.cabal index b0b27f5..1b2ca67 100644 --- a/happstack-server.cabal +++ b/happstack-server.cabal @@ -13,6 +13,7 @@ Cabal-Version: >= 1.10 Extra-Source-Files: tests/Happstack/Server/Tests.hs README.md tested-with: + GHC == 9.14.1 GHC == 9.12.2 GHC == 9.10.2 GHC == 9.8.2 diff --git a/src/Happstack/Server/Cookie.hs b/src/Happstack/Server/Cookie.hs index ffd6a57..7834adf 100644 --- a/src/Happstack/Server/Cookie.hs +++ b/src/Happstack/Server/Cookie.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE DeriveDataTypeable, FlexibleContexts #-} +{-# LANGUAGE FlexibleContexts #-} -- | Functions for creating, adding, and expiring cookies. To lookup cookie values see "Happstack.Server.RqData". module Happstack.Server.Cookie ( Cookie(..) @@ -19,7 +19,7 @@ import Happstack.Server.Types (Response, addHeader) -- | Add the 'Cookie' to 'Response'. -- -- example --- +-- -- > main = simpleHTTP nullConf $ -- > do addCookie Session (mkCookie "name" "value") -- > ok $ "You now have a session cookie." @@ -33,7 +33,7 @@ addCookie life cookie = addHeaderM a v = composeFilter $ \res-> addHeader a v res -- | Add the list 'Cookie' to the 'Response'. --- +-- -- see also: 'addCookie' addCookies :: (MonadIO m, FilterMonad Response m) => [(CookieLife, Cookie)] -> m () addCookies = mapM_ (uncurry addCookie) @@ -44,5 +44,5 @@ addCookies = mapM_ (uncurry addCookie) -- > do expireCookie "name" -- > ok $ "The cookie has been expired." -expireCookie :: (MonadIO m, FilterMonad Response m) => String -> m () +expireCookie :: (MonadIO m, FilterMonad Response m) => String -> m () expireCookie name = addCookie Expired (mkCookie name "") diff --git a/src/Happstack/Server/FileServe/BuildingBlocks.hs b/src/Happstack/Server/FileServe/BuildingBlocks.hs index 0eb8fff..71e1fc4 100644 --- a/src/Happstack/Server/FileServe/BuildingBlocks.hs +++ b/src/Happstack/Server/FileServe/BuildingBlocks.hs @@ -59,7 +59,7 @@ import Control.Monad (MonadPlus(mzero), msum) import Control.Monad.Trans (MonadIO(liftIO)) import qualified Data.ByteString.Lazy.Char8 as L import qualified Data.ByteString.Char8 as S -import Data.Data (Data, Typeable) +import Data.Data (Data) import Data.List (sort) import Data.Maybe (fromMaybe) import Data.Map (Map) @@ -523,7 +523,7 @@ browseIndex renderFn _serveFn _mimeFn _ixFiles localPath = listing <- renderFn localPath $ filter (/= ".") (sort c) ok $ toResponse $ listing -data EntryKind = File | Directory | UnknownKind deriving (Eq, Ord, Read, Show, Data, Typeable, Enum) +data EntryKind = File | Directory | UnknownKind deriving (Eq, Ord, Read, Show, Data, Enum) -- | a function to generate an HTML page showing the contents of a directory on the disk -- @@ -625,7 +625,7 @@ getMetaData localPath fp = -- | see 'serveDirectory' data Browsing = EnableBrowsing | DisableBrowsing - deriving (Eq, Enum, Ord, Read, Show, Data, Typeable) + deriving (Eq, Enum, Ord, Read, Show, Data) -- | Serve files and directories from a directory and its subdirectories using 'sendFile'. -- diff --git a/src/Happstack/Server/Internal/Cookie.hs b/src/Happstack/Server/Internal/Cookie.hs index 27ff9db..047876f 100644 --- a/src/Happstack/Server/Internal/Cookie.hs +++ b/src/Happstack/Server/Internal/Cookie.hs @@ -21,7 +21,7 @@ import Control.Monad import Control.Monad.Fail (MonadFail) import qualified Data.ByteString.Char8 as C import Data.Char (chr, toLower) -import Data.Data (Data, Typeable) +import Data.Data (Data) import Data.List ((\\), intersperse) import Data.Time.Clock (UTCTime, addUTCTime, diffUTCTime) import Data.Time.Clock.POSIX (posixSecondsToUTCTime) @@ -44,7 +44,7 @@ data Cookie = Cookie , httpOnly :: Bool , sameSite :: SameSite , partitioned :: Bool - } deriving(Show,Eq,Read,Typeable,Data) + } deriving (Show, Eq, Read, Data) -- | Specify the lifetime of a cookie. -- @@ -58,7 +58,7 @@ data CookieLife | MaxAge Int -- ^ life time of cookie in seconds | Expires UTCTime -- ^ cookie expiration date | Expired -- ^ cookie already expired - deriving (Eq, Ord, Read, Show, Typeable) + deriving (Eq, Ord, Read, Show) -- | Options for specifying third party cookie behaviour. -- @@ -75,7 +75,7 @@ data SameSite -- secure. | SameSiteNoValue -- ^ The default; used if you do not wish a SameSite attribute present at all. - deriving (Eq, Ord, Typeable, Data, Show, Read) + deriving (Eq, Ord, Data, Show, Read) displaySameSite :: SameSite -> String displaySameSite ss = diff --git a/src/Happstack/Server/Internal/Types.hs b/src/Happstack/Server/Internal/Types.hs index ed144b9..c2397d1 100644 --- a/src/Happstack/Server/Internal/Types.hs +++ b/src/Happstack/Server/Internal/Types.hs @@ -32,7 +32,6 @@ import qualified Data.Map as M import Data.Data (Data) import Data.String (fromString) import Data.Time.Format (FormatTime(..)) -import Data.Typeable(Typeable) import qualified Data.ByteString.Char8 as P import Data.ByteString.Char8 (ByteString,pack) import qualified Data.ByteString.Lazy.Char8 as L @@ -139,7 +138,7 @@ logMAccess host user time requestLine responseCode size referer userAgent = -- | HTTP request method data Method = GET | HEAD | POST | PUT | DELETE | TRACE | OPTIONS | CONNECT | PATCH | EXTENSION ByteString - deriving (Show,Read,Eq,Ord,Typeable,Data) + deriving (Show, Read, Eq, Ord, Data) -- | Does the method support a message body? -- @@ -179,7 +178,7 @@ data Length -- | Result flags data RsFlags = RsFlags { rsfLength :: Length - } deriving (Show,Read,Typeable) + } deriving (Show, Read) -- | Default RsFlags: automatically use @Transfer-Encoding: Chunked@. nullRsFlags :: RsFlags @@ -204,7 +203,7 @@ data Input = Input { inputValue :: Either FilePath L.ByteString , inputFilename :: Maybe FilePath , inputContentType :: ContentType - } deriving (Show, Read, Typeable) + } deriving (Show, Read) -- | hostname & port type Host = (String, Int) -- ^ (hostname, port) @@ -225,7 +224,6 @@ data Response , sfOffset :: Integer -- ^ offset to start at , sfCount :: Integer -- ^ number of bytes to send } - deriving (Typeable) instance Show Response where showsPrec _ res@Response{} = @@ -270,7 +268,7 @@ data Request = Request , rqHeaders :: Headers -- ^ the HTTP request headers , rqBody :: MVar RqBody -- ^ the raw, undecoded request body , rqPeer :: Host -- ^ (hostname, port) of the client making the request - } deriving (Typeable) + } instance Show Request where showsPrec _ rq = @@ -329,7 +327,7 @@ instance HasHeaders Headers where headers = id -- | The body of an HTTP 'Request' -newtype RqBody = Body { unBody :: L.ByteString } deriving (Read,Show,Typeable) +newtype RqBody = Body { unBody :: L.ByteString } deriving (Read, Show) -- | Sets the Response status code to the provided Int and lifts the computation -- into a Monad. @@ -531,7 +529,6 @@ instance FromReqURI Bool where -- | Escape from the HTTP world and get direct access to the underlying 'TimeoutIO' functions data EscapeHTTP = EscapeHTTP (TimeoutIO -> IO ()) - deriving (Typeable) instance Exception EscapeHTTP diff --git a/src/Happstack/Server/RqData.hs b/src/Happstack/Server/RqData.hs index 7e9a95f..17ad891 100644 --- a/src/Happstack/Server/RqData.hs +++ b/src/Happstack/Server/RqData.hs @@ -78,7 +78,7 @@ import qualified Data.ByteString.Lazy.Char8 as L import qualified Data.ByteString.Lazy.UTF8 as LU import Data.Char (toLower) import Data.Either (partitionEithers) -import Data.Generics (Data, Typeable) +import Data.Generics (Data) import Data.Maybe (fromJust) import Data.Monoid (Monoid(mempty, mappend, mconcat)) import qualified Data.Semigroup as SG @@ -134,7 +134,7 @@ apEither (Right f) (Right a) = Right (f a) -- | a list of errors newtype Errors a = Errors { unErrors :: [a] } - deriving (Eq, Ord, Show, Read, Data, Typeable) + deriving (Eq, Ord, Show, Read, Data) instance SG.Semigroup (Errors a) where (Errors x) <> (Errors y) = Errors (x ++ y) @@ -493,7 +493,7 @@ lookCookie name Nothing -> rqDataError $ strMsg $ "lookCookie: cookie not found: " ++ name Just c -> return c{cookieValue = f c} where - f = unEscapeString . cookieValue + f = unEscapeString . cookieValue -- | gets the named cookie as a string lookCookieValue :: (Functor m, Monad m, HasRqData m) => String -> m String diff --git a/src/Happstack/Server/SURI.hs b/src/Happstack/Server/SURI.hs index d030347..2fe612c 100644 --- a/src/Happstack/Server/SURI.hs +++ b/src/Happstack/Server/SURI.hs @@ -23,7 +23,7 @@ module Happstack.Server.SURI import Control.Arrow (first) import Data.Char (chr, digitToInt, isHexDigit) import Data.Maybe (fromJust, isJust) -import Data.Generics (Data, Typeable) +import Data.Generics (Data) import qualified Data.Text as Text import qualified Data.Text.Lazy as LazyText import qualified Network.URI as URI @@ -74,7 +74,7 @@ unEscape = percentDecode isAbs :: SURI -> Bool isAbs = not . null . URI.uriScheme . suri -newtype SURI = SURI {suri::URI.URI} deriving (Eq,Data,Typeable) +newtype SURI = SURI {suri::URI.URI} deriving (Eq,Data) instance Show SURI where showsPrec d (SURI uri) = showsPrec d $ show uri instance Read SURI where diff --git a/src/Happstack/Server/UDP.hs b/src/Happstack/Server/UDP.hs index 1d7ad6f..dedec4e 100644 --- a/src/Happstack/Server/UDP.hs +++ b/src/Happstack/Server/UDP.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE OverlappingInstances, FlexibleInstances, DeriveDataTypeable #-} +{-# LANGUAGE OverlappingInstances, FlexibleInstances #-} module Happstack.Server.UDP ( UDPConfig(..) , Request(..) @@ -9,7 +9,6 @@ module Happstack.Server.UDP import Control.Concurrent import Control.Exception as E import Control.Monad (liftM,foldM) -import Data.Typeable import Foreign import Foreign.Marshal import Happstack.Util.Common ( readM ) @@ -34,7 +33,7 @@ nullUDPConfig = UDPConfig { bodyLimit = 2 * 1024 } -data Request = Request { udpMsg :: BS.ByteString, udpAddr :: SockAddr} deriving Typeable +data Request = Request { udpMsg :: BS.ByteString, udpAddr :: SockAddr} instance Show Request where showsPrec n (Request bs (SockAddrInet port ip)) = showsPrec n (bs, port, ip) @@ -70,4 +69,3 @@ sendUDPMessage ip port msg = handle <- socketToHandle fd WriteMode BS.hPut handle msg hClose handle -