]> gitweb @ CieloNegro.org - Lucu.git/commitdiff
Documentation
authorpho <pho@cielonegro.org>
Fri, 20 Apr 2007 14:06:38 +0000 (23:06 +0900)
committerpho <pho@cielonegro.org>
Fri, 20 Apr 2007 14:06:38 +0000 (23:06 +0900)
darcs-hash:20070420140638-62b54-f215e17319df2499d4dcfb6eab687771084b6e27.gz

15 files changed:
Lucu.cabal
Network/HTTP/Lucu.hs
Network/HTTP/Lucu/Chunk.hs
Network/HTTP/Lucu/Config.hs
Network/HTTP/Lucu/DefaultPage.hs
Network/HTTP/Lucu/ETag.hs
Network/HTTP/Lucu/Headers.hs
Network/HTTP/Lucu/Interaction.hs
Network/HTTP/Lucu/Parser.hs
Network/HTTP/Lucu/Postprocess.hs
Network/HTTP/Lucu/Preprocess.hs
Network/HTTP/Lucu/RFC1123DateTime.hs
Network/HTTP/Lucu/RequestReader.hs
Network/HTTP/Lucu/ResponseWriter.hs
Network/HTTP/Lucu/StaticFile.hs

index e17c470fba1db3d44ec5f1b49bcfad640a594447..53bfa97ef5de4447fc6765c144709be7ece1a230 100644 (file)
@@ -6,7 +6,7 @@ Author: PHO
 Homepage: http://ccm.sherry.jp/
 Category: Incomplete
 Build-Depends:
-         base, mtl, network, stm, parsec, hxt, haskell-src, unix
+         base, mtl, network, stm, hxt, haskell-src, unix
 Exposed-Modules:
         Network.HTTP.Lucu
         Network.HTTP.Lucu.Abortion
index 3f4350bc35004b8a23066616b232914fdcfcb943..b2c88c6a0255f4417aa0e7f6228708ab4971293a 100644 (file)
@@ -4,12 +4,10 @@ module Network.HTTP.Lucu
     , abortA
 
       -- Config
-    , Config(..)
-    , defaultConfig
+    , module Network.HTTP.Lucu.Config
 
       -- ETag
-    , ETag
-    , mkETag
+    , ETag(..)
     , strongETag
     , weakETag
 
@@ -26,7 +24,7 @@ module Network.HTTP.Lucu
     , Method(..)
     , Request(..)
 
-      -- Resource (driftTo だけは要らない)
+      -- Resource (driftTo だけは要らない)
     , module Network.HTTP.Lucu.Resource
 
       -- Resource.Tree
@@ -48,7 +46,7 @@ import Network.HTTP.Lucu.ETag
 import Network.HTTP.Lucu.Httpd
 import Network.HTTP.Lucu.MIMEType
 import Network.HTTP.Lucu.Request
-import Network.HTTP.Lucu.Resource
+import Network.HTTP.Lucu.Resource hiding (driftTo)
 import Network.HTTP.Lucu.Resource.Tree
 import Network.HTTP.Lucu.Response
 import Network.HTTP.Lucu.StaticFile
index 342362c07959b21353d7334867277d4f285f9b45..44f2ae4c16890bc3df3b4064938c378335d2af9c 100644 (file)
@@ -1,3 +1,4 @@
+-- #hide
 module Network.HTTP.Lucu.Chunk
     ( chunkHeaderP  -- Num a => Parser a
     , chunkFooterP  -- Parser ()
index 2f6335312b029d8e9eb8e561bf5291ee3bbbf16d..d33f35ab20de5533bd21e6b51e84fc55b5e08656 100644 (file)
@@ -1,6 +1,7 @@
+-- |Configurations for the Lucu httpd like a port to listen.
 module Network.HTTP.Lucu.Config
     ( Config(..)
-    , defaultConfig -- Config
+    , defaultConfig
     )
     where
 
@@ -12,26 +13,56 @@ import           Network.HTTP.Lucu.MIMEType
 import           Network.HTTP.Lucu.MIMEType.DefaultExtensionMap
 import           System.IO.Unsafe
 
-
+-- |A configuration record for the Lucu httpd. You need to use
+-- 'defaultConfig' or setup your own configuration to run the httpd.
 data Config = Config {
+    -- |A string which will be sent to clients as \"Server\" field.
       cnfServerSoftware       :: String
+    -- |The host name of the server. This value will be used in
+    -- built-in pages like \"404 Not Found\".
     , cnfServerHost           :: HostName
+    -- |A port ID to listen to HTTP clients.
     , cnfServerPort           :: PortID
+    -- |The maximum number of requests to accept in one connection
+    -- simultaneously. If a client exceeds this limitation, its last
+    -- request won't be processed until a response for its earliest
+    -- pending request is sent back to the client.
     , cnfMaxPipelineDepth     :: Int
+    -- |The maximum length of request entity to accept in bytes. Note
+    -- that this is nothing but the default value which is used when
+    -- 'Network.HTTP.Lucu.Resource.input' and such like are applied to
+    -- 'Network.HTTP.Lucu.Resource.defaultLimit', so there is no
+    -- guarantee that this value always constrains all the requests.
     , cnfMaxEntityLength      :: Int
-    , cnfMaxURILength         :: Int
+    -- |The maximum length of chunk to output. This value is used by
+    -- 'Network.HTTP.Lucu.Resource.output' and such like to limit the
+    -- chunk length so you can safely output an infinite string (like
+    -- a lazy stream of \/dev\/random) using those actions.
     , cnfMaxOutputChunkLength :: Int
+    -- |A mapping from extension to MIME Type. This value is used by
+    -- 'Network.HTTP.Lucu.StaticFile.staticFile' to guess the MIME
+    -- Type of static files. Note that MIME Types are currently
+    -- guessed only by file name. 
+    -- 
+    -- Guessing by file magic is indeed a wonderful idea but that is
+    -- not implemented (yet). But hey, don't you think it's better a
+    -- file system got a MIME Type as a part of inode? Or it might be
+    -- a good idea to use GnomeVFS
+    -- (<http://developer.gnome.org/doc/API/2.0/gnome-vfs-2.0/>)
+    -- instead of vanilla FS.
     , cnfExtToMIMEType        :: Map String MIMEType
     }
 
-
+-- |The default configuration. Generally you can use this value as-is,
+-- or possibly you just want to replace the 'cnfServerSoftware' and
+-- 'cnfServerPort'.
+defaultConfig :: Config
 defaultConfig = Config {
                   cnfServerSoftware       = "Lucu/1.0"
                 , cnfServerHost           = unsafePerformIO getHostName
                 , cnfServerPort           = Service "http"
                 , cnfMaxPipelineDepth     = 100
                 , cnfMaxEntityLength      = 16 * 1024 * 1024 -- 16 MiB
-                , cnfMaxURILength         = 4 * 1024         -- 4 KiB
                 , cnfMaxOutputChunkLength = 5 * 1024 * 1024  -- 5 MiB
                 , cnfExtToMIMEType        = defaultExtensionMap
                 }
index f5cc4764366c62d65edbc165bfb8a0b7f73b5283..988329d28757d62a600ede2ac7aa66df1a499a61 100644 (file)
@@ -1,7 +1,8 @@
+-- #hide, prune
 module Network.HTTP.Lucu.DefaultPage
-    ( getDefaultPage   -- Config -> Maybe Request -> Response -> String
-    , writeDefaultPage -- Interaction -> STM ()
-    , mkDefaultPage    --  (ArrowXml a) => Config -> StatusCode -> a b XmlTree -> a b XmlTree
+    ( getDefaultPage
+    , writeDefaultPage
+    , mkDefaultPage
     )
     where
 
index 86dd429e265100b8318716679ebfd4d0554120b0..856588364b7c1a73daa4c2d46c280feefa18bbf0 100644 (file)
@@ -1,10 +1,12 @@
+-- #prune
+
+-- |Creation and comparison of entity tags.
 module Network.HTTP.Lucu.ETag
-    ( ETag
-    , mkETag     -- Bool -> String -> ETag
-    , strongETag -- String -> ETag
-    , weakETag   -- String -> ETag
-    , eTagP     -- Parser ETag
-    , eTagListP -- Parser [ETag]
+    ( ETag(..)
+    , strongETag
+    , weakETag
+    , eTagP
+    , eTagListP
     )
     where
 
@@ -13,9 +15,13 @@ import           Network.HTTP.Lucu.Parser
 import           Network.HTTP.Lucu.Parser.Http
 import           Network.HTTP.Lucu.Utils
 
-
+-- |An entity tag is made of a weakness flag and a opaque string.
 data ETag = ETag {
+      -- |The weakness flag. Weak tags looks like W\/\"blahblah\" and
+      -- strong tags are like \"blahblah\".
       etagIsWeak :: Bool
+      -- |An opaque string. Only characters from 0x20 (sp) to 0x7e (~)
+      -- are allowed.
     , etagToken  :: String
     } deriving (Eq)
 
@@ -27,15 +33,13 @@ instance Show ETag where
                                ++
                                quoteStr token
 
-
-mkETag :: Bool -> String -> ETag
-mkETag = ETag
-
-
+-- |This is an equivalent to @'ETag' False@. If you want to generate
+-- an ETag from a file, try using
+-- 'Network.HTTP.Lucu.StaticFile.generateETagFromFile'.
 strongETag :: String -> ETag
 strongETag = ETag False
 
-
+-- |This is an equivalent to @'ETag' True@.
 weakETag :: String -> ETag
 weakETag = ETag True
 
@@ -43,7 +47,7 @@ weakETag = ETag True
 eTagP :: Parser ETag
 eTagP = do isWeak <- option False (string "W/" >> return True)
            str    <- quotedStr
-           return $ mkETag isWeak str
+           return $ ETag isWeak str
 
 
 eTagListP :: Parser [ETag]
index ccd514087b2d7a340360c76fdf6dab034cc0d2da..fee6fadec1b595ae189b0b9515b2543cb93b7171 100644 (file)
@@ -1,9 +1,10 @@
+-- #hide
 module Network.HTTP.Lucu.Headers
     ( Headers
     , HasHeaders(..)
-    , emptyHeaders -- Headers
-    , headersP     -- Parser Headers
-    , hPutHeaders  -- Handle -> Headers -> IO ()
+    , emptyHeaders
+    , headersP
+    , hPutHeaders
     )
     where
 
index 68c6c0e919d6431a4ccc8b8524c1bcefab0ee014..0dd925916cc68d7fc083d9d6c31827e883525777 100644 (file)
@@ -1,3 +1,4 @@
+-- #hide
 module Network.HTTP.Lucu.Interaction
     ( Interaction(..)
     , InteractionState(..)
index ffbf6d13ff67f2c834529a850dc684bebe74af1a..c43dfa7616d758bd2d5776c803cc435a56f0fd22 100644 (file)
@@ -20,6 +20,7 @@ module Network.HTTP.Lucu.Parser
     , many1     -- Parser a -> Parser [a]
     , manyTill  -- Parser a -> Parser end -> Parser [a]
     , many1Till -- Parser a -> Parser end -> Parser [a]
+    , count     -- Int -> Parser a -> Parser [a]
     , option    -- a -> Parser a -> Parser a
     , sepBy     -- Parser a -> Parser sep -> Parser [a]
     , sepBy1    -- Parser a -> Parser sep -> Parser [a]
@@ -190,6 +191,13 @@ many1Till p end = many1 $ do x <- p
                              return x
 
 
+count :: Int -> Parser a -> Parser [a]
+count 0 _ = return []
+count n p = do x  <- p
+               xs <- count (n-1) p
+               return (x:xs)
+
+
 option :: a -> Parser a -> Parser a
 option def p = p <|> return def
 
index 80fc7225a4de9bca49f2891189e8123e8e5a5128..24a07f18bb7d74af7e9ba7ac6468738633dfc0cf 100644 (file)
@@ -1,6 +1,7 @@
+-- #hide
 module Network.HTTP.Lucu.Postprocess
-    ( postprocess -- Interaction -> STM ()
-    , completeUnconditionalHeaders -- Config -> Response -> IO Response
+    ( postprocess
+    , completeUnconditionalHeaders
     )
     where
 
index 1c11f89784cb622ec6ee5fae0e67c7acd666c9c1..74d66531f1d0a80c24a5b66734ca6267f1a821db 100644 (file)
@@ -1,5 +1,6 @@
+-- #hide
 module Network.HTTP.Lucu.Preprocess
-    ( preprocess -- Interaction -> STM ()
+    ( preprocess
     )
     where
 
index 9c58e51db91048c196c6a8d54a03c1c9bf272d67..ad683a9b490478e35bad9dfcc552de544212f2e2 100644 (file)
@@ -1,15 +1,17 @@
 module Network.HTTP.Lucu.RFC1123DateTime
-    ( formatRFC1123DateTime -- CalendarTime -> String
-    , formatHTTPDateTime    -- ClockTime -> String
-    , parseHTTPDateTime     -- String -> Maybe ClockTime
+    ( formatRFC1123DateTime
+    , formatHTTPDateTime
+    , parseHTTPDateTime
     )
     where
 
-import Control.Monad
-import System.Time
-import System.Locale
-import Text.ParserCombinators.Parsec
-import Text.Printf
+import           Control.Monad
+import qualified Data.ByteString.Lazy.Char8 as B
+import           Data.ByteString.Lazy.Char8 (ByteString)
+import           Network.HTTP.Lucu.Parser
+import           System.Time
+import           System.Locale
+import           Text.Printf
 
 month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
 week  = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
@@ -33,17 +35,18 @@ formatHTTPDateTime = formatRFC1123DateTime . (\cal -> cal { ctTZName = "GMT" })
 
 parseHTTPDateTime :: String -> Maybe ClockTime
 parseHTTPDateTime src
-    = case parse httpDateTime "" src of
-        Right ct  -> Just ct
-        Left  err -> Nothing
+    = case parseStr httpDateTime src of
+        (Success ct, _) -> Just ct
+        _               -> Nothing
+
 
 httpDateTime :: Parser ClockTime
-httpDateTime = do foldl (<|>) (unexpected "") (map (try . string) week)
+httpDateTime = do foldl (<|>) (fail "") (map string week)
                   char ','
                   char ' '
                   day  <- liftM read (count 2 digit)
                   char ' '
-                  mon  <- foldl (<|>) (unexpected "") (map tryEqToFst (zip month [1..]))
+                  mon  <- foldl (<|>) (fail "") (map tryEqToFst (zip month [1..]))
                   char ' '
                   year <- liftM read (count 4 digit)
                   char ' '
@@ -71,5 +74,5 @@ httpDateTime = do foldl (<|>) (unexpected "") (map (try . string) week)
                              }
     where
       tryEqToFst :: (String, a) -> Parser a
-      tryEqToFst (str, a) = try $ string str >> return a
+      tryEqToFst (str, a) = string str >> return a
       
\ No newline at end of file
index 9b54ca58e92ac648a20bc6dbcd07b4b0dbd7f949..08cc2e937b4696cb4078d425438407b95e11d81a 100644 (file)
@@ -1,5 +1,6 @@
+-- #hide
 module Network.HTTP.Lucu.RequestReader
-    ( requestReader -- Config -> ResTree -> Handle -> HostName -> InteractionQueue -> IO ()
+    ( requestReader
     )
     where
 
index 1e2eacb2df7f462b99316c2c5e3a11608f3c3b1c..71309746f07e9fb294e9bcc22faaec8ef47dbc54 100644 (file)
@@ -1,5 +1,6 @@
+-- #hide
 module Network.HTTP.Lucu.ResponseWriter
-    ( responseWriter -- Config -> Handle -> InteractionQueue -> IO ()
+    ( responseWriter
     )
     where
 
index 7937af9b6fee02996136d7335664f921af0c6932..e710fc90ec62beb0e9cf22164a5c65c92d134b9a 100644 (file)
@@ -1,9 +1,11 @@
 module Network.HTTP.Lucu.StaticFile
-    ( staticFile       -- FilePath -> ResourceDef
-    , handleStaticFile -- FilePath -> Resource ()
+    ( staticFile
+    , handleStaticFile
 
-    , staticDir       -- FilePath -> ResourceDef
-    , handleStaticDir -- FilePath -> Resource ()
+    , staticDir
+    , handleStaticDir
+
+    , generateETagFromFile
     )
     where
 
@@ -68,7 +70,18 @@ handleStaticFile path
                     foundNoEntity Nothing
 
 
--- inode-size-lastmod
+-- |Computation @'generateETagFromFile' fpath@ generates a strong
+-- entity tag from a file. The file doesn't necessarily have to be a
+-- regular file; it may be a FIFO or a device file. The tag is made of
+-- inode ID, size and modification time.
+--
+-- Note that the tag is not strictly strong because the file could be
+-- modified twice at a second without changing inode ID or size, but
+-- it's not really possible to generate a strict strong ETag from a
+-- file since we don't want to simply grab the entire file and use it
+-- as an ETag. It is indeed possible to hash it with SHA-1 or MD5 to
+-- increase strictness, but it's too inefficient if the file is really
+-- large (say, 1 TiB).
 generateETagFromFile :: FilePath -> IO ETag
 generateETagFromFile path
     = do stat <- getFileStatus path