packages feed

ngx-export 1.6.4 → 1.7.0

raw patch · 3 files changed

+86/−44 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ NgxExport: type HTTPHeaders = [(ByteString, ByteString)]
- NgxExport: type ContentHandlerResult = (ByteString, ByteString, Int)
+ NgxExport: type ContentHandlerResult = (ByteString, ByteString, Int, HTTPHeaders)

Files

Changelog.md view
@@ -1,3 +1,14 @@+### 1.7.0++- Now basic synchronous and all asynchronous content handlers are expected to+  return a list of custom response headers in the *4th* field of the+  *ContentHandlerResult*.+- All asynchronous handlers get proper masking against asynchronous exceptions,+  which is especially important for service handlers in presence of asynchronous+  exceptions from service hooks.+- Now a new StablePtr for the content type gets returned only when its value is+  not empty.+ ### 1.6.4  - Added exception *WorkerProcessIsExiting* to signal services that Nginx is
NgxExport.hs view
@@ -20,6 +20,7 @@     -- * Type declarations                   ContentHandlerResult                  ,UnsafeContentHandlerResult+                 ,HTTPHeaders     -- * Exporters     -- *** Synchronous handlers                  ,ngxExportSS@@ -116,8 +117,9 @@ {-# COMPLETE ToBool :: CUInt #-} #endif --- | The /3-tuple/ contains /(content, content-type, HTTP-status)/.-type ContentHandlerResult = (L.ByteString, B.ByteString, Int)+-- | The /4-tuple/ contains+--   /(content, content-type, HTTP-status, response-headers)/.+type ContentHandlerResult = (L.ByteString, B.ByteString, Int, HTTPHeaders)  -- | The /3-tuple/ contains /(content, content-type, HTTP-status)/. --@@ -126,6 +128,9 @@ -- termination and must not be garbage-collected in the Haskell RTS. type UnsafeContentHandlerResult = (B.ByteString, B.ByteString, Int) +-- | A list of HTTP headers comprised of /name-value/ pairs.+type HTTPHeaders = [(B.ByteString, B.ByteString)]+ data NgxExport = SS              (String -> String)                | SSS             (String -> String -> String)                | SLS             ([String] -> String)@@ -143,17 +148,17 @@                | AsyncHandlerRB  (L.ByteString -> B.ByteString ->                                      IO ContentHandlerResult) -data NgxExportDisambiguation = Unambiguous-                             | YYSync-                             | YYDefHandler-                             | IOYYSync-                             | IOYYAsync+data NgxExportTypeAmbiguityTag = Unambiguous+                               | YYSync+                               | YYDefHandler+                               | IOYYSync+                               | IOYYAsync  do     TyConI (DataD _ _ _ EXTRA_WILDCARD_BEFORE_CON tCs _) <-         reify ''NgxExport     TyConI (DataD _ _ _ EXTRA_WILDCARD_BEFORE_CON aCs _) <--        reify ''NgxExportDisambiguation+        reify ''NgxExportTypeAmbiguityTag     let tName = mkName "exportType"         aName = mkName "exportTypeAmbiguity"         tCons = map (\(NormalC con [(_, typ)]) -> (con, typ)) tCs@@ -164,7 +169,7 @@              map (\(fst -> c, i) ->                     clause [conP c [wildP]] (normalB [|return i|]) []                  ) (zip tCons [1 ..] :: [((Name, Type), Int)])-        ,sigD aName [t|NgxExportDisambiguation -> IO CInt|]+        ,sigD aName [t|NgxExportTypeAmbiguityTag -> IO CInt|]         ,funD aName $              map (\(c, i) ->                     clause [conP c []] (normalB [|return i|]) []@@ -386,6 +391,7 @@     ngxExport 'Handler 'Unambiguous 'handler     [t|CString -> CInt -> Ptr (Ptr NgxStrType) -> Ptr CInt ->        Ptr CString -> Ptr CSize -> Ptr (StablePtr B.ByteString) -> Ptr CInt ->+       Ptr (Ptr NgxStrType) -> Ptr CInt -> Ptr (StablePtr L.ByteString) ->        Ptr (StablePtr L.ByteString) -> IO CUInt|]  -- | Exports a function of type@@ -428,6 +434,7 @@     ngxExport 'AsyncHandler 'Unambiguous 'asyncHandler     [t|CString -> CInt -> CInt -> CUInt ->        Ptr CString -> Ptr CSize -> Ptr (StablePtr B.ByteString) -> Ptr CInt ->+       Ptr (Ptr NgxStrType) -> Ptr CInt -> Ptr (StablePtr L.ByteString) ->        Ptr (Ptr NgxStrType) -> Ptr CInt ->        Ptr CUInt -> Ptr (StablePtr L.ByteString) -> IO (StablePtr (Async ()))|] @@ -447,6 +454,7 @@     [t|Ptr NgxStrType -> Ptr NgxStrType -> CInt ->        CString -> CInt -> CInt -> CUInt ->        Ptr CString -> Ptr CSize -> Ptr (StablePtr B.ByteString) -> Ptr CInt ->+       Ptr (Ptr NgxStrType) -> Ptr CInt -> Ptr (StablePtr L.ByteString) ->        Ptr (Ptr NgxStrType) -> Ptr CInt ->        Ptr CUInt -> Ptr (StablePtr L.ByteString) -> IO (StablePtr (Async ()))|] @@ -589,7 +597,7 @@     return (nullPtr, 0) toBuffers s p = do     let n = L.foldlChunks (const . succ) 0 s-    if n == 1+    if n == 1 && p /= nullPtr         then do             B.unsafeUseAsCStringLen (head $ L.toChunks s) $                 \(x, I l) -> poke p $ NgxStrType l x@@ -617,10 +625,11 @@     when (t /= nullPtr) $ newStablePtr s >>= poke spd  pokeContentTypeAndStatus :: B.ByteString ->-    Ptr CString -> Ptr CSize -> Ptr CInt -> CInt -> IO ()+    Ptr CString -> Ptr CSize -> Ptr CInt -> CInt -> IO CSize pokeContentTypeAndStatus ct pct plct pst st = do     PtrLen sct lct <- B.unsafeUseAsCStringLen ct return     pokeCStringLen sct lct pct plct >> poke pst st+    return lct  peekRequestBodyChunks :: Ptr NgxStrType -> Ptr NgxStrType -> Int ->     IO L.ByteString@@ -634,10 +643,12 @@         else peekNgxStringArrayLenY b m  pokeAsyncHandlerData :: B.ByteString -> Ptr CString -> Ptr CSize ->-    Ptr (StablePtr B.ByteString) -> Ptr CInt -> CInt -> IO ()-pokeAsyncHandlerData ct pct plct spct pst st = do-    pokeContentTypeAndStatus ct pct plct pst st-    newStablePtr ct >>= poke spct+    Ptr (StablePtr B.ByteString) -> Ptr CInt -> CInt -> HTTPHeaders ->+    Ptr (Ptr NgxStrType) -> Ptr CInt -> Ptr (StablePtr L.ByteString) -> IO ()+pokeAsyncHandlerData ct pct plct spct pst st rhs prhs plrhs sprhs = do+    lct <- pokeContentTypeAndStatus ct pct plct pst st+    when (lct > 0) $ newStablePtr ct >>= poke spct+    pokeLazyByteString (fromHTTPHeaders rhs) prhs plrhs sprhs  safeHandler :: Ptr CString -> Ptr CInt -> IO CUInt -> IO CUInt safeHandler p pl = handle $ \e -> do@@ -645,9 +656,14 @@     pokeCStringLen x l p pl     return 1 -safeYYHandler :: IO (L.ByteString, (CUInt, Bool)) ->-    IO (L.ByteString, (CUInt, Bool))+safeYYHandler :: IO (L.ByteString, CUInt) -> IO (L.ByteString, CUInt) safeYYHandler = handle $ \e ->+    return (C8L.pack $ show (e :: SomeException), 1)+{-# INLINE safeYYHandler #-}++safeAsyncYYHandler :: IO (L.ByteString, (CUInt, Bool)) ->+    IO (L.ByteString, (CUInt, Bool))+safeAsyncYYHandler = handle $ \e ->     return (C8L.pack $ show e,             (case fromException e of                 Just ServiceHookInterrupt -> 2@@ -666,8 +682,13 @@                 _ -> False             )            )-{-# INLINE safeYYHandler #-}+{-# INLINE safeAsyncYYHandler #-} +fromHTTPHeaders :: HTTPHeaders -> L.ByteString+fromHTTPHeaders = L.fromChunks . foldr (\(z -> a, z -> b) -> ([a, b] ++)) []+    where z s | B.null s = B.singleton 0+              | otherwise = s+ isEINTR :: IOError -> Bool isEINTR = (Just ((\(Errno i) -> i) eINTR) ==) . ioe_errno {-# INLINE isEINTR #-}@@ -704,9 +725,9 @@     Ptr (Ptr NgxStrType) -> Ptr CInt ->     Ptr (StablePtr L.ByteString) -> IO CUInt yY f x (I n) p pl spd = do-    (s, (r, _)) <- safeYYHandler $ do+    (s, r) <- safeYYHandler $ do         s <- f <$> B.unsafePackCStringLen (x, n)-        fmap (, (0, False)) $ return $!! s+        fmap (, 0) $ return $!! s     pokeLazyByteString s p pl spd     return r @@ -715,9 +736,9 @@     Ptr (Ptr NgxStrType) -> Ptr CInt ->     Ptr (StablePtr L.ByteString) -> IO CUInt ioyYCommon pack f x (I n) p pl spd = do-    (s, (r, _)) <- safeYYHandler $ do+    (s, r) <- safeYYHandler $ do         s <- pack (x, n) >>= flip f False-        fmap (, (0, False)) $ return $!! s+        fmap (, 0) $ return $!! s     pokeLazyByteString s p pl spd     return r @@ -740,12 +761,13 @@ asyncIOCommon :: IO (L.ByteString, Bool) ->     CInt -> Bool -> Ptr (Ptr NgxStrType) -> Ptr CInt ->     Ptr CUInt -> Ptr (StablePtr L.ByteString) -> IO (StablePtr (Async ()))-asyncIOCommon a (I fd) efd p pl pr spd =+asyncIOCommon a (I fd) efd p pl pr spd = mask $ \restore ->     async     (do-        (s, (r, exiting)) <- safeYYHandler $ do-            (s, exiting) <- a-            fmap (, (0, exiting)) $ return $!! s+        (s, (r, exiting)) <- safeAsyncYYHandler $+            restore $ do+                (s, exiting) <- a+                fmap (, (0, exiting)) $ return $!! s         pokeLazyByteString s p pl spd         poke pr r         if exiting@@ -768,11 +790,11 @@           writeFlag1b = B.unsafeUseAsCString asyncIOFlag1b $ writeBufN 1           writeFlag8b = B.unsafeUseAsCString asyncIOFlag8b $ writeBufN 8           closeChannel = closeFd fd `catchIOError` const (return ())-          -- FIXME: cleanupOnWriteError should free contents of p, spd,-          -- and spct. However, leaving this not implemented seems to be safe-          -- because Nginx won't close the event channel or delete the request-          -- object (for request-driven handlers) regardless of the Haskell-          -- handler's duration.+          -- FIXME: cleanupOnWriteError should free all previously allocated+          -- data and stable pointers. However, leaving this not implemented+          -- seems to be safe because Nginx won't close the event channel or+          -- delete the request object (for request-driven handlers)+          -- regardless of the Haskell handler's duration.           cleanupOnWriteError = return ()  asyncIOYY :: IOYY -> CString -> CInt ->@@ -818,29 +840,35 @@ asyncHandler :: AsyncHandler -> CString -> CInt ->     CInt -> CUInt ->     Ptr CString -> Ptr CSize -> Ptr (StablePtr B.ByteString) -> Ptr CInt ->+    Ptr (Ptr NgxStrType) -> Ptr CInt -> Ptr (StablePtr L.ByteString) ->     Ptr (Ptr NgxStrType) -> Ptr CInt ->     Ptr CUInt -> Ptr (StablePtr L.ByteString) -> IO (StablePtr (Async ()))-asyncHandler f x (I n) fd (ToBool efd) pct plct spct pst =+asyncHandler f x (I n) fd (ToBool efd) pct plct spct pst+        prhs plrhs sprhs =     asyncIOCommon     (do         x' <- B.unsafePackCStringLen (x, n)-        (s, ct, I st) <- f x'-        (return $!! s) >> pokeAsyncHandlerData ct pct plct spct pst st+        v@(s, ct, I st, rhs) <- f x'+        (return $!! v) >> mask_+            (pokeAsyncHandlerData ct pct plct spct pst st rhs prhs plrhs sprhs)         return (s, False)     ) fd efd  asyncHandlerRB :: AsyncHandlerRB -> Ptr NgxStrType -> Ptr NgxStrType -> CInt ->     CString -> CInt -> CInt -> CUInt ->     Ptr CString -> Ptr CSize -> Ptr (StablePtr B.ByteString) -> Ptr CInt ->+    Ptr (Ptr NgxStrType) -> Ptr CInt -> Ptr (StablePtr L.ByteString) ->     Ptr (Ptr NgxStrType) -> Ptr CInt ->     Ptr CUInt -> Ptr (StablePtr L.ByteString) -> IO (StablePtr (Async ()))-asyncHandlerRB f tmpf b (I m) x (I n) fd (ToBool efd) pct plct spct pst =+asyncHandlerRB f tmpf b (I m) x (I n) fd (ToBool efd) pct plct spct pst+        prhs plrhs sprhs =     asyncIOCommon     (do         b' <- peekRequestBodyChunks tmpf b m         x' <- B.unsafePackCStringLen (x, n)-        (s, ct, I st) <- f b' x'-        (return $!! s) >> pokeAsyncHandlerData ct pct plct spct pst st+        v@(s, ct, I st, rhs) <- f b' x'+        (return $!! v) >> mask_+            (pokeAsyncHandlerData ct pct plct spct pst st rhs prhs plrhs sprhs)         return (s, False)     ) fd efd @@ -879,13 +907,16 @@  handler :: Handler -> CString -> CInt -> Ptr (Ptr NgxStrType) -> Ptr CInt ->     Ptr CString -> Ptr CSize -> Ptr (StablePtr B.ByteString) -> Ptr CInt ->+    Ptr (Ptr NgxStrType) -> Ptr CInt -> Ptr (StablePtr L.ByteString) ->     Ptr (StablePtr L.ByteString) -> IO CUInt-handler f x (I n) p pl pct plct spct pst spd =+handler f x (I n) p pl pct plct spct pst prhs plrhs sprhs spd =     safeHandler pct pst $ do-        (s, ct, I st) <- f <$> B.unsafePackCStringLen (x, n)-        (return $!! s) >> pokeContentTypeAndStatus ct pct plct pst st+        v@(s, ct, I st, rhs) <- f <$> B.unsafePackCStringLen (x, n)+        lct <- (return $!! v) >> pokeContentTypeAndStatus ct pct plct pst st+        (return $!! lct) >>+            pokeLazyByteString (fromHTTPHeaders rhs) prhs plrhs sprhs         pokeLazyByteString s p pl spd-        newStablePtr ct >>= poke spct+        when (lct > 0) $ newStablePtr ct >>= poke spct         return 0  defHandler :: YY -> CString -> CInt ->@@ -901,8 +932,8 @@     Ptr CString -> Ptr CSize -> Ptr CInt -> IO CUInt unsafeHandler f x (I n) p pl pct plct pst =     safeHandler pct pst $ do-        (s, ct, I st) <- f <$> B.unsafePackCStringLen (x, n)-        (return $!! s) >> pokeContentTypeAndStatus ct pct plct pst st+        v@(s, ct, I st) <- f <$> B.unsafePackCStringLen (x, n)+        (return $!! v) >> void (pokeContentTypeAndStatus ct pct plct pst st)         PtrLen t l <- B.unsafeUseAsCStringLen s return         pokeCStringLen t l p pl         return 0
ngx-export.cabal view
@@ -1,5 +1,5 @@ name:                       ngx-export-version:                    1.6.4+version:                    1.7.0 synopsis:                   Helper module for Nginx haskell module description:                Helper module for         <http://github.com/lyokha/nginx-haskell-module Nginx haskell module>.