summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlyokha <>2020-01-13 11:27:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2020-01-13 11:27:00 (GMT)
commit01ba47c353026133f43eef969908f779f22a3248 (patch)
tree0fd8bda4fa457ae95ea69a0d6ff6f1b7e0740240
parentd428128894ad1a210abe3a5ed1fe12efe121b7d4 (diff)
version 0.2.1.0HEAD0.2.1.0master
-rw-r--r--Changelog.md6
-rw-r--r--NgxExport/Tools/EDE.hs61
-rw-r--r--ngx-export-tools-extra.cabal2
3 files changed, 45 insertions, 24 deletions
diff --git a/Changelog.md b/Changelog.md
index 18acf14..793bd1d 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,9 @@
+### 0.2.1.0
+
+- Improved treatment of quoted string values in *b64* and *uenc* EDE filters.
+- Added function *renderEDETemplateWith* for templating from any configuration
+ language which is translatable to *Aeson*'s *Value*.
+
### 0.2.0.0
- Added module *NgxExport.Tools.EDE* for parsing JSON values.
diff --git a/NgxExport/Tools/EDE.hs b/NgxExport/Tools/EDE.hs
index 38d1a60..69f0e64 100644
--- a/NgxExport/Tools/EDE.hs
+++ b/NgxExport/Tools/EDE.hs
@@ -20,6 +20,7 @@ module NgxExport.Tools.EDE (
-- * Rendering JSON objects using EDE templates
-- $renderingEDETemplates
renderEDETemplate
+ ,renderEDETemplateWith
) where
import NgxExport
@@ -39,10 +40,8 @@ import Data.ByteString.Base64.URL
import Data.IORef
import Data.Text (Text)
import qualified Data.Text.Encoding as T
-import qualified Data.Text.Lazy as LT
import qualified Data.Text.Lazy.Encoding as LT
-import Data.Aeson (decode, Value)
-import Data.Aeson.Text
+import Data.Aeson (encode, decode, Value (String))
import Network.HTTP.Types.URI (urlEncode)
import Control.Exception (Exception, throwIO)
import System.IO.Unsafe
@@ -51,8 +50,8 @@ import System.IO (FilePath)
-- $renderingEDETemplates
--
-- This module allows for complex parsing of JSON objects with [EDE templating
--- language](http://brendanhay.nz/ede/Text-EDE.html#syntax). In terms of module
--- "NgxExport.Tools", it exports a /single-shot/ service
+-- language](http://hackage.haskell.org/package/ede/docs/Text-EDE.html). In
+-- terms of module "NgxExport.Tools", it exports a /single-shot/ service
-- __/compileEDETemplates/__ to configure the list of templates parameterized
-- by a simple key, and an asynchronous variable handler __/renderEDETemplate/__
-- for parsing POSTed JSON objects and substitution of extracted data in the
@@ -104,26 +103,31 @@ import System.IO (FilePath)
-- rewrite ^ \/internal\/user\/$hs_user last;
-- }
--
+-- location ~ ^\/internal\/user\/(EDE\\ ERROR:.*) {
+-- internal;
+-- echo_status 404;
+-- echo \"Bad input: $1\";
+-- }
+--
-- location ~ ^\/internal\/user\/([^\/]+)\/([^\/]+)\/([^\/]+)$ {
-- internal;
-- echo \"User id: $1, options: $2, path: $3\";
-- }
--
--- location ~ \/internal\/user\/(.*) {
+-- location ~ ^\/internal\/user\/(.*) {
-- internal;
-- echo_status 404;
--- echo \"Bad input for user: $1\";
+-- echo \"Unexpected input: $1\";
-- }
-- }
-- }
-- @
--
--- There is an EDE template declared by the argument of the service
+-- There is an EDE template declared by the argument of service
-- __/simpleService_compileEDETemplates/__. The template will be accessed later
--- in the asynchronous body handler __/renderEDETemplate/__ with the key
--- __/user/__. The path /\/var\/lib\/nginx\/EDE/ can be used in the templates to
--- /include/ more rules from files located inside it, but we do not actually use
--- this here.
+-- in the asynchronous body handler __/renderEDETemplate/__ with key __/user/__.
+-- Path /\/var\/lib\/nginx\/EDE/ can be used in the templates to /include/ more
+-- rules from files located inside it, but we do not actually use this here.
--
-- The rule inside template /user/ says: with given JSON object,
--
@@ -153,7 +157,7 @@ import System.IO (FilePath)
-- Let's try to send a broken (in any meaning) input value.
--
-- > $ curl -d '{"user": {"id" : "user1", "ops": ["op1", "op2"]}, "resources": {"p": "/opt/users"}}' 'http://localhost:8010/'
--- > Bad input for user: EDE ERROR: Text.EDE.parse:1:32 error: variable resources.path doesn't exist.
+-- > Bad input: EDE ERROR: Text.EDE.parse:1:32 error: variable resources.path doesn't exist.
--
-- Now we got response with HTTP status /404/ and a comprehensive description of
-- what went wrong. To not mess rewrite logic and error responses, variable
@@ -164,7 +168,8 @@ import System.IO (FilePath)
-- haskell_var_empty_on_error $hs_user;
-- @
--
--- Now errors will only be logged by Nginx in the error log.
+-- Now the variable will always be empty on errors, while the errors will still
+-- be logged by Nginx in the error log.
type InputTemplates = (FilePath, [(ByteString, ByteString)])
type Templates = HashMap B.ByteString (Result Template)
@@ -195,26 +200,36 @@ filters = HM.fromList
,"uenc" @: applyToValue (T.decodeUtf8 . urlEncode False)
]
where applyToValue :: (ByteString -> Text) -> Value -> Text
- applyToValue f = f . L.toStrict . LT.encodeUtf8 .
- LT.dropAround (== '"') . encodeToLazyText
+ applyToValue f (String t) = f $ T.encodeUtf8 t
+ applyToValue f v = f $ L.toStrict $ encode v
--- | The core function of the /renderEDETemplate/ exporter.
+-- | Render an EDE template from a JSON object.
--
--- Accepts a JSON object written in a 'L.ByteString' and a key to find the EDE
--- template declared by the /compileEDETemplates/ exporter. The function is
--- exported because it can be useful not only in asynchronous body handlers but
--- anywhere else.
+-- This is the core function of the /renderEDETemplate/ exporter. Accepts a
+-- JSON object written in a 'L.ByteString' and a key to find a compiled EDE
+-- template declared by the /compileEDETemplates/ exporter.
renderEDETemplate :: L.ByteString -- ^ JSON object
-> ByteString -- ^ Key to find the EDE template
-> IO L.ByteString
-renderEDETemplate v k = do
+renderEDETemplate = renderEDETemplateWith decode
+
+-- | Render an EDE template with a custom decoding function.
+--
+-- This function can be used for templating from any configuration language
+-- which is translatable to Aeson's 'Value'.
+renderEDETemplateWith
+ :: (L.ByteString -> Maybe Value) -- ^ Decoding function
+ -> L.ByteString -- ^ JSON object
+ -> ByteString -- ^ Key to find the EDE template
+ -> IO L.ByteString
+renderEDETemplateWith fdec v k = do
tpls <- readIORef templates
case HM.lookup k tpls of
Nothing -> throwIO $ EDERenderError $
"EDE template " ++ C8.unpack k ++ " was not found"
Just (Failure msg) -> throwIO $ EDERenderError $ showPlain msg
Just (Success tpl) ->
- case (decode v :: Maybe Value) >>= fromValue of
+ case fdec v >>= fromValue of
Nothing -> throwIO $ EDERenderError $
"Failed to decode value '" ++ C8L.unpack v ++ "'"
Just obj ->
diff --git a/ngx-export-tools-extra.cabal b/ngx-export-tools-extra.cabal
index ad82141..4405e59 100644
--- a/ngx-export-tools-extra.cabal
+++ b/ngx-export-tools-extra.cabal
@@ -1,5 +1,5 @@
name: ngx-export-tools-extra
-version: 0.2.0.0
+version: 0.2.1.0
synopsis: More extra tools for Nginx haskell module
description: More extra tools for
<http://github.com/lyokha/nginx-haskell-module Nginx haskell module>.