nginx中不同client设置User-Agent与user_agent的坑

最近发现nginx内部用lua获取user_agent,得到的是一个table值,很奇怪,自己测试记录一下:

1、nginx配置

location /zcy/hello {
    set_by_lua $ret '
        local headers = ngx.req.get_headers();
        
        ngx.log(ngx.ERR, "user_agent value: ", headers["user_agent"])
        ngx.log(ngx.ERR, "user-agent value: ", headers["user-agent"])

        if type(headers["user_agent"]) == "table" then
            local str = ""
            for k, v in pairs(headers["user_agent"]) do
                str = str .. k .. ":" .. v .. ","
            end
            ngx.log(ngx.ERR, "user_agent type table: ", str)
        else
            ngx.log(ngx.ERR, "user_agent value: ", headers["user_agent"])
        end
        return;
    ';

    set $ret_body '{"code": "200","msg": "zcy"}';
    return 200 $ret_body;
}

 

2、Python测试user_agent和User-Agent

首先说明一下,Python不能同时设置两个相同的header,例如两个user_agent

测试1

def test_agent_1():
    url = 'http://localhost:8888/zcy/hello'
    r = requests.get(url,
            headers={
                'host':'zcy-server',
                'user_agent':'zcy_agent (1)',
                'User-Agent':'zcy_agent (2)',
                })
    assert 200 == r.status_code

日志结果: 
    user_agent: zcy_agent (1)
    user-agent: zcy_agent (2)

分析:得到两个不同的值

测试2:

def test_agent_2():
    url = 'http://localhost:8888/zcy/hello'
    r = requests.get(url,
            headers={
                'host':'zcy-server',
                'user_agent':'zcy_agent (3)',
                'user_agent':'zcy_agent (4)',
                })
    assert 200 == r.status_code

日志结果: 
    user_agent: zcy_agent (4)
    user-agent: python-requests/2.21.0

分析:user-agent值为默认的python-requests

测试3:

def test_agent_3():
    url = 'http://localhost:8888/zcy/hello'
    r = requests.get(url,
            headers={
                'host':'zcy-server',
                'User-Agent':'zcy_agent (5)', 
                'User-Agent':'zcy_agent (6)',
                })
    assert 200 == r.status_code

日志结果: 
    user_agent: zcy_agent (5)
    user-agent: zcy_agent (5)

分析:user_agent和user-agent都有值,且是Python第一次设置的值zcy_agent (5)。且在Nginx内部user-agent的值会传给user_agent。

 

3、CURL测试user_agent和User-Agent

curl命令1:

curl "http://localhost:8888/zcy/hello" -H 'user_agent:zcy_agent (1)' -H 'User-Agent:zcy_agent (2)'

结果
user_agent value: zcy_agent (2)
user-agent value: zcy_agent (2)

分析:设置的User-Agent有效,curl内部可能将user_agent的值设置为user-agent的值 

curl命令2:

curl "http://localhost:8888/zcy/hello" -i -H "host:zcy-server" -H 'user_agent:zcy_agent (3)' -H 'user_agent:zcy_agent (4)'

结果
 user_agent value: curl/7.29.0
 user-agent value: curl/7.29.0

分析:设置user_agent无效

curl命令3:

curl "http://localhost:8888/zcy/hello" -H "User-Agent:zcy_agent (5)" -H "User-Agent:zcy_agent (6)"

结果
user_agent和user-agent都是table,lua报错

 

为什么会是table类型呢,因为是可以设置的,查看:https://github.com/openresty/lua-nginx-module#ngxreqget_headers

For multiple instances of request headers such as:

 Foo: foo
 Foo: bar
 Foo: baz

the value of ngx.req.get_headers()["Foo"] will be a Lua (array) table such as:

 {"foo", "bar", "baz"}

4、结论

1:设置http头要根据client的设置情况,Python不能设置重复的http头,而curl可以设置重复http头

2:当客户端同时设置user_agent和user-agent时,也是根据不同客户端情况进行分析,比如curl内部可能将user_agent的值设置为user-agent的值 。

3:curl可以设置重复的http头,这样导致nginx内部获取http头时解析出问题,因为lua类型是一个table。

请我喝咖啡

如果觉得文章写得不错,能对你有帮助,可以扫描我的微信二维码请我喝咖啡哦~~哈哈~~

你可能感兴趣的:(http,Nginx)