OpenResty body_filter_by_lua Nginx 指定返回内容

背景:

需要统一处理error的返回,其实呢就是nginx 默认的error 会是html格式,而且返回的不符合我们统一规范,所以需要在最后归一化。 当然也可以延伸到 在body_filter_by_lua中 修改返回内容,甚至指定返回内容


原理说明:

首先需要先声明!!HTTP1.1 之后基于流式处理的方式,body_filter_by_lua 基本在一个请求中会调用多次。 简单直白的理解就是流式输出,每次拿到了如果你要处理那么就处理,不处理就输出!!

git 源码链接  body_filter_by_lua  

The input data chunk is passed via ngx.arg[1] (as a Lua string value) and the "eof" flag indicating the end of the response body data stream is passed via ngx.arg[2] (as a Lua boolean value).

简单说明就是

流每次的内容输出在ngx.arg[1]  中; 是否到eof -最后 的标记在ngx.arg[2] 中

所以你要改输出内容 那么就把ngx.arg[1]  改掉,如果不想要以后的内容了那么ngx.arg[2]=true 就行


代码:

body_filter.lua
---
--- Created by sunfangyuan.
--- DateTime: 18/1/31 上午9:53
---
local headers = ngx.header
local constant = require("conf.constant")
local log = ngx.log
local ERR = ngx.ERR
local json_util = require("cjosn")

local function res_json()
    local res = {}
    res["message"] = "你希望输出的内容"
    res["code"] = "你希望输出的内容"
    return json_util.encode(res)
end

if headers["Content-Type"] == nil or string.find(headers["Content-Type"], "application/json") == nil then
    local status = ngx.var.status
    headers["Content-Type"] = "application/json"
    local chunk, eof = ngx.arg[1], ngx.arg[2]  -- 获取当前的流 和是否时结束
    local info = ngx.ctx.buf
    chunk = chunk or ""
    if info then
        ngx.ctx.buf = info .. chunk -- 这个可以将原本的内容记录下来
    else
        ngx.ctx.buf = chunk
    end
    if eof then
        ngx.ctx.buffered = nil
        if status == 413 or status == "413" then  -- 413是nginx request body 超过限制时的状态吗
            ngx.arg[1] = res_json() -- 这个是你期待输出的内容
        else
            log(ERR, "[ Internal Exception ] " .. ngx.ctx.buf)
            ngx.arg[1] = res_json()
        end
    else
        ngx.arg[1] = nil -- 这里是为了将原本的输出不显示
    end
end

由于改变了body内容长度,记得更新header 里的长度

ngx.header.content_length = nil




你可能感兴趣的:(openresty)