packages feed

Lucu 0.6 → 0.7

raw patch · 6 files changed

+71/−51 lines, 6 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Network.HTTP.Lucu.Resource: fdName :: FormData -> String
- Network.HTTP.Lucu.Resource: FormData :: String -> Maybe String -> ByteString -> FormData
+ Network.HTTP.Lucu.Resource: FormData :: Maybe String -> ByteString -> FormData
- Network.HTTP.Lucu.Resource: getQueryForm :: Resource [FormData]
+ Network.HTTP.Lucu.Resource: getQueryForm :: Resource [(String, FormData)]
- Network.HTTP.Lucu.Resource: inputForm :: Int -> Resource [FormData]
+ Network.HTTP.Lucu.Resource: inputForm :: Int -> Resource [(String, FormData)]

Files

Lucu.cabal view
@@ -2,13 +2,13 @@ Synopsis: HTTP Daemonic Library Description:         Lucu is an HTTP daemonic library. It can be embedded in any-        Haskell program and runs in an independent thread.-        Lucu is not a replacement for Apache. It is intended to be-        used to create an efficient web-based application without-        messing around FastCGI. It is also intended to be run behind a-        reverse-proxy so it doesn't have some facilities like logging,-        client filtering or such like.-Version: 0.6+        Haskell program and runs in an independent thread.  Lucu is+        not a replacement for Apache or lighttpd. It is intended to be+        used to create an efficient web-based RESTful application+        without messing around FastCGI. It is also intended to be run+        behind a reverse-proxy so it doesn't have some facilities like+        logging, client filtering or such like.+Version: 0.7 License: PublicDomain License-File: COPYING Author: PHO <pho at cielonegro dot org>@@ -96,8 +96,12 @@         Network.HTTP.Lucu.SocketLike      Extensions:-        BangPatterns, DeriveDataTypeable, FlexibleContexts,-        FlexibleInstances, ScopedTypeVariables, TypeFamilies,+        BangPatterns+        DeriveDataTypeable+        FlexibleContexts+        FlexibleInstances+        ScopedTypeVariables+        TypeFamilies         UnboxedTuples      ghc-options:@@ -113,7 +117,9 @@     Main-Is: ImplantFile.hs      Extensions:-        BangPatterns, ScopedTypeVariables, UnboxedTuples+        BangPatterns+        ScopedTypeVariables+        UnboxedTuples      ghc-options:         -Wall
NEWS view
@@ -1,3 +1,14 @@+Changes from 0.6 to 0.7+-----------------------+* Network.HTTP.Lucu.Resource: (Suggested by Voker57)++    - getQueryForm and inputForm now return [(name :: String,+      FormData)] instead of [FormData] to ease field lookup by+      name. The reason why it's not 'Map String FormData' is that+      there is a possibility where multiple fields have the same name.++    - Removed field fdName from FormData type as it's now redundant.+ Changes from 0.5 to 0.6 ----------------------- * New dependency: time-http == 0.1.*
Network/HTTP/Lucu.hs view
@@ -16,10 +16,11 @@ --   [/SSL connections/] Lucu can handle HTTP connections over SSL --   layer. ----- Lucu is not a replacement for Apache. It is intended to be used to--- create an efficient web-based application without messing around--- FastCGI. It is also intended to be run behind a reverse-proxy so it--- doesn't have the following (otherwise essential) facilities:+-- Lucu is not a replacement for Apache or lighttpd. It is intended to+-- be used to create an efficient web-based RESTful application+-- without messing around FastCGI. It is also intended to be run+-- behind a reverse-proxy so it doesn't have the following (otherwise+-- essential) facilities: -- --   [/Logging/] Lucu doesn't log any requests from any clients. --
Network/HTTP/Lucu/MultipartForm.hs view
@@ -18,12 +18,11 @@  data Part = Part Headers L8.ByteString --- |This data type represents a form entry name, form value and--- possibly an uploaded file name.+-- |This data type represents a form value and possibly an uploaded+-- file name. data FormData     = FormData {-        fdName     :: String-      , fdFileName :: Maybe String+        fdFileName :: Maybe String       , fdContent  :: L8.ByteString       } @@ -50,7 +49,7 @@                                    value  -multipartFormP :: String -> Parser [FormData]+multipartFormP :: String -> Parser [(String, FormData)] multipartFormP boundary     = do parts <- many (partP boundary)          _     <- string "--"@@ -58,7 +57,7 @@          _     <- string "--"          _     <- crlf          eof-         return $ map partToFormData parts+         return $ map partToFormPair parts   partP :: String -> Parser Part@@ -82,17 +81,15 @@          return body  -partToFormData :: Part -> FormData-partToFormData part@(Part _ body)+partToFormPair :: Part -> (String, FormData)+partToFormPair part@(Part _ body)     = let name  = partName part-          fName = partFileName part-      in-        FormData {-          fdName     = name-        , fdFileName = fName-        , fdContent  = body-        }-+          fname = partFileName part+          fd    = FormData {+                    fdFileName = fname+                  , fdContent  = body+                  }+      in (name, fd)  partName :: Part -> String partName = getName' . getContDispoFormData
Network/HTTP/Lucu/Resource.hs view
@@ -301,20 +301,26 @@                  -- rsrcPath の長さの分だけ削除すれば良い。                  return $! drop (length rsrcPath) reqPath --- | Assume the query part of request URI as--- application\/x-www-form-urlencoded, and parse it. This action--- doesn't parse the request body. See 'inputForm'.-getQueryForm :: Resource [FormData]-getQueryForm = do uri <- getRequestURI-                  return $! map pairToFormData $ parseWWWFormURLEncoded $ snd $ splitAt 1 $ uriQuery uri+-- |Assume the query part of request URI as+-- application\/x-www-form-urlencoded, and parse it to pairs of+-- @(name, formData)@. This action doesn't parse the request body. See+-- 'inputForm'.+getQueryForm :: Resource [(String, FormData)]+getQueryForm = liftM parse' getRequestURI+    where+      parse' = map toPairWithFormData .+               parseWWWFormURLEncoded .+               snd .+               splitAt 1 .+               uriQuery -pairToFormData :: (String, String) -> FormData-pairToFormData (name, value)-    = FormData {-        fdName     = name-      , fdFileName = Nothing-      , fdContent  = L8.pack value-      }+toPairWithFormData :: (String, String) -> (String, FormData)+toPairWithFormData (name, value)+    = let fd = FormData {+                 fdFileName = Nothing+               , fdContent  = L8.pack value+               }+      in (name, fd)  -- |Get a value of given request header. Comparison of header name is -- case-insensitive. Note that this action is not intended to be used@@ -726,7 +732,7 @@ -- makes 'Resource' abort with status \"415 Unsupported Media -- Type\". If the request has no \"Content-Type\", it aborts with -- \"400 Bad Request\".-inputForm :: Int -> Resource [FormData]+inputForm :: Int -> Resource [(String, FormData)] inputForm limit     = limit `seq`        do cTypeM <- getContentType@@ -742,8 +748,7 @@                                                           ++ show cType)     where       readWWWFormURLEncoded-          = do src <- input limit-               return $ map pairToFormData $ parseWWWFormURLEncoded src+          = liftM (map toPairWithFormData . parseWWWFormURLEncoded) (input limit)        readMultipartFormData params           = do case find ((== "boundary") . map toLower . fst) params of@@ -752,7 +757,8 @@                  Just (_, boundary)                      -> do src <- inputLBS limit                            case parse (multipartFormP boundary) src of-                             (# Success fdList, _ #) -> return fdList+                             (# Success formList, _ #)+                                 -> return formList                              (# _, _ #)                                  -> abort BadRequest [] (Just "Unparsable multipart/form-data") 
examples/Multipart.hs view
@@ -1,5 +1,4 @@ import qualified Data.ByteString.Lazy.Char8 as L8-import Data.List import Data.Maybe import Network.HTTP.Lucu @@ -28,9 +27,9 @@       , resHead   = Nothing       , resPost           = Just $ do form <- inputForm defaultLimit-                      let text     = fromMaybe L8.empty $ fmap fdContent $ find ((== "text") . fdName) form-                          file     = fromMaybe L8.empty $ fmap fdContent $ find ((== "file") . fdName) form-                          fileName = fdFileName =<< find ((== "file") . fdName) form+                      let text     = fromMaybe L8.empty $ fmap fdContent $ lookup "text" form+                          file     = fromMaybe L8.empty $ fmap fdContent $ lookup "file" form+                          fileName = fdFileName =<< lookup "file" form                       setContentType $ read "text/plain"                       outputChunk ("You entered \"" ++ L8.unpack text ++ "\".\n")                       outputChunk ("You uploaded a " ++ show (L8.length file) ++ " bytes long file.\n")