proxy_pass 请求基于通过 lua-nginx 的另一个内部请求的结果
proxy_pass request base on the result of another internal request via lua-nginx
我想proxy_pass一个请求或return一个基于内部服务结果的响应。
为了实现这个目的,我使用 openresty docker image
这是我的 nginx.conf
:
# nginx.vh.default.conf -- docker-openresty
#
# This file is installed to:
# `/etc/nginx/conf.d/default.conf`
#
# It tracks the `server` section of the upstream OpenResty's `nginx.conf`.
#
# This config (and any other configs in `etc/nginx/conf.d/`) is loaded by
# default by the `include` directive in `/usr/local/openresty/nginx/conf/nginx.conf`.
#
# See https://github.com/openresty/docker-openresty/blob/master/README.md#nginx-config-files
#
# load_module /usr/lib/nginx/modules/ndk_http_module.so;
# load_module /usr/lib/nginx/modules/ngx_http_lua_module.so;
lua_package_path '/usr/local/nginx/includes.d/?.lua;/home/user/lua/?.lua;/home/lua/?.lua;;';
error_log logs/error.log info;
error_log logs/error.log debug;
upstream flask_webservice {
server challenge:5000;
}
server {
listen 80;
server_name localhost;
lua_need_request_body on;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
# default_type text/plain;
# proxy_pass http://challenge:5000/;
content_by_lua_file /home/user/lua/proxy_middleware.lua;
# content_by_lua_block {}
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/openresty/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root /usr/local/openresty/nginx/html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
这里是proxy_middleware.lua
:
local http = require "resty.http"
local cjson = require "cjson"
local httpc = http.new()
local challenge_url = "http://" .. ngx.var.flask_webservice .. ngx.var.uri
local request_header = ngx.req.get_headers()
local request_method = ngx.req.get_method()
local request_body = ngx.req.get_body_data()
if request_body == nil then
request_body = {}
end
if request_header == nil then
request_header = {}
end
ngx.log(ngx.DEBUG, challenge_url)
ngx.log(ngx.DEBUG, "request_header: " .. cjson.encode(request_header))
ngx.log(ngx.DEBUG, "request_method: " .. request_method)
ngx.log(ngx.DEBUG, "request_body: " .. cjson.encode(request_body))
local res, err = httpc:request_uri(challenge_url, {
method = request_method,
headers = request_header,
body = request_body
})
ngx.log(ngx.DEBUG, "response is:" .. cjson.encode(res))
ngx.log(ngx.DEBUG, "error is:" .. cjson.encode(err))
这是我遇到的错误:
2020/12/24 19:17:52 [error] 7#7: *3 lua entry thread aborted: runtime error: /home/user/lua/proxy_middleware.lua:6: attempt to concatenate field 'flask_webservice' (a nil value)
上的项目
我有两个问题:
- 还有其他方法可以达到这个目的吗?
- 如何在
Lua
代码中访问上游服务器?
我通过 resty-http 管理了第一个请求,然后根据第一个请求的响应
使用 ngx.location.capture
到 proxy_pass 请求
这里是lua_middleware.lua
:
local http = require "resty.http"
local cjson = require "cjson"
local httpc = http.new()
local challenge_url = "http://challenge:5000" .. ngx.var.uri
local request_header = ngx.req.get_headers()
local request_method = ngx.req.get_method()
local request_body = ngx.req.get_body_data()
if request_body == nil then
request_body = {}
end
if request_header == nil then
request_header = {}
end
ngx.log(ngx.DEBUG, challenge_url)
ngx.log(ngx.DEBUG, "request_header: " .. cjson.encode(request_header))
ngx.log(ngx.DEBUG, "request_method: " .. request_method)
ngx.log(ngx.DEBUG, "request_body: " .. cjson.encode(request_body))
local res, err = httpc:request_uri(challenge_url, {
method = request_method,
headers = request_header,
body = request_body
})
local response_body = res.body
local response_headers = res.headers
local response_status = res.status
ngx.log(ngx.DEBUG, "response_body: " .. cjson.encode(response_body))
ngx.log(ngx.DEBUG, "response_headers: " .. cjson.encode(response_headers))
ngx.log(ngx.DEBUG, "response_status: " .. cjson.encode(response_status))
ngx.log(ngx.DEBUG, "error: " .. cjson.encode(err))
ngx.log(ngx.DEBUG, "logger: " .. response_status == 200)
ngx.log(ngx.DEBUG, "status type: " .. type(response_status))
if response_status == 200 then
ngx.log(ngx.DEBUG, "Redirecting ...")
local redirected_res = ngx.location.capture("/redirect_to", {
method = ngx.HTTP_POST,
always_forward_body = true
})
ngx.log(ngx.DEBUG, "redirect res body: " .. cjson.encode(redirected_res.body))
ngx.log(ngx.DEBUG, "redirect res status: " .. cjson.encode(redirected_res.status))
ngx.status = redirected_res.status
ngx.say(redirected_res.body)
ngx.exit(ngx.HTTP_OK)
else
ngx.status = response_status
ngx.say(response_body)
ngx.exit(ngx.HTTP_OK)
end
这是我的 nginx.conf
:
# nginx.vh.default.conf -- docker-openresty
#
# This file is installed to:
# `/etc/nginx/conf.d/default.conf`
#
# It tracks the `server` section of the upstream OpenResty's `nginx.conf`.
#
# This config (and any other configs in `etc/nginx/conf.d/`) is loaded by
# default by the `include` directive in `/usr/local/openresty/nginx/conf/nginx.conf`.
#
# See https://github.com/openresty/docker-openresty/blob/master/README.md#nginx-config-files
#
# load_module /usr/lib/nginx/modules/ndk_http_module.so;
# load_module /usr/lib/nginx/modules/ngx_http_lua_module.so;
lua_package_path '/usr/local/nginx/includes.d/?.lua;/home/user/lua/?.lua;/home/lua/?.lua;;';
error_log logs/error.log info;
error_log logs/error.log debug;
upstream flask_webservice {
server challenge:5000;
}
server {
listen 80;
server_name localhost;
resolver 127.0.0.11;
lua_need_request_body on;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
client_max_body_size 50k;
client_body_buffer_size 50k;
# default_type text/plain;
# proxy_pass http://challenge:5000/;
content_by_lua_file /home/user/lua/proxy_middleware.lua;
}
location /redirect_to {
proxy_pass http://challenge:5000/arvan;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/openresty/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root /usr/local/openresty/nginx/html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
这里是 project link
我想proxy_pass一个请求或return一个基于内部服务结果的响应。 为了实现这个目的,我使用 openresty docker image
这是我的 nginx.conf
:
# nginx.vh.default.conf -- docker-openresty
#
# This file is installed to:
# `/etc/nginx/conf.d/default.conf`
#
# It tracks the `server` section of the upstream OpenResty's `nginx.conf`.
#
# This config (and any other configs in `etc/nginx/conf.d/`) is loaded by
# default by the `include` directive in `/usr/local/openresty/nginx/conf/nginx.conf`.
#
# See https://github.com/openresty/docker-openresty/blob/master/README.md#nginx-config-files
#
# load_module /usr/lib/nginx/modules/ndk_http_module.so;
# load_module /usr/lib/nginx/modules/ngx_http_lua_module.so;
lua_package_path '/usr/local/nginx/includes.d/?.lua;/home/user/lua/?.lua;/home/lua/?.lua;;';
error_log logs/error.log info;
error_log logs/error.log debug;
upstream flask_webservice {
server challenge:5000;
}
server {
listen 80;
server_name localhost;
lua_need_request_body on;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
# default_type text/plain;
# proxy_pass http://challenge:5000/;
content_by_lua_file /home/user/lua/proxy_middleware.lua;
# content_by_lua_block {}
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/openresty/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root /usr/local/openresty/nginx/html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
这里是proxy_middleware.lua
:
local http = require "resty.http"
local cjson = require "cjson"
local httpc = http.new()
local challenge_url = "http://" .. ngx.var.flask_webservice .. ngx.var.uri
local request_header = ngx.req.get_headers()
local request_method = ngx.req.get_method()
local request_body = ngx.req.get_body_data()
if request_body == nil then
request_body = {}
end
if request_header == nil then
request_header = {}
end
ngx.log(ngx.DEBUG, challenge_url)
ngx.log(ngx.DEBUG, "request_header: " .. cjson.encode(request_header))
ngx.log(ngx.DEBUG, "request_method: " .. request_method)
ngx.log(ngx.DEBUG, "request_body: " .. cjson.encode(request_body))
local res, err = httpc:request_uri(challenge_url, {
method = request_method,
headers = request_header,
body = request_body
})
ngx.log(ngx.DEBUG, "response is:" .. cjson.encode(res))
ngx.log(ngx.DEBUG, "error is:" .. cjson.encode(err))
这是我遇到的错误:
2020/12/24 19:17:52 [error] 7#7: *3 lua entry thread aborted: runtime error: /home/user/lua/proxy_middleware.lua:6: attempt to concatenate field 'flask_webservice' (a nil value)
上的项目
我有两个问题:
- 还有其他方法可以达到这个目的吗?
- 如何在
Lua
代码中访问上游服务器?
我通过 resty-http 管理了第一个请求,然后根据第一个请求的响应
使用ngx.location.capture
到 proxy_pass 请求
这里是lua_middleware.lua
:
local http = require "resty.http"
local cjson = require "cjson"
local httpc = http.new()
local challenge_url = "http://challenge:5000" .. ngx.var.uri
local request_header = ngx.req.get_headers()
local request_method = ngx.req.get_method()
local request_body = ngx.req.get_body_data()
if request_body == nil then
request_body = {}
end
if request_header == nil then
request_header = {}
end
ngx.log(ngx.DEBUG, challenge_url)
ngx.log(ngx.DEBUG, "request_header: " .. cjson.encode(request_header))
ngx.log(ngx.DEBUG, "request_method: " .. request_method)
ngx.log(ngx.DEBUG, "request_body: " .. cjson.encode(request_body))
local res, err = httpc:request_uri(challenge_url, {
method = request_method,
headers = request_header,
body = request_body
})
local response_body = res.body
local response_headers = res.headers
local response_status = res.status
ngx.log(ngx.DEBUG, "response_body: " .. cjson.encode(response_body))
ngx.log(ngx.DEBUG, "response_headers: " .. cjson.encode(response_headers))
ngx.log(ngx.DEBUG, "response_status: " .. cjson.encode(response_status))
ngx.log(ngx.DEBUG, "error: " .. cjson.encode(err))
ngx.log(ngx.DEBUG, "logger: " .. response_status == 200)
ngx.log(ngx.DEBUG, "status type: " .. type(response_status))
if response_status == 200 then
ngx.log(ngx.DEBUG, "Redirecting ...")
local redirected_res = ngx.location.capture("/redirect_to", {
method = ngx.HTTP_POST,
always_forward_body = true
})
ngx.log(ngx.DEBUG, "redirect res body: " .. cjson.encode(redirected_res.body))
ngx.log(ngx.DEBUG, "redirect res status: " .. cjson.encode(redirected_res.status))
ngx.status = redirected_res.status
ngx.say(redirected_res.body)
ngx.exit(ngx.HTTP_OK)
else
ngx.status = response_status
ngx.say(response_body)
ngx.exit(ngx.HTTP_OK)
end
这是我的 nginx.conf
:
# nginx.vh.default.conf -- docker-openresty
#
# This file is installed to:
# `/etc/nginx/conf.d/default.conf`
#
# It tracks the `server` section of the upstream OpenResty's `nginx.conf`.
#
# This config (and any other configs in `etc/nginx/conf.d/`) is loaded by
# default by the `include` directive in `/usr/local/openresty/nginx/conf/nginx.conf`.
#
# See https://github.com/openresty/docker-openresty/blob/master/README.md#nginx-config-files
#
# load_module /usr/lib/nginx/modules/ndk_http_module.so;
# load_module /usr/lib/nginx/modules/ngx_http_lua_module.so;
lua_package_path '/usr/local/nginx/includes.d/?.lua;/home/user/lua/?.lua;/home/lua/?.lua;;';
error_log logs/error.log info;
error_log logs/error.log debug;
upstream flask_webservice {
server challenge:5000;
}
server {
listen 80;
server_name localhost;
resolver 127.0.0.11;
lua_need_request_body on;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
client_max_body_size 50k;
client_body_buffer_size 50k;
# default_type text/plain;
# proxy_pass http://challenge:5000/;
content_by_lua_file /home/user/lua/proxy_middleware.lua;
}
location /redirect_to {
proxy_pass http://challenge:5000/arvan;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/openresty/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root /usr/local/openresty/nginx/html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
这里是 project link