Skip to content

Commit

Permalink
[policy] introduce content phase
Browse files Browse the repository at this point in the history
need to share context between internal redirect
(openresty/lua-nginx-module#1057)

but then the policies have total control over generating the content
so they can use cosockets / files / upstream / generate content

please note this is higly experimental and should not be merged to
master yet
  • Loading branch information
mikz committed Dec 22, 2017
1 parent 056428b commit 4346bf1
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 13 deletions.
31 changes: 21 additions & 10 deletions gateway/conf.d/apicast.conf
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,25 @@ location @out_of_band_authrep_action {
}
}

location @upstream {
internal;

rewrite_by_lua_block {
require('resty.exec').ctx(ngx.var.ctx_ref)
}

proxy_pass $proxy_pass;

proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-3scale-proxy-secret-token $secret_token;
proxy_set_header X-3scale-debug "";
proxy_set_header Connection "";

post_action @out_of_band_authrep_action;
}

location / {
set $cached_key null;
set $credentials null;
Expand All @@ -76,6 +95,8 @@ location / {
set $version '';
set $real_url null;

set $ctx_ref -1;

set $post_action_impact null;
set $original_request_id null;

Expand All @@ -88,16 +109,6 @@ location / {

content_by_lua_block { require('apicast.executor'):content() }

proxy_pass $proxy_pass;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-3scale-proxy-secret-token $secret_token;
proxy_set_header X-3scale-debug "";
proxy_set_header Connection "";

post_action @out_of_band_authrep_action;

include ../apicast.d/location.d/*.conf;
}

Expand Down
6 changes: 6 additions & 0 deletions gateway/src/apicast/policy/apicast/policy.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local math = math
local setmetatable = setmetatable

local user_agent = require('apicast.user_agent')
local exec = require('resty.exec')

local noop = function() end

Expand Down Expand Up @@ -101,6 +102,11 @@ function _M:access(context)
return ok, err
end

_M.content = function()
ngx.var.ctx_ref = exec.ctx_ref()
ngx.exec("@upstream")
end

_M.body_filter = noop
_M.header_filter = noop

Expand Down
6 changes: 4 additions & 2 deletions gateway/src/apicast/policy/echo/policy.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ function _M.new(configuration)
return policy
end

function _M:content()
ngx.say(ngx.var.request)
end

function _M:rewrite()
if self.status then
ngx.status = self.status
end

ngx.say(ngx.var.request)

if self.exit == 'request' then
return ngx.exit(ngx.status)
elseif self.exit == 'phase' then
Expand Down
1 change: 1 addition & 0 deletions gateway/src/apicast/policy/policy.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ local _M = { }
local PHASES = {
'init', 'init_worker',
'rewrite', 'access', 'balancer',
'content',
'header_filter', 'body_filter',
'post_action', 'log'
}
Expand Down
68 changes: 68 additions & 0 deletions gateway/src/resty/exec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
local ffi = require 'ffi'
local debug = require 'debug'
local base = require "resty.core.base"
local misc = require "resty.core.misc"


local registry = debug.getregistry()
local new_tab = base.new_tab
local ref_in_table = base.ref_in_table
local getfenv = getfenv
local C = ffi.C
local FFI_NO_REQ_CTX = base.FFI_NO_REQ_CTX
local FFI_OK = base.FFI_OK
local error = error


local _M = {

}

local mt = {}

setmetatable(_M, mt)

local exec = ngx.exec

function _M.ctx_ref()
local r = getfenv(0).__ngx_req

if not r then
return error("no request found")
end

local ctx = ngx.ctx
local ctx_ref = C.ngx_http_lua_ffi_get_ctx_ref(r)
if ctx_ref == FFI_NO_REQ_CTX then
return error("no request ctx found")
end

local ctxs = registry.ngx_lua_ctx_tables
-- TODO: why they are not equal?
if ctx_ref == ref_in_table(ctxs, ctx) then
return ctx_ref
end

return ctx_ref
end

function _M.ctx(ref)
local r = getfenv(0).__ngx_req

if not r then
return error("no request found")
end

local ctx_ref = tonumber(ref)
if not ctx_ref then
return
end

if C.ngx_http_lua_ffi_set_ctx_ref(r, ctx_ref) ~= FFI_OK then
return nil
end

return true
end

return _M
3 changes: 2 additions & 1 deletion spec/policy_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ local policy = require 'apicast.policy'
describe('policy', function()
local phases = {
'init', 'init_worker',
'rewrite', 'access', 'balancer',
'rewrite', 'access',
'content', 'balancer',
'header_filter', 'body_filter',
'post_action', 'log'
}
Expand Down

0 comments on commit 4346bf1

Please sign in to comment.