{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE StrictData #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Language.Symantic.HTTP ( module Language.Symantic.HTTP , module Language.Symantic.HTTP.API , module Language.Symantic.HTTP.Layout , module Language.Symantic.HTTP.Media , module Language.Symantic.HTTP.Router ) where -- import qualified Data.ByteString.Lazy as BSL import Control.Applicative (Applicative(..)) import Control.Monad () import Data.Bool import Data.Either (Either(..)) import Data.Function (($)) import Data.Functor ((<$>), (<$)) import Data.Maybe (Maybe(..)) import Data.Proxy (Proxy(..)) import Data.Semigroup (Semigroup(..)) import Data.String (IsString(..)) import System.IO (IO) import Prelude (error) import Text.Show (Show(..)) import qualified Data.Text as Text import qualified Data.Time as Time import qualified Network.HTTP.Media as Media import qualified Network.HTTP.Types as HTTP import qualified Network.HTTP.Types.Header as HTTP import qualified Network.Wai as Wai import qualified Network.Wai.Handler.Warp as Warp import Language.Symantic.HTTP.API import Language.Symantic.HTTP.Media import Language.Symantic.HTTP.Router import Language.Symantic.HTTP.Layout -- * Type 'API0' data API0 = API0_Date Time.Day | API0_Time Time.ZonedTime | API0_Reset Bool deriving (Show) instance IsString Time.TimeZone where fromString s = case s of "CEST" -> Time.TimeZone 2 True "CEST" "CET" -> Time.TimeZone 1 False "CET" _ -> error "unknown TimeZone" api0 :: HTTP_API repr => repr () api0 = () <$ method_GET <+> () <$ method_POST api00 :: HTTP_API repr => repr () api00 = () <$ method_GET <+> () <$ method_POST <+> () <$ method_HEAD api000 :: HTTP_API repr => repr () api000 = () <$ method_GET <+> () <$ method_POST <+> () <$ method_HEAD <+> () <$ method_PUT api1 f0 f1 = f0 <$ segment "time" <*> capture "timezone" <*> endpoint HTTP.methodGet plainText <+> f1 <$ segment "date" <*> endpoint HTTP.methodGet plainText lay1 :: Layout () lay1 = api1 (\_tz (Proxy::Proxy ()) -> ()) (\(Proxy::Proxy ()) -> ()) rou1 :: Router Application rou1 = api1 (\tz (RouterEndpoint respond) _rq re -> do time <- Time.utcToZonedTime (fromString $ Text.unpack tz) <$> Time.getCurrentTime re $ Right $ respond (HTTP.mkStatus 200 "") [] $ show time <> "\n") (\(RouterEndpoint respond) _rq re -> do date <- Time.utctDay <$> Time.getCurrentTime re $ Right $ respond (HTTP.mkStatus 200 "") [] $ show date <> "\n") srv1 :: IO () srv1 = Warp.run 8080 $ runRouterApp rou1 {- api2 :: HTTP_API repr => repr Application api2 = (\too respond _rq re -> re $ Right $ respond (HTTP.mkStatus 200 "") [] too) <$ segment "me" <*> capture "too" <*> endpoint HTTP.methodGet plainText api3 f = f <$ segment "me" <*> capture "too" <*> capture "too" -} req1_1 :: Wai.Request req1_1 = Wai.defaultRequest { Wai.requestMethod = HTTP.methodGet , Wai.pathInfo = ["date"] , Wai.requestHeaders = [ (HTTP.hAccept, Media.renderHeader $ mediaType plainText) ] } req1_2 :: Wai.Request req1_2 = Wai.defaultRequest { Wai.requestMethod = HTTP.methodGet , Wai.pathInfo = ["time", "CEST"] , Wai.requestHeaders = [ (HTTP.hAccept, Media.renderHeader $ mediaType plainText) ] } req1_3 :: Wai.Request req1_3 = Wai.defaultRequest { Wai.requestMethod = HTTP.methodPost , Wai.pathInfo = ["clock"] , Wai.queryString = [ ("reset", Just "1") ] } req1_KO_1 :: Wai.Request req1_KO_1 = Wai.defaultRequest { Wai.requestMethod = HTTP.methodPut , Wai.pathInfo = ["time", "CEST"] , Wai.requestHeaders = [ (HTTP.hAccept, Media.renderHeader $ mediaType plainText) ] } req1_KO_2 :: Wai.Request req1_KO_2 = Wai.defaultRequest { Wai.requestMethod = HTTP.methodGet , Wai.pathInfo = ["non-existent"] , Wai.requestHeaders = [ (HTTP.hAccept, Media.renderHeader $ mediaType plainText) ] } req1_KO_3 :: Wai.Request req1_KO_3 = Wai.defaultRequest { Wai.requestMethod = HTTP.methodGet , Wai.pathInfo = ["date"] , Wai.requestHeaders = [ (HTTP.hAccept, "application/non-sense") ] } req1_KO_4 :: Wai.Request req1_KO_4 = Wai.defaultRequest { Wai.requestMethod = HTTP.methodGet , Wai.pathInfo = ["date"] , Wai.requestHeaders = [ (HTTP.hHost, "example.com") ] } req1_KO_5 :: Wai.Request req1_KO_5 = Wai.defaultRequest { Wai.requestMethod = HTTP.methodPost , Wai.pathInfo = ["clock"] , Wai.queryString = [ ("reset", Just "NaN") ] } {- test :: IO () test = do forM_ [ req1_1, req1_2, req1_3 , req1_KO_1, req1_KO_2, req1_KO_3, req1_KO_4, req1_KO_5 ] $ \req -> do runRouterIO api1 req -}