Работа с nginx + lua

nginx redis lua - record post params

Generally with payment gateways, we receive an http request to confirm a transaction. This transaction is important and the http requests must be processed. For example, we want our stack to stay available during a deployment.
Our goal is to record the payload received from a payment pingback in a Redis queue, without involving the application code.
nginx allows lua scripting with thirdparty modules lua-nginx-module.
For Redis we will use the lua-resty-redis module.
If you are on a Debian system and don't want to recompile nginx you can use the nginx-extras and lua-nginx-redispackages.
aptitude install redis nginx-extras lua-nginx-redis lua-json
Then we can create a server with this nginx config:
# on Debian the lua-nginx-redis is installed here
lua_package_path "/usr/share/lua/5.1/nginx/?.lua;;";
server {
  server_name payment.local;
  location / {
     content_by_lua '
-- connect to redis
local redis = require "redis"
local json = require "json"
local red = redis:new()
red:set_timeout(1000) -- 1 sec
local ok, err = red:connect("", 6379)
if not ok then
    ngx.say("failed to connect: ", err)

-- read post data
local args = ngx.req.get_post_args()
if not args then
    ngx.say("failed to get post args: ", err)

local args_to_redis = json.encode(args)

-- record it to redis
local ans, err = red:lpush("payment", args_to_redis)
if not ans then
    ngx.say("failed to run rpush: ", err)
Once nginx is reloaded, it can be tested with this curl command:
curl -v -XPOST \
    -d "TPE=1234567&date=05%2f12%2f2006%5fa%5f11%3a55%3a23&montant=62%2e75EUR&reference=ABERTYP00145&MAC=e4359a2c18d86cf2e4b0e646016c202e89947b04&texte-libre=LeTexteLibre&code-retour=payetest&cvx=oui&vld=1208&brand=VI&status3ds=1&numauto=010101&originecb=FRA&bincb=010101&hpancb=74E94B03C22D786E0F2C2CADBFC1C00B004B7C45&ipclient=127%2e0%2e0%2e1&originetr=FRA&veres=Y&pares=Y" \
We can get the params, for example, on a Ruby script that parses the recorded post from nginx.
require 'redis'
require 'json'
redis = Redis.new
list, element = redis.blpop("payment")


Дополнительные ссылки на материалы:

Комментариев нет:

Отправить комментарий