通过lua操作http请求头

一、如何通过openresty操作http头

http头分请求头和,响应头

在nginx的access_by_lua阶段操作请求头,操作请求头涉及两个函数。

1、ngx.req.get_headers,第一个参数请求头个数,默认分析100个头,防止恶意攻击,第二个参数默认将头域信息转为小写,如果设置为true会关闭掉。

2、ngx.req.set_headers对头的域信息作一些设置操作,并且可以设置为table

respnse header通常在header filter阶段操作响应头,可以通过ngx.header.*方法读取响应头信息,也可以重写头信息。

二、测试

2.1测试get_headers

1.conf/lua/request_header.json

local function print_table(t)
    local function parse_array(key, tab)
        local str = ''
        for _, v in pairs(tab) do
            str = str .. key .. ' ' .. v .. '\r\n'
        end
        return str
    end

    local str = ''
    for k, v in pairs(t) do
        if type(v) == "table" then
            str = str .. parse_array(k, v)
        else
            str = str .. k .. ' ' .. v .. '\r\n'
        end
    end
    return str
end

local headers = ngx.req.get_headers()
ngx.say(print_table(headers))
curl -H "Foo:bar"  http://localhost:8080/request_header

2.修改request_header.json

local headers = ngx.req.get_headers(1)

nginx -s reload热加载后,请求request_header响应只有打印了一个header

3.修改request_header.json

local headers = ngx.req.get_headers(0, true)

nginx -s reload热加载后,请求request_header响应header大小写保持不变

2.2测试set_headers

增加conf/lua/sub_request_header.json文件

cp conf/lua/request_header.json conf/lua/sub_request_header.json
 

修改conf/lua/request_header.json文件

local function print_table(t)
    local function parse_array(key, tab)
        local str = ''
        for _, v in pairs(tab) do
            str = str .. key .. ' ' .. v .. '\r\n'
        end
        return str
    end

    local str = ''
    for k, v in pairs(t) do
        if type(v) == "table" then
            str = str .. parse_array(k, v)
        else
            str = str .. k .. ' ' .. v .. '\r\n'
        end
    end
    return str
end

--local headers = ngx.req.get_headers(0, true)
--ngx.say(print_table(headers))
ngx.req.set_header('Foo', 'Bar')
local res = ngx.location.capture('/sub_request_header.json')
if res.status == ngx.HTTP_OK then
    ngx.say(res.body)
else
    ngx.exit(res.status)
end

子请求set_header

2.3测试response.header.*

2.3.1

ngx.header.Foo = 'Bar'

--lua_transform_underscores_in_response_headers

ngx.header['Foo_Bar'] = 'Bar2'
curl -I http://localhost:8080/response_header

lua_transform_underscores_in_response_headers指令设置在nginx.conf,可以保持response.header中大小写保持不变

2.3.2修改response_header.json

2.3.3修改response_header.json,如果修改ContentType后边为table,只取出最后一个值

--ngx.header['Content_Type'] = {"a=32; path", "text"}
ngx.header['content_type'] = {"a=32; path", "text"}

2.3.4测试response.header的类型为table

修改response_header.json

ngx.say(type(ngx.header))

2.3.5打印response.header内容使用parirs方式,打印内容为空

local function print_table(t)
    local function parse_array(key, tab)
        local str = ''
        for _, v in pairs(tab) do
            str = str .. key .. ' ' .. v .. '\r\n'
        end
        return str
    end

    local str = ''
    for k, v in pairs(t) do
        if type(v) == "table" then
            str = str .. parse_array(k, v)
        else
            str = str .. k .. ' ' .. v .. '\r\n'
        end
    end
    return str
end

ngx.say(print_table(ngx.header))

2.3.6打印response.header

local function print_table(t)
    local function parse_array(key, tab)
        local str = ''
        for _, v in pairs(tab) do
            str = str .. key .. ' ' .. v .. '\r\n'
        end
        return str
    end

    local str = ''
    for k, v in pairs(t) do
        if type(v) == "table" then
            str = str .. parse_array(k, v)
        else
            str = str .. k .. ' ' .. v .. '\r\n'
        end
    end
    return str
end

ngx.header.Foo = 'Bar'
local resp = ngx.resp.get_headers(0, true)
ngx.say(print_table(resp))

(1)上面演示可以看到,通过ngx.header.*方式设置头信息。需要注意像ngx.set_headers,ngx.print,ngx.c这样函数后面,不能通过ngx.header去设置改变头信息。原因是这些函数调用后,触发一个内容句柄返回,内容句柄返回后,通头信息的设置会失效。如果在这些函数后面,调用ngx.header改变头信息,会得到lua异常。

(2)ngx.header就是一个普通的lua table

(3)通过ngx.header.Foo访问Foo这个域,内部会映射到index,并且跳转一个c函数,再去做这样的访问

(4)ngx.header.Foo='Bar'这样方式改变一个域信息,内部会映射到del index,来完成域信息改变,不要尝试使用pairs和ipairs方式去遍历ngx.header,而是通过ngx.resp.get_header()去获取所头部信息返回,这个函数获取的信息也并非是完全的

三、总结

请求头(ngx.req.get_headers/ngx.req.set_headers)和响应头(ngx.header/ngx.resp.get_headers)的操作和读取

发布了524 篇原创文章 · 获赞 172 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/INGNIGHT/article/details/104914689