Software /
code /
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 |
parent | 1158:ae1767b54964 |
child | 1160: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 |