Operate HTTP request header through lua

1. How to operate http header through openresty

http header is divided into request header and response header

The request header is operated in the access_by_lua stage of nginx. The operation request header involves two functions.

1. ngx.req.get_headers. The first parameter requests the number of headers. By default, 100 headers are analyzed to prevent malicious attacks. The second parameter defaults to converting the header field information to lowercase. If set to true, it will be turned off.

2. ngx.req.set_headers does some setting operations on the header domain information, and can be set to table

The respnse header usually operates the response header in the header filter stage. You can read the response header information through the ngx.header. * method, or you can rewrite the header information.

Second, the test

2.1 Test 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. Modify request_header.json

local headers = ngx.req.get_headers(1)

After nginx -s reload is hot loaded, only one header is printed in response to request_header

3. Modify request_header.json

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

nginx -s reload After hot loading, the request_header response header remains unchanged

2.2 Test set_headers

 

Add conf / lua / sub_request_header.json file

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

Modify conf / lua / request_header.json file

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

Subrequest set_header

2.3 Test 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

The lua_transform_underscores_in_response_headers directive is set in nginx.conf to keep the case in response.header

2.3.2 Modify response_header.json

2.3.3 Modify response_header.json, if the ContentType is changed to table, only the last value is taken out

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

2.3.4 Test response.header type is table

Modify response_header.json

ngx.say(type(ngx.header))

2.3.5 Print response.header content using parirs method, the print content is empty

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 Print 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) As you can see in the above demo, the header information is set by ngx.header. *. It should be noted that functions such as ngx.set_headers, ngx.print, ngx.c cannot be used to change the header information through ngx.header. The reason is that after these functions are called, a content handle is triggered to return. After the content handle is returned, the setting of the general information will be invalid. If you call ngx.header after these functions to change the header information, you will get a lua exception.

(2) ngx.header is an ordinary lua table

(3) Access the Foo domain through ngx.header.Foo, which will be mapped to index internally, and jump to a C function, and then do such access

(4) ngx.header.Foo = 'Bar' This way to change a domain information, it will be mapped to del index internally to complete the domain information change, do not try to use pairs and ipairs to traverse ngx.header, but through ngx. resp.get_header () to get the header information returned, the information obtained by this function is not complete

3. Summary

Request header (ngx.req.get_headers / ngx.req.set_headers) and response header (ngx.header / ngx.resp.get_headers) operation and reading

Published 524 original articles · praised 172 · 100,000+ views

Guess you like

Origin blog.csdn.net/INGNIGHT/article/details/104914689