ACIL FM
Dark
Refresh
Current DIR:
/opt/imunify360-webshield/lualib/resty
/
opt
imunify360-webshield
lualib
resty
Upload
Zip Selected
Delete Selected
Pilih semua
Nama
Ukuran
Permission
Aksi
core
-
chmod
Open
Rename
Delete
dns
-
chmod
Open
Rename
Delete
limit
-
chmod
Open
Rename
Delete
lrucache
-
chmod
Open
Rename
Delete
template
-
chmod
Open
Rename
Delete
upstream
-
chmod
Open
Rename
Delete
websocket
-
chmod
Open
Rename
Delete
aes.lua
9.62 MB
chmod
View
DL
Edit
Rename
Delete
cookie.lua
5.55 MB
chmod
View
DL
Edit
Rename
Delete
core.lua
710 B
chmod
View
DL
Edit
Rename
Delete
http.lua
28.99 MB
chmod
View
DL
Edit
Rename
Delete
http_headers.lua
1.12 MB
chmod
View
DL
Edit
Rename
Delete
lock.lua
4.58 MB
chmod
View
DL
Edit
Rename
Delete
lrucache.lua
6.95 MB
chmod
View
DL
Edit
Rename
Delete
md5.lua
1.19 MB
chmod
View
DL
Edit
Rename
Delete
random.lua
672 B
chmod
View
DL
Edit
Rename
Delete
sha.lua
236 B
chmod
View
DL
Edit
Rename
Delete
sha1.lua
1.16 MB
chmod
View
DL
Edit
Rename
Delete
sha224.lua
1.02 MB
chmod
View
DL
Edit
Rename
Delete
sha256.lua
1.19 MB
chmod
View
DL
Edit
Rename
Delete
sha384.lua
1.02 MB
chmod
View
DL
Edit
Rename
Delete
sha512.lua
1.33 MB
chmod
View
DL
Edit
Rename
Delete
shell.lua
4.88 MB
chmod
View
DL
Edit
Rename
Delete
signal.lua
3.12 MB
chmod
View
DL
Edit
Rename
Delete
string.lua
887 B
chmod
View
DL
Edit
Rename
Delete
template.lua
22.69 MB
chmod
View
DL
Edit
Rename
Delete
Edit file: /opt/imunify360-webshield/lualib/resty/http.lua
local http_headers = require "resty.http_headers" local ngx = ngx local ngx_socket_tcp = ngx.socket.tcp local ngx_req = ngx.req local ngx_req_socket = ngx_req.socket local ngx_req_get_headers = ngx_req.get_headers local ngx_req_get_method = ngx_req.get_method local str_gmatch = string.gmatch local str_lower = string.lower local str_upper = string.upper local str_find = string.find local str_sub = string.sub local tbl_concat = table.concat local tbl_insert = table.insert local ngx_encode_args = ngx.encode_args local ngx_re_match = ngx.re.match local ngx_re_gmatch = ngx.re.gmatch local ngx_re_sub = ngx.re.sub local ngx_re_gsub = ngx.re.gsub local ngx_re_find = ngx.re.find local ngx_log = ngx.log local ngx_DEBUG = ngx.DEBUG local ngx_ERR = ngx.ERR local ngx_var = ngx.var local ngx_print = ngx.print local ngx_header = ngx.header local co_yield = coroutine.yield local co_create = coroutine.create local co_status = coroutine.status local co_resume = coroutine.resume local setmetatable = setmetatable local tonumber = tonumber local tostring = tostring local unpack = unpack local rawget = rawget local select = select local ipairs = ipairs local pairs = pairs local pcall = pcall local type = type -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1 local HOP_BY_HOP_HEADERS = { ["connection"] = true, ["keep-alive"] = true, ["proxy-authenticate"] = true, ["proxy-authorization"] = true, ["te"] = true, ["trailers"] = true, ["transfer-encoding"] = true, ["upgrade"] = true, ["content-length"] = true, -- Not strictly hop-by-hop, but Nginx will deal -- with this (may send chunked for example). } -- Reimplemented coroutine.wrap, returning "nil, err" if the coroutine cannot -- be resumed. This protects user code from inifite loops when doing things like -- repeat -- local chunk, err = res.body_reader() -- if chunk then -- <-- This could be a string msg in the core wrap function. -- ... -- end -- until not chunk local co_wrap = function(func) local co = co_create(func) if not co then return nil, "could not create coroutine" else return function(...) if co_status(co) == "suspended" then return select(2, co_resume(co, ...)) else return nil, "can't resume a " .. co_status(co) .. " coroutine" end end end end -- Returns a new table, recursively copied from the one given. -- -- @param table table to be copied -- @return table local function tbl_copy(orig) local orig_type = type(orig) local copy if orig_type == "table" then copy = {} for orig_key, orig_value in next, orig, nil do copy[tbl_copy(orig_key)] = tbl_copy(orig_value) end else -- number, string, boolean, etc copy = orig end return copy end local _M = { _VERSION = '0.12', } _M._USER_AGENT = "lua-resty-http/" .. _M._VERSION .. " (Lua) ngx_lua/" .. ngx.config.ngx_lua_version local mt = { __index = _M } local HTTP = { [1.0] = " HTTP/1.0\r\n", [1.1] = " HTTP/1.1\r\n", } local DEFAULT_PARAMS = { method = "GET", path = "/", version = 1.1, } function _M.new(self) local sock, err = ngx_socket_tcp() if not sock then return nil, err end return setmetatable({ sock = sock, keepalive = true }, mt) end function _M.set_timeout(self, timeout) local sock = self.sock if not sock then return nil, "not initialized" end return sock:settimeout(timeout) end function _M.set_timeouts(self, connect_timeout, send_timeout, read_timeout) local sock = self.sock if not sock then return nil, "not initialized" end return sock:settimeouts(connect_timeout, send_timeout, read_timeout) end function _M.ssl_handshake(self, ...) local sock = self.sock if not sock then return nil, "not initialized" end self.ssl = true return sock:sslhandshake(...) end function _M.connect(self, ...) local sock = self.sock if not sock then return nil, "not initialized" end self.host = select(1, ...) self.port = select(2, ...) -- If port is not a number, this is likely a unix domain socket connection. if type(self.port) ~= "number" then self.port = nil end self.keepalive = true return sock:connect(...) end function _M.set_keepalive(self, ...) local sock = self.sock if not sock then return nil, "not initialized" end if self.keepalive == true then return sock:setkeepalive(...) else -- The server said we must close the connection, so we cannot setkeepalive. -- If close() succeeds we return 2 instead of 1, to differentiate between -- a normal setkeepalive() failure and an intentional close(). local res, err = sock:close() if res then return 2, "connection must be closed" else return res, err end end end function _M.get_reused_times(self) local sock = self.sock if not sock then return nil, "not initialized" end return sock:getreusedtimes() end function _M.close(self) local sock = self.sock if not sock then return nil, "not initialized" end return sock:close() end local function _should_receive_body(method, code) if method == "HEAD" then return nil end if code == 204 or code == 304 then return nil end if code >= 100 and code < 200 then return nil end return true end function _M.parse_uri(self, uri, query_in_path) if query_in_path == nil then query_in_path = true end local m, err = ngx_re_match(uri, [[^(?:(http[s]?):)?//([^:/\?]+)(?::(\d+))?([^\?]*)\??(.*)]], "jo") if not m then if err then return nil, "failed to match the uri: " .. uri .. ", " .. err end return nil, "bad uri: " .. uri else -- If the URI is schemaless (i.e. //example.com) try to use our current -- request scheme. if not m[1] then local scheme = ngx_var.scheme if scheme == "http" or scheme == "https" then m[1] = scheme else return nil, "schemaless URIs require a request context: " .. uri end end if m[3] then m[3] = tonumber(m[3]) else if m[1] == "https" then m[3] = 443 else m[3] = 80 end end if not m[4] or "" == m[4] then m[4] = "/" end if query_in_path and m[5] and m[5] ~= "" then m[4] = m[4] .. "?" .. m[5] m[5] = nil end return m, nil end end local function _format_request(params) local version = params.version local headers = params.headers or {} local query = params.query or "" if type(query) == "table" then query = "?" .. ngx_encode_args(query) elseif query ~= "" and str_sub(query, 1, 1) ~= "?" then query = "?" .. query end -- Initialize request local req = { str_upper(params.method), " ", params.path, query, HTTP[version], -- Pre-allocate slots for minimum headers and carriage return. true, true, true, } local c = 6 -- req table index it's faster to do this inline vs table.insert -- Append headers for key, values in pairs(headers) do if type(values) ~= "table" then values = {values} end key = tostring(key) for _, value in pairs(values) do req[c] = key .. ": " .. tostring(value) .. "\r\n" c = c + 1 end end -- Close headers req[c] = "\r\n" return tbl_concat(req) end local function _receive_status(sock) local line, err = sock:receive("*l") if not line then return nil, nil, nil, err end return tonumber(str_sub(line, 10, 12)), tonumber(str_sub(line, 6, 8)), str_sub(line, 14) end local function _receive_headers(sock) local headers = http_headers.new() repeat local line, err = sock:receive("*l") if not line then return nil, err end local m, err = ngx_re_match(line, "([^:\\s]+):\\s*(.+)", "jo") if not m then break end local key = m[1] local val = m[2] if headers[key] then if type(headers[key]) ~= "table" then headers[key] = { headers[key] } end tbl_insert(headers[key], tostring(val)) else headers[key] = tostring(val) end until ngx_re_find(line, "^\\s*$", "jo") return headers, nil end local function _chunked_body_reader(sock, default_chunk_size) return co_wrap(function(max_chunk_size) local remaining = 0 local length max_chunk_size = max_chunk_size or default_chunk_size repeat -- If we still have data on this chunk if max_chunk_size and remaining > 0 then if remaining > max_chunk_size then -- Consume up to max_chunk_size length = max_chunk_size remaining = remaining - max_chunk_size else -- Consume all remaining length = remaining remaining = 0 end else -- This is a fresh chunk -- Receive the chunk size local str, err = sock:receive("*l") if not str then co_yield(nil, err) end length = tonumber(str, 16) if not length then co_yield(nil, "unable to read chunksize") end if max_chunk_size and length > max_chunk_size then -- Consume up to max_chunk_size remaining = length - max_chunk_size length = max_chunk_size end end if length > 0 then local str, err = sock:receive(length) if not str then co_yield(nil, err) end max_chunk_size = co_yield(str) or default_chunk_size -- If we're finished with this chunk, read the carriage return. if remaining == 0 then sock:receive(2) -- read \r\n end else -- Read the last (zero length) chunk's carriage return sock:receive(2) -- read \r\n end until length == 0 end) end local function _body_reader(sock, content_length, default_chunk_size) return co_wrap(function(max_chunk_size) max_chunk_size = max_chunk_size or default_chunk_size if not content_length and max_chunk_size then -- We have no length, but wish to stream. -- HTTP 1.0 with no length will close connection, so read chunks to the end. repeat local str, err, partial = sock:receive(max_chunk_size) if not str and err == "closed" then co_yield(partial, err) end max_chunk_size = tonumber(co_yield(str) or default_chunk_size) if max_chunk_size and max_chunk_size < 0 then max_chunk_size = nil end if not max_chunk_size then ngx_log(ngx_ERR, "Buffer size not specified, bailing") break end until not str elseif not content_length then -- We have no length but don't wish to stream. -- HTTP 1.0 with no length will close connection, so read to the end. co_yield(sock:receive("*a")) elseif not max_chunk_size then -- We have a length and potentially keep-alive, but want everything. co_yield(sock:receive(content_length)) else -- We have a length and potentially a keep-alive, and wish to stream -- the response. local received = 0 repeat local length = max_chunk_size if received + length > content_length then length = content_length - received end if length > 0 then local str, err = sock:receive(length) if not str then co_yield(nil, err) end received = received + length max_chunk_size = tonumber(co_yield(str) or default_chunk_size) if max_chunk_size and max_chunk_size < 0 then max_chunk_size = nil end if not max_chunk_size then ngx_log(ngx_ERR, "Buffer size not specified, bailing") break end end until length == 0 end end) end local function _no_body_reader() return nil end local function _read_body(res) local reader = res.body_reader if not reader then -- Most likely HEAD or 304 etc. return nil, "no body to be read" end local chunks = {} local c = 1 local chunk, err repeat chunk, err = reader() if err then return nil, err, tbl_concat(chunks) -- Return any data so far. end if chunk then chunks[c] = chunk c = c + 1 end until not chunk return tbl_concat(chunks) end local function _trailer_reader(sock) return co_wrap(function() co_yield(_receive_headers(sock)) end) end local function _read_trailers(res) local reader = res.trailer_reader if not reader then return nil, "no trailers" end local trailers = reader() setmetatable(res.headers, { __index = trailers }) end local function _send_body(sock, body) if type(body) == 'function' then repeat local chunk, err, partial = body() if chunk then local ok, err = sock:send(chunk) if not ok then return nil, err end elseif err ~= nil then return nil, err, partial end until chunk == nil elseif body ~= nil then local bytes, err = sock:send(body) if not bytes then return nil, err end end return true, nil end local function _handle_continue(sock, body) local status, version, reason, err = _receive_status(sock) if not status then return nil, nil, err end -- Only send body if we receive a 100 Continue if status == 100 then local ok, err = sock:receive("*l") -- Read carriage return if not ok then return nil, nil, err end _send_body(sock, body) end return status, version, err end function _M.send_request(self, params) -- Apply defaults setmetatable(params, { __index = DEFAULT_PARAMS }) local sock = self.sock local body = params.body local headers = http_headers.new() local params_headers = params.headers if params_headers then -- We assign one by one so that the metatable can handle case insensitivity -- for us. You can blame the spec for this inefficiency. for k,v in pairs(params_headers) do headers[k] = v end end -- Ensure minimal headers are set if type(body) == 'string' and not headers["Content-Length"] then headers["Content-Length"] = #body end if not headers["Host"] then if (str_sub(self.host, 1, 5) == "unix:") then return nil, "Unable to generate a useful Host header for a unix domain socket. Please provide one." end -- If we have a port (i.e. not connected to a unix domain socket), and this -- port is non-standard, append it to the Host heaer. if self.port then if self.ssl and self.port ~= 443 then headers["Host"] = self.host .. ":" .. self.port elseif not self.ssl and self.port ~= 80 then headers["Host"] = self.host .. ":" .. self.port else headers["Host"] = self.host end else headers["Host"] = self.host end end if not headers["User-Agent"] then headers["User-Agent"] = _M._USER_AGENT end if params.version == 1.0 and not headers["Connection"] then headers["Connection"] = "Keep-Alive" end params.headers = headers -- Format and send request local req = _format_request(params) ngx_log(ngx_DEBUG, "\n", req) local bytes, err = sock:send(req) if not bytes then return nil, err end -- Send the request body, unless we expect: continue, in which case -- we handle this as part of reading the response. if headers["Expect"] ~= "100-continue" then local ok, err, partial = _send_body(sock, body) if not ok then return nil, err, partial end end return true end function _M.read_response(self, params) local sock = self.sock local status, version, reason, err -- If we expect: continue, we need to handle this, sending the body if allowed. -- If we don't get 100 back, then status is the actual status. if params.headers["Expect"] == "100-continue" then local _status, _version, _err = _handle_continue(sock, params.body) if not _status then return nil, _err elseif _status ~= 100 then status, version, err = _status, _version, _err end end -- Just read the status as normal. if not status then status, version, reason, err = _receive_status(sock) if not status then return nil, err end end local res_headers, err = _receive_headers(sock) if not res_headers then return nil, err end -- keepalive is true by default. Determine if this is correct or not. local ok, connection = pcall(str_lower, res_headers["Connection"]) if ok then if (version == 1.1 and connection == "close") or (version == 1.0 and connection ~= "keep-alive") then self.keepalive = false end else -- no connection header if version == 1.0 then self.keepalive = false end end local body_reader = _no_body_reader local trailer_reader, err local has_body = false -- Receive the body_reader if _should_receive_body(params.method, status) then local ok, encoding = pcall(str_lower, res_headers["Transfer-Encoding"]) if ok and version == 1.1 and encoding == "chunked" then body_reader, err = _chunked_body_reader(sock) has_body = true else local ok, length = pcall(tonumber, res_headers["Content-Length"]) if ok then body_reader, err = _body_reader(sock, length) has_body = true end end end if res_headers["Trailer"] then trailer_reader, err = _trailer_reader(sock) end if err then return nil, err else return { status = status, reason = reason, headers = res_headers, has_body = has_body, body_reader = body_reader, read_body = _read_body, trailer_reader = trailer_reader, read_trailers = _read_trailers, } end end function _M.request(self, params) params = tbl_copy(params) -- Take by value local res, err = self:send_request(params) if not res then return res, err else return self:read_response(params) end end function _M.request_pipeline(self, requests) requests = tbl_copy(requests) -- Take by value for _, params in ipairs(requests) do if params.headers and params.headers["Expect"] == "100-continue" then return nil, "Cannot pipeline request specifying Expect: 100-continue" end local res, err = self:send_request(params) if not res then return res, err end end local responses = {} for i, params in ipairs(requests) do responses[i] = setmetatable({ params = params, response_read = false, }, { -- Read each actual response lazily, at the point the user tries -- to access any of the fields. __index = function(t, k) local res, err if t.response_read == false then res, err = _M.read_response(self, t.params) t.response_read = true if not res then ngx_log(ngx_ERR, err) else for rk, rv in pairs(res) do t[rk] = rv end end end return rawget(t, k) end, }) end return responses end function _M.request_uri(self, uri, params) params = tbl_copy(params or {}) -- Take by value local parsed_uri, err = self:parse_uri(uri, false) if not parsed_uri then return nil, err end local scheme, host, port, path, query = unpack(parsed_uri) if not params.path then params.path = path end if not params.query then params.query = query end -- See if we should use a proxy to make this request local proxy_uri = self:get_proxy_uri(scheme, host) -- Make the connection either through the proxy or directly -- to the remote host local c, err if proxy_uri then c, err = self:connect_proxy(proxy_uri, scheme, host, port) else c, err = self:connect(host, port) end if not c then return nil, err end if proxy_uri then if scheme == "http" then -- When a proxy is used, the target URI must be in absolute-form -- (RFC 7230, Section 5.3.2.). That is, it must be an absolute URI -- to the remote resource with the scheme, host and an optional port -- in place. -- -- Since _format_request() constructs the request line by concatenating -- params.path and params.query together, we need to modify the path -- to also include the scheme, host and port so that the final form -- in conformant to RFC 7230. if port == 80 then params.path = scheme .. "://" .. host .. path else params.path = scheme .. "://" .. host .. ":" .. port .. path end end if scheme == "https" then -- don't keep this connection alive as the next request could target -- any host and re-using the proxy tunnel for that is not possible self.keepalive = false end -- self:connect_uri() set the host and port to point to the proxy server. As -- the connection to the proxy has been established, set the host and port -- to point to the actual remote endpoint at the other end of the tunnel to -- ensure the correct Host header added to the requests. self.host = host self.port = port end if scheme == "https" then local verify = true if params.ssl_verify == false then verify = false end local ok, err = self:ssl_handshake(nil, host, verify) if not ok then return nil, err end end local res, err = self:request(params) if not res then return nil, err end local body, err = res:read_body() if not body then return nil, err end res.body = body local ok, err = self:set_keepalive() if not ok then ngx_log(ngx_ERR, err) end return res, nil end function _M.get_client_body_reader(self, chunksize, sock) chunksize = chunksize or 65536 if not sock then local ok, err ok, sock, err = pcall(ngx_req_socket) if not ok then return nil, sock -- pcall err end if not sock then if err == "no body" then return nil else return nil, err end end end local headers = ngx_req_get_headers() local length = headers.content_length local encoding = headers.transfer_encoding if length then return _body_reader(sock, tonumber(length), chunksize) elseif encoding and str_lower(encoding) == 'chunked' then -- Not yet supported by ngx_lua but should just work... return _chunked_body_reader(sock, chunksize) else return nil end end function _M.proxy_request(self, chunksize) return self:request{ method = ngx_req_get_method(), path = ngx_re_gsub(ngx_var.uri, "\\s", "%20", "jo") .. ngx_var.is_args .. (ngx_var.query_string or ""), body = self:get_client_body_reader(chunksize), headers = ngx_req_get_headers(), } end function _M.proxy_response(self, response, chunksize) if not response then ngx_log(ngx_ERR, "no response provided") return end ngx.status = response.status -- Filter out hop-by-hop headeres for k,v in pairs(response.headers) do if not HOP_BY_HOP_HEADERS[str_lower(k)] then ngx_header[k] = v end end local reader = response.body_reader repeat local chunk, err = reader(chunksize) if err then ngx_log(ngx_ERR, err) break end if chunk then local res, err = ngx_print(chunk) if not res then ngx_log(ngx_ERR, err) break end end until not chunk end function _M.set_proxy_options(self, opts) self.proxy_opts = tbl_copy(opts) -- Take by value end function _M.get_proxy_uri(self, scheme, host) if not self.proxy_opts then return nil end -- Check if the no_proxy option matches this host. Implementation adapted -- from lua-http library (https://github.com/daurnimator/lua-http) if self.proxy_opts.no_proxy then if self.proxy_opts.no_proxy == "*" then -- all hosts are excluded return nil end local no_proxy_set = {} -- wget allows domains in no_proxy list to be prefixed by "." -- e.g. no_proxy=.mit.edu for host_suffix in ngx_re_gmatch(self.proxy_opts.no_proxy, "\\.?([^,]+)") do no_proxy_set[host_suffix[1]] = true end -- From curl docs: -- matched as either a domain which contains the hostname, or the -- hostname itself. For example local.com would match local.com, -- local.com:80, and www.local.com, but not www.notlocal.com. -- -- Therefore, we keep stripping subdomains from the host, compare -- them to the ones in the no_proxy list and continue until we find -- a match or until there's only the TLD left repeat if no_proxy_set[host] then return nil end -- Strip the next level from the domain and check if that one -- is on the list host = ngx_re_sub(host, "^[^.]+\\.", "") until not ngx_re_find(host, "\\.") end if scheme == "http" and self.proxy_opts.http_proxy then return self.proxy_opts.http_proxy end if scheme == "https" and self.proxy_opts.https_proxy then return self.proxy_opts.https_proxy end return nil end function _M.connect_proxy(self, proxy_uri, scheme, host, port) -- Parse the provided proxy URI local parsed_proxy_uri, err = self:parse_uri(proxy_uri, false) if not parsed_proxy_uri then return nil, err end -- Check that the scheme is http (https is not supported for -- connections between the client and the proxy) local proxy_scheme = parsed_proxy_uri[1] if proxy_scheme ~= "http" then return nil, "protocol " .. proxy_scheme .. " not supported for proxy connections" end -- Make the connection to the given proxy local proxy_host, proxy_port = parsed_proxy_uri[2], parsed_proxy_uri[3] local c, err = self:connect(proxy_host, proxy_port) if not c then return nil, err end if scheme == "https" then -- Make a CONNECT request to create a tunnel to the destination through -- the proxy. The request-target and the Host header must be in the -- authority-form of RFC 7230 Section 5.3.3. See also RFC 7231 Section -- 4.3.6 for more details about the CONNECT request local destination = host .. ":" .. port local res, err = self:request({ method = "CONNECT", path = destination, headers = { ["Host"] = destination } }) if not res then return nil, err end if res.status < 200 or res.status > 299 then return nil, "failed to establish a tunnel through a proxy: " .. res.status end end return c, nil end return _M
Simpan
Batal
Isi Zip:
Unzip
Create
Buat Folder
Buat File
Terminal / Execute
Run
Chmod Bulk
All File
All Folder
All File dan Folder
Apply