Mercurial > prosody-modules
comparison mod_auth_external/mod_auth_external.lua @ 1159:c56a1d449cad
mod_auth_external: Add non-blocking mode (requires trunk, libevent and lpty 1.0.1). Our first complete non-blocking auth module!
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Tue, 13 Aug 2013 23:37:31 +0100 |
| parents | ae1767b54964 |
| children | 05685fd07395 |
comparison
equal
deleted
inserted
replaced
| 1158:ae1767b54964 | 1159:c56a1d449cad |
|---|---|
| 18 local command = module:get_option_string("external_auth_command", ""); | 18 local command = module:get_option_string("external_auth_command", ""); |
| 19 local read_timeout = module:get_option_number("external_auth_timeout", 5); | 19 local read_timeout = module:get_option_number("external_auth_timeout", 5); |
| 20 assert(not host:find(":"), "Invalid hostname"); | 20 assert(not host:find(":"), "Invalid hostname"); |
| 21 local usermanager = require "core.usermanager"; | 21 local usermanager = require "core.usermanager"; |
| 22 local new_sasl = require "util.sasl".new; | 22 local new_sasl = require "util.sasl".new; |
| 23 local server = require "net.server"; | |
| 24 local have_async, async = pcall(require, "util.async"); | |
| 23 | 25 |
| 24 local pty = lpty.new({ throw_errors = false, no_local_echo = true, use_path = false }); | 26 local blocking = module:get_option_boolean("external_auth_blocking", not(have_async and server.event and lpty.getfd)); |
| 27 | |
| 28 if not blocking then | |
| 29 log("debug", "External auth in non-blocking mode, yay!") | |
| 30 waiter, guard = async.waiter, async.guarder(); | |
| 31 end | |
| 32 | |
| 33 local ptys = { lpty.new({ throw_errors = false, no_local_echo = true, use_path = false }) }; | |
| 25 | 34 |
| 26 function send_query(text) | 35 function send_query(text) |
| 36 local pty = ptys[1]; | |
| 37 | |
| 38 local finished_with_pty | |
| 39 if not blocking then | |
| 40 finished_with_pty = guard(pty); -- Prevent others from crossing this line while we're busy | |
| 41 end | |
| 27 if not pty:hasproc() then | 42 if not pty:hasproc() then |
| 28 local status, ret = pty:exitstatus(); | 43 local status, ret = pty:exitstatus(); |
| 29 if status and (status ~= "exit" or ret ~= 0) then | 44 if status and (status ~= "exit" or ret ~= 0) then |
| 30 log("warn", "Auth process exited unexpectedly with %s %d, restarting", status, ret or 0); | 45 log("warn", "Auth process exited unexpectedly with %s %d, restarting", status, ret or 0); |
| 31 return nil; | 46 return nil; |
| 37 end | 52 end |
| 38 log("debug", "Started auth process"); | 53 log("debug", "Started auth process"); |
| 39 end | 54 end |
| 40 | 55 |
| 41 pty:send(text); | 56 pty:send(text); |
| 42 return pty:read(read_timeout); | 57 if blocking then |
| 58 return pty:read(read_timeout); | |
| 59 else | |
| 60 local response; | |
| 61 local wait, done = waiter(); | |
| 62 server.addevent(pty:getfd(), server.event.EV_READ, function () | |
| 63 response = pty:read(); | |
| 64 done(); | |
| 65 return -1; | |
| 66 end); | |
| 67 wait(); | |
| 68 finished_with_pty(); | |
| 69 return response; | |
| 70 end | |
| 43 end | 71 end |
| 44 | 72 |
| 45 function do_query(kind, username, password) | 73 function do_query(kind, username, password) |
| 46 if not username then return nil, "not-acceptable"; end | 74 if not username then return nil, "not-acceptable"; end |
| 47 | 75 |
