Network.HTTP.Lucu.Request
Network.HTTP.Lucu.Resource
Network.HTTP.Lucu.Response
+ Network.HTTP.Lucu.Response.StatusCode
Network.HTTP.Lucu.SocketLike
Network.HTTP.Lucu.StaticFile
- Network.HTTP.Lucu.StatusCode
Network.HTTP.Lucu.Utils
Other-Modules:
Network.HTTP.Lucu.Preprocess
Network.HTTP.Lucu.RequestReader
Network.HTTP.Lucu.Resource.Internal
+ Network.HTTP.Lucu.Response.StatusCode.Internal
Network.HTTP.Lucu.ResponseWriter
- Network.HTTP.Lucu.StatusCode.Internal
ghc-options:
-Wall
, Method(..)
-- *** 'StatusCode'
- , module Network.HTTP.Lucu.StatusCode
+ , module Network.HTTP.Lucu.Response.StatusCode
-- *** 'Abortion'
, module Network.HTTP.Lucu.Abortion
import Network.HTTP.Lucu.MIMEType
import Network.HTTP.Lucu.Request
import Network.HTTP.Lucu.Resource
-import Network.HTTP.Lucu.Response
+import Network.HTTP.Lucu.Response.StatusCode
import Network.HTTP.Lucu.StaticFile
-import Network.HTTP.Lucu.StatusCode
import Network.HTTP.Lucu.Utils
import Data.Monoid.Unicode
import Data.Text (Text)
import Network.HTTP.Lucu.Abortion.Internal
-import Network.HTTP.Lucu.Response
+import Network.HTTP.Lucu.Response.StatusCode
import Prelude.Unicode
-- |Construct an 'Abortion' with additional headers and an optional
import Network.HTTP.Lucu.Headers
import Network.HTTP.Lucu.Request
import Network.HTTP.Lucu.Response
+import Network.HTTP.Lucu.Response.StatusCode
-- |'Abortion' is an 'Exception' that aborts the execution of
-- 'Network.HTTP.Lucu.Rsrc' monad with a 'StatusCode', additional
import Network.HTTP.Lucu.Headers
import Network.HTTP.Lucu.Request
import Network.HTTP.Lucu.Response
+import Network.HTTP.Lucu.Response.StatusCode
import Network.URI hiding (path)
import Prelude hiding (head)
import Prelude.Unicode
hostMap = HMap
-- |Container type for the 'HostMapper' type class.
-data HostMap = ∀α. HostMapper α ⇒ HMap α
+data HostMap = ∀α. HostMapper α ⇒ HMap !α
-- |Class of maps from resource 'Path' to 'Resource'.
--
resourceMap = RMap
-- |Container type for the 'ResourceMapper' type class.
-data ResourceMap = ∀α. ResourceMapper α ⇒ RMap α
+data ResourceMap = ∀α. ResourceMapper α ⇒ RMap !α
-- |'ResourceTree' is an opaque structure which a map from resource
-- 'Path' to 'ResourceNode'.
import Network.HTTP.Lucu.Preprocess
import Network.HTTP.Lucu.Request
import Network.HTTP.Lucu.Response
+import Network.HTTP.Lucu.Response.StatusCode
import Network.HTTP.Lucu.Utils
#if defined(HAVE_SSL)
import OpenSSL.X509
)
where
import Control.Applicative hiding (empty)
+import Control.Monad
import Data.Ascii (Ascii)
import qualified Data.Ascii as A
import Data.ByteString (ByteString)
import Prelude hiding (last, mapM, null, reverse)
import Prelude.Unicode
+instance Applicative Q where
+ {-# INLINE pure #-}
+ pure = return
+ {-# INLINE (<*>) #-}
+ (<*>) = ap
+
instance Lift ByteString where
lift bs = [| Strict.pack $(litE ∘ stringL $ Strict.unpack bs) |]
import Network.HTTP.Lucu.Interaction
import Network.HTTP.Lucu.Request
import Network.HTTP.Lucu.Response
+import Network.HTTP.Lucu.Response.StatusCode
import Prelude.Unicode
postprocess ∷ NormalInteraction → STM ()
import Network.HTTP.Lucu.Headers
import Network.HTTP.Lucu.HttpVersion
import Network.HTTP.Lucu.Request
-import Network.HTTP.Lucu.Response
+import Network.HTTP.Lucu.Response.StatusCode
import Network.Socket
import Network.URI
import Prelude.Unicode
, UnicodeSyntax
, ViewPatterns
#-}
--- |Definition of things related on HTTP request.
---
--- In general you don't have to use this module directly.
+-- |Definition of HTTP requests.
module Network.HTTP.Lucu.Request
( Method(..)
, Request(..)
import Network.URI
import Prelude.Unicode
--- |This is the definition of HTTP request methods, which shouldn't
--- require any descriptions.
+-- |Definition of HTTP request methods.
data Method = OPTIONS
| GET
| HEAD
| ExtensionMethod !Ascii
deriving (Eq, Show)
--- |This is the definition of an HTTP reqest.
+-- |Definition of HTTP requests.
data Request
= Request {
reqMethod ∷ !Method
| m ≡ PUT = True
| otherwise = False
+instance Default (Parser Method) where
+ {-# INLINEABLE def #-}
+ def = choice
+ [ string "OPTIONS" ≫ return OPTIONS
+ , string "GET" ≫ return GET
+ , string "HEAD" ≫ return HEAD
+ , string "POST" ≫ return POST
+ , string "PUT" ≫ return PUT
+ , string "DELETE" ≫ return DELETE
+ , string "TRACE" ≫ return TRACE
+ , string "CONNECT" ≫ return CONNECT
+ , ExtensionMethod <$> token
+ ]
+
instance Default (Parser Request) where
{-# INLINEABLE def #-}
def = do skipMany crlf
requestLine ∷ Parser (Method, URI, HttpVersion)
{-# INLINEABLE requestLine #-}
-requestLine = do meth ← method
+requestLine = do meth ← def
sp
u ← uri
sp
crlf
return (meth, u, ver)
-method ∷ Parser Method
-{-# INLINEABLE method #-}
-method = choice
- [ string "OPTIONS" ≫ return OPTIONS
- , string "GET" ≫ return GET
- , string "HEAD" ≫ return HEAD
- , string "POST" ≫ return POST
- , string "PUT" ≫ return PUT
- , string "DELETE" ≫ return DELETE
- , string "TRACE" ≫ return TRACE
- , string "CONNECT" ≫ return CONNECT
- , ExtensionMethod <$> token
- ]
-
uri ∷ Parser URI
{-# INLINEABLE uri #-}
uri = do bs ← takeWhile1 (\c → (¬) (isCtl c ∨ c ≡ '\x20'))
import Network.HTTP.Lucu.Preprocess
import Network.HTTP.Lucu.Request
import Network.HTTP.Lucu.Response
+import Network.HTTP.Lucu.Response.StatusCode
import Network.HTTP.Lucu.Resource.Internal
import Network.HTTP.Lucu.Utils
import Network.Socket
import Network.HTTP.Lucu.Request
import Network.HTTP.Lucu.Resource.Internal
import Network.HTTP.Lucu.Response
+import Network.HTTP.Lucu.Response.StatusCode
import Network.HTTP.Lucu.MIMEType
import Network.HTTP.Lucu.Utils
import Network.Socket hiding (accept)
import Network.HTTP.Lucu.Postprocess
import Network.HTTP.Lucu.Request
import Network.HTTP.Lucu.Response
+import Network.HTTP.Lucu.Response.StatusCode
import Network.HTTP.Lucu.Utils
import Network.Socket
#if defined(HAVE_SSL)
, UnicodeSyntax
, ViewPatterns
#-}
--- |Definition of things related on HTTP response.
+-- |Definition of HTTP responses.
module Network.HTTP.Lucu.Response
- ( -- * Class and Types
- StatusCode(..)
- , SomeStatusCode
- , Response(..)
- , statusCodes
- , module Network.HTTP.Lucu.StatusCode
-
- -- * Functions
+ ( Response(..)
+
, emptyResponse
, setStatusCode
, resCanHaveBody
import Data.Monoid.Unicode
import Network.HTTP.Lucu.Headers
import Network.HTTP.Lucu.HttpVersion
-import Network.HTTP.Lucu.StatusCode
-import Network.HTTP.Lucu.StatusCode.Internal
+import Network.HTTP.Lucu.Response.StatusCode
import Prelude.Unicode
-- |This is the definition of an HTTP response.
{-# LANGUAGE
- OverloadedStrings
- , QuasiQuotes
+ QuasiQuotes
#-}
--- |Definition of HTTP status code.
--- 'Network.HTTP.Lucu.Resource.setStatus' accepts these named status
--- codes so you don't have to memorize that, say, \"Gateway Timeout\"
--- is 504.
-module Network.HTTP.Lucu.StatusCode
- ( -- * Informational
- Continue(..)
+-- |Definition of HTTP status codes.
+module Network.HTTP.Lucu.Response.StatusCode
+ ( -- * Type class
+ StatusCode(..)
+ , SomeStatusCode
+ , statusCodes
+
+ -- * Status codes
+ -- ** Informational
+ , Continue(..)
, SwitchingProtocols(..)
, Processing(..)
- -- * Successful
+ -- ** Successful
, OK(..)
, Created(..)
, Accepted(..)
, AlreadyReported(..)
, IMUsed(..)
- -- * Redirection
+ -- ** Redirection
, MultipleChoices(..)
, MovedPermanently(..)
, Found(..)
, UseProxy(..)
, TemporaryRedirect(..)
- -- * Client Error
+ -- ** Client Error
, BadRequest(..)
, Unauthorized(..)
, PaymentRequired(..)
, FailedDependency(..)
, UpgradeRequired(..)
- -- * Server Error
+ -- ** Server Error
, InternalServerError(..)
, NotImplemented(..)
, BadGateway(..)
, NotExtended(..)
)
where
-import Network.HTTP.Lucu.StatusCode.Internal
+import Network.HTTP.Lucu.Response.StatusCode.Internal
[statusCodes|
100 Continue
, FlexibleInstances
, MultiParamTypeClasses
, OverlappingInstances
+ , OverloadedStrings
, TemplateHaskell
- , TypeFamilies
, UndecidableInstances
, UnicodeSyntax
, ViewPatterns
#-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
-module Network.HTTP.Lucu.StatusCode.Internal
+module Network.HTTP.Lucu.Response.StatusCode.Internal
( StatusCode(..)
, SomeStatusCode
, statusCodes
)
where
import Control.Applicative
+import Control.Applicative.Unicode
+import Control.Monad.Unicode
import Data.Ascii (Ascii, AsciiBuilder)
import qualified Data.Ascii as A
import Data.Attoparsec.Char8
import Data.Convertible.Instances.Ascii ()
import Data.Convertible.Utils
import Data.List
+import Data.Monoid
import Language.Haskell.TH.Lib
import Language.Haskell.TH.Syntax
import Language.Haskell.TH.Quote
+import Network.HTTP.Lucu.OrphanInstances ()
import Network.HTTP.Lucu.Parser
import Prelude.Unicode
textualStatus ∷ sc → AsciiBuilder
-- |Wrap the status code into 'SomeStatusCode'.
fromStatusCode ∷ sc → SomeStatusCode
+ {-# INLINE CONLIKE fromStatusCode #-}
fromStatusCode = SomeStatusCode
instance StatusCode sc ⇒ ConvertSuccess sc SomeStatusCode where
-- |Container type for the 'StatusCode' type class.
data SomeStatusCode
- = ∀sc. StatusCode sc ⇒ SomeStatusCode sc
+ = ∀sc. StatusCode sc ⇒ SomeStatusCode !sc
-- |Equivalence of 'StatusCode's. Two 'StatusCode's @α@ and
-- @β@ are said to be equivalent iff @'numericCode' α '=='
show (SomeStatusCode sc) = show sc
instance StatusCode SomeStatusCode where
- numericCode (SomeStatusCode sc) = numericCode sc
+ {-# INLINE numericCode #-}
+ numericCode (SomeStatusCode sc) = numericCode sc
+ {-# INLINE textualStatus #-}
textualStatus (SomeStatusCode sc) = textualStatus sc
+ {-# INLINE CONLIKE fromStatusCode #-}
fromStatusCode = id
-- |'QuasiQuoter' for 'StatusCode' declarations.
--
-- @
-- data OK = OK deriving ('Eq', 'Show')
--- instance OK where
+-- instance 'StatusCode' OK where
-- 'numericCode' _ = 200
-- 'textualStatus' _ = 'cs' (\"200 OK\" ∷ Ascii)
--
-- data BadRequest = BadRequest deriving ('Eq', 'Show')
--- instance BadRequest where
+-- instance 'StatusCode' BadRequest where
-- 'numericCode' _ = 400
-- 'textualStatus' _ = 'cs' (\"400 Bad Request\" ∷ Ascii)
--
-- data MethodNotAllowed = MethodNotAllowed deriving ('Eq', 'Show')
--- instance MethodNotAllowed where
+-- instance 'StatusCode' MethodNotAllowed where
-- 'numericCode' _ = 405
-- 'textualStatus' _ = 'cs' (\"405 Method Not Allowed\" ∷ Ascii)
-- @
quoteExp = const unsupported
, quotePat = const unsupported
, quoteType = const unsupported
- , quoteDec = (concat <$>) ∘ mapM statusDecl ∘ parseStatusCodes ∘ Lazy.pack
+ , quoteDec = (concat <$>)
+ ∘ (mapM statusDecl =≪)
+ ∘ parseStatusCodes
+ ∘ Lazy.pack
}
where
unsupported ∷ Monad m ⇒ m α
unsupported = fail "Unsupported usage of statusCodes quasi-quoter."
-parseStatusCodes ∷ Lazy.ByteString → [(Int, [Ascii])]
+parseStatusCodes ∷ Monad m ⇒ Lazy.ByteString → m [(Int, [Ascii])]
parseStatusCodes src
= case LP.parse pairs src of
LP.Fail _ eCtx e
- → error $ "Unparsable status codes: "
- ⧺ intercalate ", " eCtx
- ⧺ ": "
- ⧺ e
+ → fail $ "Unparsable status codes: "
+ ⧺ intercalate ", " eCtx
+ ⧺ ": "
+ ⧺ e
LP.Done _ xs
- → xs
+ → return xs
where
pairs ∷ Parser [(Int, [Ascii])]
pairs = do skipMany endOfLine
word = A.unsafeFromByteString <$> takeWhile1 isAlpha_ascii
statusDecl ∷ (Int, [Ascii]) → Q [Dec]
-statusDecl (num, phrase)
- = do a ← dataDecl
- bs ← instanceDecl
- return (a:bs)
+statusDecl (num, phrase) = (:) <$> dataDecl ⊛ instanceDecl
where
+ dataDecl ∷ Q Dec
+ dataDecl = dataD (cxt []) name [] [con] [''Eq, ''Show]
+
name ∷ Name
name = mkName $ concatMap cs phrase
- dataDecl ∷ Q Dec
- dataDecl = dataD (cxt []) name [] [con] [''Eq, ''Show]
+ con ∷ Q Con
+ con = normalC name []
instanceDecl ∷ Q [Dec]
instanceDecl
= [d| instance StatusCode $typ where
{-# INLINE CONLIKE numericCode #-}
numericCode _ = $(lift num)
- {-# INLINE CONLIKE textualStatus #-}
- textualStatus _ = $txt
+ {-# INLINE textualStatus #-}
+ textualStatus _ = cs $(lift txt)
|]
typ ∷ Q Type
typ = conT name
- con ∷ Q Con
- con = return $ NormalC name []
-
- txt ∷ Q Exp
- txt = [| cs ($(lift txt') ∷ Ascii) |]
-
- txt' ∷ String
- txt' = concat $ intersperse "\x20"
- $ show num : map cs phrase
+ txt ∷ Ascii
+ txt = mconcat $ intersperse "\x20"
+ $ A.unsafeFromString (show num) : phrase
import Network.HTTP.Lucu.Interaction
import Network.HTTP.Lucu.Request
import Network.HTTP.Lucu.Response
+import Network.HTTP.Lucu.Response.StatusCode
import Prelude.Unicode
import System.IO (hPutStrLn, stderr)
import Network.HTTP.Lucu.MIMEType.Guess
import Network.HTTP.Lucu.Resource
import Network.HTTP.Lucu.Resource.Internal
-import Network.HTTP.Lucu.Response
+import Network.HTTP.Lucu.Response.StatusCode
import Network.HTTP.Lucu.Utils
import Prelude.Unicode
import System.Directory
component: Lucu
release: Lucu-1.0
reporter: PHO <pho@cielonegro.org>
-status: :in_progress
-disposition:
+status: :closed
+disposition: :wontfix
creation_time: 2011-12-16 10:11:08.635552 Z
references: []
- PHO <pho@cielonegro.org>
- changed status from unstarted to in_progress
- ""
+- - 2011-12-27 23:37:46.236041 Z
+ - PHO <pho@cielonegro.org>
+ - closed with disposition wontfix
+ - Cancelled.
git_branch: