File: misc.lua

package info (click to toggle)
lua-resty-core 0.1.32-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,268 kB
  • sloc: sh: 207; perl: 143; makefile: 26
file content (258 lines) | stat: -rw-r--r-- 5,841 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
-- Copyright (C) Yichun Zhang (agentzh)


local base = require "resty.core.base"
local ffi = require "ffi"
local os = require "os"


local C = ffi.C
local ffi_new = ffi.new
local ffi_str = ffi.string
local ngx = ngx
local type = type
local error = error
local rawget = rawget
local rawset = rawset
local tonumber = tonumber
local setmetatable = setmetatable
local FFI_OK = base.FFI_OK
local FFI_NO_REQ_CTX = base.FFI_NO_REQ_CTX
local FFI_BAD_CONTEXT = base.FFI_BAD_CONTEXT
local new_tab = base.new_tab
local get_request = base.get_request
local get_size_ptr = base.get_size_ptr
local get_string_buf = base.get_string_buf
local get_string_buf_size = base.get_string_buf_size
local subsystem = ngx.config.subsystem


local ngx_lua_ffi_get_resp_status
local ngx_lua_ffi_get_conf_env
local ngx_magic_key_getters
local ngx_magic_key_setters


local _M = new_tab(0, 3)
local ngx_mt = new_tab(0, 2)


if subsystem == "http" then
    ngx_magic_key_getters = new_tab(0, 4)
    ngx_magic_key_setters = new_tab(0, 2)

elseif subsystem == "stream" then
    ngx_magic_key_getters = new_tab(0, 2)
    ngx_magic_key_setters = new_tab(0, 1)
end


local function register_getter(key, func)
    ngx_magic_key_getters[key] = func
end
_M.register_ngx_magic_key_getter = register_getter


local function register_setter(key, func)
    ngx_magic_key_setters[key] = func
end
_M.register_ngx_magic_key_setter = register_setter


ngx_mt.__index = function (tb, key)
    local f = ngx_magic_key_getters[key]
    if f then
        return f()
    end
    return rawget(tb, key)
end


ngx_mt.__newindex = function (tb, key, ctx)
    local f = ngx_magic_key_setters[key]
    if f then
        return f(ctx)
    end
    return rawset(tb, key, ctx)
end


setmetatable(ngx, ngx_mt)


if subsystem == "http" then
    ffi.cdef[[
    int ngx_http_lua_ffi_get_resp_status(ngx_http_request_t *r);
    int ngx_http_lua_ffi_set_resp_status(ngx_http_request_t *r, int r);
    int ngx_http_lua_ffi_is_subrequest(ngx_http_request_t *r);
    int ngx_http_lua_ffi_headers_sent(ngx_http_request_t *r);
    int ngx_http_lua_ffi_get_conf_env(const unsigned char *name,
                                      unsigned char **env_buf,
                                      size_t *name_len);
    int ngx_http_lua_ffi_req_is_internal(ngx_http_request_t *r);
    ]]


    ngx_lua_ffi_get_resp_status = C.ngx_http_lua_ffi_get_resp_status
    ngx_lua_ffi_get_conf_env = C.ngx_http_lua_ffi_get_conf_env


    -- ngx.status


    local function set_status(status)
        local r = get_request()

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

        if type(status) ~= 'number' then
            status = tonumber(status)
        end

        local rc = C.ngx_http_lua_ffi_set_resp_status(r, status)

        if rc == FFI_BAD_CONTEXT then
            error("API disabled in the current context", 2)
        end
    end
    register_setter("status", set_status)


    -- ngx.is_subrequest


    local function is_subreq()
        local r = get_request()

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

        local rc = C.ngx_http_lua_ffi_is_subrequest(r)

        if rc == FFI_BAD_CONTEXT then
            error("API disabled in the current context", 2)
        end

        return rc == 1
    end
    register_getter("is_subrequest", is_subreq)


    -- ngx.headers_sent


    local function headers_sent()
        local r = get_request()

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

        local rc = C.ngx_http_lua_ffi_headers_sent(r)

        if rc == FFI_NO_REQ_CTX then
            error("no request ctx found")
        end

        if rc == FFI_BAD_CONTEXT then
            error("API disabled in the current context", 2)
        end

        return rc == 1
    end
    register_getter("headers_sent", headers_sent)


    -- ngx.req.is_internal


    function ngx.req.is_internal()
        local r = get_request()
        if not r then
            error("no request found")
        end

        local rc = C.ngx_http_lua_ffi_req_is_internal(r)

        if rc == FFI_BAD_CONTEXT then
            error("API disabled in the current context")
        end

        return rc == 1
    end

elseif subsystem == "stream" then
    ffi.cdef[[
    int ngx_stream_lua_ffi_get_resp_status(ngx_stream_lua_request_t *r);
    int ngx_stream_lua_ffi_get_conf_env(const unsigned char *name,
                                        unsigned char **env_buf,
                                        size_t *name_len);
    ]]

    ngx_lua_ffi_get_resp_status = C.ngx_stream_lua_ffi_get_resp_status
    ngx_lua_ffi_get_conf_env = C.ngx_stream_lua_ffi_get_conf_env
end


-- ngx.status


local function get_status()
    local r = get_request()

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

    local rc = ngx_lua_ffi_get_resp_status(r)

    if rc == FFI_BAD_CONTEXT then
        error("API disabled in the current context", 2)
    end

    return rc
end
register_getter("status", get_status)


do
    local _getenv = os.getenv
    local env_ptr = ffi_new("unsigned char *[1]")

    os.getenv = function (name)
        local r = get_request()
        if r then
            -- past init_by_lua* phase now
            os.getenv = _getenv
            env_ptr = nil
            return os.getenv(name)
        end

        local size = get_string_buf_size()
        env_ptr[0] = get_string_buf(size)
        local name_len_ptr = get_size_ptr()

        local rc = ngx_lua_ffi_get_conf_env(name, env_ptr, name_len_ptr)
        if rc == FFI_OK then
            return ffi_str(env_ptr[0] + name_len_ptr[0] + 1)
        end

        -- FFI_DECLINED

        local value = _getenv(name)
        if value ~= nil then
            return value
        end

        return nil
    end
end


_M._VERSION = base.version


return _M