local type = type local error = error local pcall = pcall local getmetatable = getmetatable local ffi = require "ffi" do --if not pcall(ffi.typeof, "tmp_ngx_http_lua_socket_tcp_upstream_t") then -- --end -- based on nginx 1.27.1 -- @see ngx_connection_t, ngx_peer_connection_t, ngx_http_lua_socket_tcp_upstream_t ffi.cdef [[ typedef struct { intptr_t prefix[3]; int fd; char rest[0]; } tmp_ngx_connection_t; typedef struct { tmp_ngx_connection_t *connection; char rest[0]; } tmp_ngx_peer_connection_t; typedef struct { intptr_t prefix[9]; tmp_ngx_peer_connection_t peer; char rest[0]; } tmp_ngx_http_lua_socket_tcp_upstream_t; ]] end local ffi_cast = ffi.cast local C = ffi.C local lua_registry = debug.getregistry() -- C types local ngx_http_lua_socket_tcp_upstream_pct = ffi.typeof("tmp_ngx_http_lua_socket_tcp_upstream_t*") -- constants local SOCKET_CTX_INDEX = 1 local _M = { _VERSION = '0.0.1' } -- @see lua-resty-core/lib/resty/core/socket.lua local function get_tcp_socket(cosocket) local tcp_socket = cosocket[SOCKET_CTX_INDEX] if not tcp_socket then error("socket is never created nor connected") end return tcp_socket end local function get_socket_fd(sock) local ud = get_tcp_socket(sock) local cdata_ref = ffi_cast(ngx_http_lua_socket_tcp_upstream_pct, ud) return cdata_ref.peer.connection.fd end _M.get_fd = function(cosock) -- @note this may not nes if type(cosock) ~= "table" then return nil, "valid cosocket object expected" end return pcall(get_socket_fd, cosock) end _M.verify_cosocket = function(cosock) if type(cosock) ~= "table" or getmetatable(cosock) ~= lua_registry.__tcp_cosocket_mt then return nil, "valid cosocket object expected" end return cosock end return _M