worker_processes auto;
error_log logs/error.log debug;
events {
worker_connections 1024;
}
stream {
resolver 127.0.0.1;
lua_add_variable $VMess;
server {
listen 80;
preread_by_lua_block {
local sock, err = ngx.req.socket()
if sock then
-- ngx.say("got the request socket")
else
ngx.say("failed to get the request socket: ", err)
end
local data, err = sock:peek(16)
local datal, err = sock:peek(58)
if string.match(data, "HTTP") then
-- for normal http req
ngx.var.VMess = "8080"
else
-- for V2Ray's tcp+TLS +web
ngx.var.VMess = "10080"
end
}
proxy_pass 127.0.0.1:$VMess;
}
}
与 bug 有关的页面 / related page
tls_routing_with_nginx.md
bug 描述 / description of the bug
缺陷:
使用该配置,path过长的http请求无法通过
proxy_pass
转发给WEB服务器。造成缺陷的原因:
当正常的HTTP流量path过长时,
local data, err = sock:peek(16)
只会拿到method+空格+不完整的path,无法被任何if/elseif分支匹配到,最终在else分支匹配命中,请求将会转发给V2ray后端。复现步骤 / how we can reproduce
在此描述复现出现的问题所需的步骤和环境。
使用教程中的配置简化和修改后的配置:
http://domain.name/123456
正常,但是请求http://domain.name/1234567
则会无法得到响应http://domain.name/1234567
无法得到响应,但是使用浏览器先访问短 path 或无 path 的 url (如http://domain.name/123456
)在短时间内再跳转到http://domain.name/1234567
,则可获得正常的服务器响应。 可能是preread_by_lua_block
块只在浏览器的第一个请求时执行了一次? 但即使如此,正常使用环境也有可能面临需要直接访问长path的场景,比如 V2ray 客户端从订阅链接获取节点配置时。