packages feed

Lucu 0.3.1 → 0.3.2

raw patch · 4 files changed

+54/−22 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

Lucu.cabal view
@@ -8,7 +8,7 @@         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.3.1+Version: 0.3.2 License: PublicDomain License-File: COPYING Author: PHO <pho at cielonegro dot org>@@ -92,7 +92,7 @@         Buildable: False     Main-Is: ImplantFile.hs     Extensions:-        UnboxedTuples+        BangPatterns, UnboxedTuples     ghc-options:         -Wall         -funbox-strict-fields
NEWS view
@@ -1,3 +1,10 @@+Changes from 0.3.1 to 0.3.2+---------------------------+* Network.HTTP.Lucu.Parser:+    - Reimplemented 'many', 'many1' and 'count' in tail-recursive+      way. This resolves a stack overflow when a large file is POSTed+      as a multipart/form-data.+ Changes from 0.3 to 0.3.1 ------------------------- * Network.HTTP.Lucu.Resource:
Network/HTTP/Lucu/Parser.hs view
@@ -174,7 +174,8 @@                      IllegalInput -> do put saved -- 状態を復歸                                         runParser g                      ReachedEOF   -> if pstIsEOFFatal saved then-                                         return ReachedEOF+                                         do put saved+                                            return ReachedEOF                                      else                                          do put saved                                             runParser g@@ -221,27 +222,48 @@   many :: Parser a -> Parser [a]-many p = p `seq`-         do x  <- p-            xs <- many p-            return (x:xs)-         <|>-         return []+many !p = Parser $! many' p [] +-- This implementation is rather ugly but we need to make it+-- tail-recursive to avoid stack overflow.+many' :: Parser a -> [a] -> State ParserState (ParserResult [a])+many' !p !soFar+    = do saved  <- get+         result <- runParser p+         case result of+           Success a    -> many' p (a:soFar)+           IllegalInput -> do put saved+                              return $! Success $ reverse soFar+           ReachedEOF   -> if pstIsEOFFatal saved then+                               do put saved+                                  return ReachedEOF+                           else+                               do put saved+                                  return $! Success $ reverse soFar + many1 :: Parser a -> Parser [a]-many1 p = p `seq`-          do x  <- p-             xs <- many p-             return (x:xs)+many1 !p = do x  <- p+              xs <- many p+              return (x:xs)   count :: Int -> Parser a -> Parser [a]-count 0 _ = return []-count n p = n `seq` p `seq`-            do x  <- p-               xs <- count (n-1) p-               return (x:xs)+count !n !p = Parser $! count' n p []++-- This implementation is rather ugly but we need to make it+-- tail-recursive to avoid stack overflow.+count' :: Int -> Parser a -> [a] -> State ParserState (ParserResult [a])+count' 0  _  !soFar = return $! Success $ reverse soFar+count' !n !p !soFar = do saved  <- get+                         result <- runParser p+                         case result of+                           Success a    -> count' (n-1) p (a:soFar)+                           IllegalInput -> do put saved+                                              return IllegalInput+                           ReachedEOF   -> do put saved+                                              return ReachedEOF+  -- def may be a _|_ option :: a -> Parser a -> Parser a
examples/Multipart.hs view
@@ -20,16 +20,19 @@           = Just $ do setContentType $ read "text/html"                       output ("<title>Multipart Form Test</title>" ++                               "<form action=\"/\" method=\"post\" enctype=\"multipart/form-data\">" ++-                              "  Enter some value:" ++-                              "  <input type=\"text\" name=\"val\">" +++                              "  Upload some file:" +++                              "  <input type=\"text\" name=\"text\">" +++                              "  <input type=\"file\" name=\"file\">" ++                               "  <input type=\"submit\" value=\"Submit\">" ++                               "</form>")       , resHead   = Nothing       , resPost           = Just $ do form <- inputForm defaultLimit-                      let value = fromMaybe "" $ fmap snd $ find ((== "val") . fst) form+                      let text = fromMaybe "" $ fmap snd $ find ((== "text") . fst) form+                          file = fromMaybe "" $ fmap snd $ find ((== "file") . fst) form                       setContentType $ read "text/plain"-                      output ("You entered: " ++ value)+                      outputChunk ("You entered \"" ++ text ++ "\".\n")+                      output ("You uploaded a " ++ show (length file) ++ " bytes long file.\n")       , resPut    = Nothing       , resDelete = Nothing       }