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

19 篇文章 1 订阅

最近发现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。

请我喝咖啡

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了解决`strict-origin-when-cross-origin`跨域问题,可以在nginx配置文件添加以下内容: ``` location / { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # # Custom headers and headers various browsers *should* be OK with but aren't # add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; # # Tell client that this pre-flight info is valid for 20 days # add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } if ($request_method = 'POST') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; } if ($request_method = 'GET') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; } } ``` 这段代码会在nginx的配置文件添加跨域处理的相关配置,包括允许的请求方法、请求头、响应头等信息。其`Access-Control-Allow-Origin`设置为`*`表示允许所有来源的请求访问该资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值