Software /
code /
prosody-modules
Changeset
6202:6d5a19bdd718
mod_openid, mod_json_streams: Remove modules depending on obsolete net.httpserver API
These have not been updated for a long time and do not work with Prosody
versions from recent years, which is a good indication they are not being
used.
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Fri, 14 Feb 2025 14:59:14 +0000 |
parents | 6201:274fb65904a7 |
children | 6203:131b8bfbefb4 |
files | mod_json_streams/README.md mod_json_streams/mod_json_streams.lua mod_json_streams/strophe.jsonstreams.js mod_openid/README.md mod_openid/mod_openid.lua |
diffstat | 5 files changed, 0 insertions(+), 866 deletions(-) [+] |
line wrap: on
line diff
--- a/mod_json_streams/README.md Thu Feb 13 12:20:46 2025 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ ---- -labels: -- 'Stage-Beta' -summary: JSON Encodings for XMPP -... - -Introduction -============ - -This plugin encodes XMPP as JSON. This is an implementation of -[XEP-0295: JSON Encodings for -XMPP](http://xmpp.org/extensions/xep-0295.html). - -Simply loading this module makes Prosody accept JSON on C2S streams -(legacy XML clients are still supported). - -For BOSH, it requires mod\_bosh be loaded, and JSON should be directed -at the `/jsonstreams` HTTP path. - -JSON for S2S isn't supported due to the lack of a discovery mechanism, -so we have left that disabled to stay compatible with legacy XML -servers. - -Configuration -============= - -Just add `"json_streams"` in your config's global `modules_enabled` -list, for example: - - modules_enabled = { - ... - "json_streams"; - } - -Strophe.js plugin -================= - -We also developed a [JSON streams -plugin](http://prosody-modules.googlecode.com/hg/mod_json_streams/strophe.jsonstreams.js) -for the popular [strophe.js](http://code.stanziq.com/strophe) library. - -Just include it like this after including the strophe library, and your -strophe-based client will be speaking JSON: - - <script type="text/javascript" src="strophe.jsonstreams.js"></script> - -Be sure to set the HTTP path to `/jsonstreams`. No other changes are -required. - -Compatibility -============= - - ------- ------- - 0.8 Works - trunk Works - ------- ------- - -Quirks -====== - -- This plugin does not currently work with Prosody's [port - multiplexing](http://prosody.im/doc/port_multiplexing) feature
--- a/mod_json_streams/mod_json_streams.lua Thu Feb 13 12:20:46 2025 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,154 +0,0 @@ --- --- XEP-0295: JSON Encodings for XMPP --- - -module.host = "*" - -local httpserver = require "net.httpserver"; -local filters = require "util.filters" -local json = require "util.json" - -local json_escapes = { - ["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b", ["\f"] = "\\f", - ["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t"}; - -local s_char = string.char; -for i=0,31 do - local ch = s_char(i); - if not json_escapes[ch] then json_escapes[ch] = ("\\u%.4X"):format(i); end -end - -local state_out = 0; -local state_key_before = 1; -local state_key_in = 2; -local state_key_escape = 3; -local state_key_after = 4; -local state_val_before = 5; -local state_val_in = 6; -local state_val_escape = 7; -local state_val_after = 8; - -local whitespace = { [" "] = true, ["\n"] = true, ["\r"] = true, ["\t"] = true }; -function json_decoder() - local state = state_out; - local quote; - local output = ""; - local buffer = ""; - return function(input) - for ch in input:gmatch(".") do - module:log("debug", "%s | %d", ch, state) - local final = false; - if state == state_out then - if whitespace[ch] then - elseif ch ~= "{" then return nil, "{ expected"; - else state = state_key_before end - elseif state == state_key_before then - if whitespace[ch] then - elseif ch ~= "'" and ch ~= "\"" then return nil, "\" expected"; - else quote = ch; state = state_key_in; end - elseif state == state_key_in then - if ch == quote then state = state_key_after; - elseif ch ~= "s" then return nil, "invalid key, 's' expected"; -- only s as key allowed - else end -- ignore key - elseif state == state_key_after then - if whitespace[ch] then - elseif ch ~= ":" then return nil, ": expected"; - else state = state_val_before; end - elseif state == state_val_before then - if whitespace[ch] then - elseif ch ~= "'" and ch ~= "\"" then return nil, "\" expected"; - else quote = ch; state = state_val_in; end - elseif state == state_val_in then - if ch == quote then state = state_val_after; - elseif ch == "\\" then state = state_val_escape; - else end - elseif state == state_val_after then - if whitespace[ch] then - elseif ch ~= "}" then return nil, "} expected"; - else state = state_out; - final = true; - end - elseif state == state_val_escape then - state = state_val_in; - else - module:log("error", "Unhandled state: "..state); - return nil, "Unhandled state in parser" - end - buffer = buffer..ch; - if final then - module:log("debug", "%s", buffer) - local tmp; - pcall(function() tmp = json.decode(buffer); end); - if not tmp then return nil, "Invalid JSON"; end - output, buffer = output..tmp.s, ""; - end - end - local _ = output; output = ""; - return _; - end; -end - -function filter_hook(session) - local determined = false; - local is_json = false; - local function in_filter(t) - if not determined then - is_json = (t:sub(1,1) == "{") and json_decoder(); - determined = true; - end - if is_json then - local s, err = is_json(t); - if not err then return s; end - session:close("not-well-formed"); - return; - end - return t; - end - local function out_filter(t) - if is_json then - return '{"s":"' .. t:gsub(".", json_escapes) .. '"}'; -- encode - end - return t; - end - filters.add_filter(session, "bytes/in", in_filter, 100); - filters.add_filter(session, "bytes/out", out_filter, 100); -end - -function module.load() - filters.add_filter_hook(filter_hook); -end -function module.unload() - filters.remove_filter_hook(filter_hook); -end - -function encode(data) - if type(data) == "string" then - data = json.encode({ s = data }); - elseif type(data) == "table" and data.body then - data.body = json.encode({ s = data.body }); - data.headers["Content-Type"] = "application/json"; - end - return data; -end -function handle_request(method, body, request) - local mod_bosh = modulemanager.get_module("*", "bosh") - if mod_bosh then - if body and method == "POST" then - pcall(function() body = json.decode(body).s; end); - end - local _send = request.send; - function request:send(data) return _send(self, encode(data)); end - return encode(mod_bosh.handle_request(method, body, request)); - end - return "<html><body>mod_bosh not loaded</body></html>"; -end - -local function setup() - local ports = module:get_option("jsonstreams_ports") or { 5280 }; - httpserver.new_from_config(ports, handle_request, { base = "jsonstreams" }); -end -if prosody.start_time then -- already started - setup(); -else - prosody.events.add_handler("server-started", setup); -end
--- a/mod_json_streams/strophe.jsonstreams.js Thu Feb 13 12:20:46 2025 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ - -/* jsonstreams plugin -** -** This plugin upgrades Strophe to support XEP-0295: JSON Encodings for XMPP -** -*/ - -Strophe.addConnectionPlugin('jsonstreams', { - init: function (conn) { - - var parseXMLString = function(xmlStr) { - var xmlDoc = null; - if (window.ActiveXObject) { - xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); - xmlDoc.async=false; - xmlDoc.loadXML(xmlStr); - } else { - var parser = new DOMParser(); - xmlDoc = parser.parseFromString(xmlStr, "text/xml"); - } - return xmlDoc; - } - - // replace Strophe.Request._newXHR with new jsonstreams version - // if JSON is detected - if (window.JSON) { - var _newXHR = Strophe.Request.prototype._newXHR; - Strophe.Request.prototype._newXHR = function () { - var _xhr = _newXHR.apply(this, arguments); - var xhr = { - readyState: 0, - responseText: null, - responseXML: null, - status: null, - open: function(a, b, c) { return _xhr.open(a, b, c) }, - abort: function() { _xhr.abort(); }, - send: function(data) { - data = JSON.stringify({"s":data}); - return _xhr.send(data); - } - }; - var req = this; - xhr.onreadystatechange = this.func.bind(null, this); - _xhr.onreadystatechange = function() { - xhr.readyState = _xhr.readyState; - if (xhr.readyState != 4) { - xhr.status = 0; - xhr.responseText = ""; - xhr.responseXML = null; - } else { - xhr.status = _xhr.status; - xhr.responseText = _xhr.responseText; - xhr.responseXML = _xhr.responseXML; - if (_xhr.responseText && !(_xhr.responseXML - && _xhr.responseXML.documentElement - && _xhr.responseXML.documentElement.tagName != "parsererror")) { - var data = JSON.parse(_xhr.responseText); - if (data && data.s) { - xhr.responseText = data.s; - xhr.responseXML = parseXMLString(data.s); - } - } - } - if ("function" == typeof xhr.onreadystatechange) { xhr.onreadystatechange(req); } - } - return xhr; - }; - } else { - Strophe.error("jsonstreams plugin loaded, but JSON not found." + - " Falling back to native XHR implementation."); - } - } -});
--- a/mod_openid/README.md Thu Feb 13 12:20:46 2025 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ ---- -labels: -- 'Stage-Alpha' -summary: Enables Prosody to act as an OpenID provider -... - -Introduction -============ - -[OpenID](http://openid.net/) is an decentralized authentication -mechanism for the Web. mod\_openid turns Prosody into an OpenID -*provider*, allowing users to use their Prosody credentials to -authenticate with various third party websites. - -Caveats -======= - -mod\_openid can best be described as a **proof-of-concept**, it has -known deficiencies and should **not** be used in the wild as a -legitimate OpenID provider. mod\_openid was developed using the Prosody -0.4.x series, it has not been tested with the 0.5.x or later series. - -Details -======= - -OpenID works on the basis of a user proving to a third-party they wish -to authenticate with, an OpenID *relaying party*, that they have claim -or ownership over a URL, known as an OpenID *identifier*. mod\_openid -uses Prosody's built in HTTP server to provide every user with an OpenID -identifier of the form `http://host.domain.tld[:port]/openid/user`, -which would be the OpenID identifier of the user with a Jabber ID of -`user@host.domain.tld`. - -Usage -===== - -Simply add "mod\_openid" to your modules\_enabled list. You may then use -the OpenID identifier form as described above as your OpenID identifier. -The port Prosody's HTTP server will listen on is currently set as 5280, -meaning the full OpenID identifier of the user `romeo@montague.lit` -would be `http://montague.lit:5280/openid/romeo`. - -Configuration -============= - -mod\_openid has no configuration options as of this time. - -TODO -==== - -The following is a list of the pending tasks which would have to be done -to make mod\_openid fully featured. They are generally ranked in order -of most importance with an estimated degree of difficulty. - -1. Support Prosody 0.6.x series (**Medium**) -2. Refactor code (**Medium**) - - The code is pretty messy at the moment, it should be refactored - to be more easily understood. - -3. Disable use of "user@domain" OpenID identifier form (*Easy*) - - This is a vestigial feature from the early design, allowing - explicit specification of the JID. However the JID can be - inferred from the simpler OpenID identifier form. - -4. Use a cryptographically secure Pseudo Random Number Generator (PRNG) - (**Medium**) - - This would likely be accomplished using luacrypto which provides - a Lua binding to the OpenSSL PRNG. - -5. Make sure OpenID key-value pairs get signed in the right order - (***Hard***) - - It is important that the OpenID key-value responses be signed in - the proper order so that the signature can be properly verified - by the receiving party. This may be complicated by the fact that - the iterative ordering of keys in a Lua table is not guaranteed - for non-integer keys. - -6. Do an actual match on the OpenID realm (**Medium**) - - The code currently always returns true for matches against an - OpenID realm, posing a security risk. - -7. Don't use plain text authentication over HTTP (***Hard***) - - This would require some Javascript to perform a digest. - -8. Return meaningful error responses (**Medium**) - - Most error responses are an HTTP 404 File Not Found, obviously - something more meaningful could be returned. - -9. Enable Association (***Hard***) - - Association is a feature of the OpenID specification which - reduces the number of round-trips needed to perform - authentication. - -10. Support HTTPS (**Medium**) - - With option to only allow authentication through HTTPS - -11. Enable OpenID 1.1 compatibility (**Medium**) - - mod\_openid is designed from the OpenID 2.0 specification, which - has an OpenID 1.1 compatibility mode. - -12. Check specification compliance (**Medium**) - - Walk through the code and make sure it complies with the OpenID - specification. Comment code as necessary with the relevant - sections in the specification. - -Once all these steps are done, mod\_openid could be considered to have -reached "beta" status and ready to real world use. The following are -features that would be nice to have in a stable release: - -1. Allow users to always trust realms (***Hard***) -2. Allow users to remain logged in with a cookie (***Hard***) -3. Enable simple registration using a user's vCard (**Medium**) -4. More useful user identity page (***Hard***) - - Allow users to alter what realms they trust and what simple - registration information gets sent to relaying parties by - default. - -5. OpenID Bot (***Hard***) - - Offers all functionality of the user identity page management - -6. Better designed pages (*Easy*) - - Use semantic XHTML and CSS to allow for custom styling. - - Use the Prosody favicon. - -Useful Links -============ - -- [OpenID Specifications](http://openid.net/developers/specs/) -- [OpenID on Wikipedia](http://en.wikipedia.org/wiki/OpenID)
--- a/mod_openid/mod_openid.lua Thu Feb 13 12:20:46 2025 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,448 +0,0 @@ -local usermanager = require "core.usermanager" -local httpserver = require "net.httpserver" -local jidutil = require "util.jid" -local hmac = require "hmac" - -local base64 = require "util.encodings".base64 - -local humane = require "util.serialization".serialize - --- Configuration -local base = "openid" -local openidns = "http://specs.openid.net/auth/2.0" -- [#4.1.2] -local response_404 = { status = "404 Not Found", body = "<h1>Page Not Found</h1>Sorry, we couldn't find what you were looking for :(" }; - -local associations = {} - -local function genkey(length) - -- FIXME not cryptographically secure - str = {} - - for i = 1,length do - local rand = math.random(33, 126) - table.insert(str, string.char(rand)) - end - - return table.concat(str) -end - -local function tokvstring(dict) - -- key-value encoding for a dictionary [#4.1.3] - local str = "" - - for k,v in pairs(dict) do - str = str..k..":"..v.."\n" - end - - return str -end - -local function newassoc(key, shared) - -- TODO don't use genkey here - local handle = genkey(16) - associations[handle] = {} - associations[handle]["key"] = key - associations[handle]["shared"] = shared - associations[handle]["time"] = os.time() - return handle -end - -local function split(str, sep) - local splits = {} - str:gsub("([^.."..sep.."]*)"..sep, function(c) table.insert(splits, c) end) - return splits -end - -local function sign(response, key) - local fields = {} - - for _,field in pairs(split(response["openid.signed"],",")) do - fields[field] = response["openid."..field] - end - - -- [#10.1] - return base64.encode(hmac.sha256(key, tokvstring(fields))) -end - -local function urlencode(s) - return (string.gsub(s, "%W", - function(str) - return string.format("%%%02X", string.byte(str)) - end)) -end - -local function urldecode(s) - return(string.gsub(string.gsub(s, "+", " "), "%%(%x%x)", - function(str) - return string.char(tonumber(str,16)) - end)) -end - -local function utctime() - local now = os.time() - local diff = os.difftime(now, os.time(os.date("!*t", now))) - return now-diff -end - -local function nonce() - -- generate a response nonce [#10.1] - local random = "" - for i=0,10 do - random = random..string.char(math.random(33,126)) - end - - local timestamp = os.date("%Y-%m-%dT%H:%M:%SZ", utctime()) - - return timestamp..random -end - -local function query_params(query) - if type(query) == "string" and #query > 0 then - if query:match("=") then - local params = {} - for k, v in query:gmatch("&?([^=%?]+)=([^&%?]+)&?") do - if k and v then - params[urldecode(k)] = urldecode(v) - end - end - return params - else - return urldecode(query) - end - end -end - -local function split_host_port(combined) - local host = combined - local port = "" - local cpos = string.find(combined, ":") - if cpos ~= nil then - host = string.sub(combined, 0, cpos-1) - port = string.sub(combined, cpos+1) - end - - return host, port -end - -local function toquerystring(dict) - -- query string encoding for a dictionary [#4.1.3] - local str = "" - - for k,v in pairs(dict) do - str = str..urlencode(k).."="..urlencode(v).."&" - end - - return string.sub(str, 0, -1) -end - -local function match_realm(url, realm) - -- FIXME do actual match [#9.2] - return true -end - -local function handle_endpoint(method, body, request) - module:log("debug", "Request at OpenID provider endpoint") - - local params = nil - - if method == "GET" then - params = query_params(request.url.query) - elseif method == "POST" then - params = query_params(body) - else - -- TODO error - return response_404 - end - - module:log("debug", "Request Parameters:\n"..humane(params)) - - if params["openid.ns"] == openidns then - -- OpenID 2.0 request [#5.1.1] - if params["openid.mode"] == "associate" then - -- Associate mode [#8] - -- TODO implement association - - -- Error response [#8.2.4] - local openidresponse = { - ["ns"] = openidns, - ["session_type"] = params["openid.session_type"], - ["assoc_type"] = params["openid.assoc_type"], - ["error"] = "Association not supported... yet", - ["error_code"] = "unsupported-type", - } - - local kvresponse = tokvstring(openidresponse) - module:log("debug", "OpenID Response:\n"..kvresponse) - return { - headers = { - ["Content-Type"] = "text/plain" - }, - body = kvresponse - } - elseif params["openid.mode"] == "checkid_setup" or params["openid.mode"] == "checkid_immediate" then - -- Requesting authentication [#9] - if not params["openid.realm"] then - -- set realm to default value of return_to [#9.1] - if params["openid.return_to"] then - params["openid.realm"] = params["openid.return_to"] - else - -- neither was sent, error [#9.1] - -- FIXME return proper error - return response_404 - end - end - - if params["openid.return_to"] then - -- Assure that the return_to url matches the realm [#9.2] - if not match_realm(params["openid.return_to"], params["openid.realm"]) then - -- FIXME return proper error - return response_404 - end - - -- Verify the return url [#9.2.1] - -- TODO implement return url verification - end - - if params["openid.claimed_id"] and params["openid.identity"] then - -- asserting an identifier [#9.1] - - if params["openid.identity"] == "http://specs.openid.net/auth/2.0/identifier_select" then - -- automatically select an identity [#9.1] - params["openid.identity"] = params["openid.claimed_id"] - end - - if params["openid.mode"] == "checkid_setup" then - -- Check ID Setup mode - -- TODO implement: NEXT STEP - local head = "<title>Prosody OpenID : Login</title>" - local body = string.format([[ -<p>Open ID Authentication<p> -<p>Identifier: <tt>%s</tt></p> -<p>Realm: <tt>%s</tt></p> -<p>Return: <tt>%s</tt></p> -<form method="POST" action="%s"> - Jabber ID: <input type="text" name="jid"/><br/> - Password: <input type="password" name="password"/><br/> - <input type="hidden" name="openid.return_to" value="%s"/> - <input type="submit" value="Authenticate"/> -</form> - ]], params["openid.claimed_id"], params["openid.realm"], params["openid.return_to"], base, params["openid.return_to"]) - - return string.format([[ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" -"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head> -<meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> -%s -</head> -<body> -%s -</body> -</html> - ]], head, body) - elseif params["openid.mode"] == "checkid_immediate" then - -- Check ID Immediate mode [#9.3] - -- TODO implement check id immediate - end - else - -- not asserting an identifier [#9.1] - -- used for extensions - -- TODO implement common extensions - end - elseif params["openid.mode"] == "check_authentication" then - module:log("debug", "OpenID Check Authentication Mode") - local assoc = associations[params["openid.assoc_handle"]] - module:log("debug", "Checking Association Handle: "..params["openid.assoc_handle"]) - if assoc and not assoc["shared"] then - module:log("debug", "Found valid association") - local sig = sign(params, assoc["key"]) - - local is_valid = "false" - if sig == params["openid.sig"] then - is_valid = "true" - end - - module:log("debug", "Signature is: "..is_valid) - - openidresponse = { - ns = openidns, - is_valid = is_valid, - } - - -- Delete this association - associations[params["openid.assoc_handle"]] = nil - return { - headers = { - ["Content-Type"] = "text/plain" - }, - body = tokvstring(openidresponse), - } - else - module:log("debug", "No valid association") - -- TODO return error - -- Invalidate the handle [#11.4.2.2] - end - else - -- Some other mode - -- TODO error - end - elseif params["password"] then - -- User is authenticating - local user, domain = jidutil.split(params["jid"]) - module:log("debug", "Authenticating "..params["jid"].." ("..user..","..domain..") with password: "..params["password"]) - local valid = usermanager.validate_credentials(domain, user, params["password"], "PLAIN") - if valid then - module:log("debug", "Authentication Succeeded: "..params["jid"]) - if params["openid.return_to"] ~= "" then - -- TODO redirect the user to return_to with the openid response - -- included, need to handle the case if its a GET, that there are - -- existing query parameters on the return_to URL [#10.1] - local host, port = split_host_port(request.headers.host) - local endpointurl = "" - if port == '' then - endpointurl = string.format("http://%s/%s", host, base) - else - endpointurl = string.format("http://%s:%s/%s", host, port, base) - end - - local nonce = nonce() - local key = genkey(32) - local assoc_handle = newassoc(key) - - local openidresponse = { - ["openid.ns"] = openidns, - ["openid.mode"] = "id_res", - ["openid.op_endpoint"] = endpointurl, - ["openid.claimed_id"] = endpointurl.."/"..user, - ["openid.identity"] = endpointurl.."/"..user, - ["openid.return_to"] = params["openid.return_to"], - ["openid.response_nonce"] = nonce, - ["openid.assoc_handle"] = assoc_handle, - ["openid.signed"] = "op_endpoint,identity,claimed_id,return_to,assoc_handle,response_nonce", -- FIXME - ["openid.sig"] = nil, - } - - openidresponse["openid.sig"] = sign(openidresponse, key) - - queryresponse = toquerystring(openidresponse) - - redirecturl = params["openid.return_to"] - -- add the parameters to the return_to - if redirecturl:match("?") then - redirecturl = redirecturl.."&" - else - redirecturl = redirecturl.."?" - end - - redirecturl = redirecturl..queryresponse - - module:log("debug", "Open ID Positive Assertion Response Table:\n"..humane(openidresponse)) - module:log("debug", "Open ID Positive Assertion Response URL:\n"..queryresponse) - module:log("debug", "Redirecting User to:\n"..redirecturl) - return { - status = "303 See Other", - headers = { - Location = redirecturl, - }, - body = "Redirecting to: "..redirecturl -- TODO Include a note with a hyperlink to redirect - } - else - -- TODO Do something useful is there is no return_to - end - else - module:log("debug", "Authentication Failed: "..params["jid"]) - -- TODO let them try again - end - else - -- Not an Open ID request, do something useful - -- TODO - end - - return response_404 -end - -local function handle_identifier(method, body, request, id) - module:log("debug", "Request at OpenID identifier") - local host, port = split_host_port(request.headers.host) - - local user_name = "" - local user_domain = "" - local apos = string.find(id, "@") - if apos == nil then - user_name = id - user_domain = host - else - user_name = string.sub(id, 0, apos-1) - user_domain = string.sub(id, apos+1) - end - - user, domain = jidutil.split(id) - - local exists = usermanager.user_exists(user_name, user_domain) - - if not exists then - return response_404 - end - - local endpointurl = "" - if port == '' then - endpointurl = string.format("http://%s/%s", host, base) - else - endpointurl = string.format("http://%s:%s/%s", host, port, base) - end - - local head = string.format("<title>Prosody OpenID : %s@%s</title>", user_name, user_domain) - -- OpenID HTML discovery [#7.3] - head = head .. string.format('<link rel="openid2.provider" href="%s" />', endpointurl) - - local content = 'request.url.path: ' .. request.url.path .. '<br/>' - content = content .. 'host+port: ' .. request.headers.host .. '<br/>' - content = content .. 'host: ' .. tostring(host) .. '<br/>' - content = content .. 'port: ' .. tostring(port) .. '<br/>' - content = content .. 'user_name: ' .. user_name .. '<br/>' - content = content .. 'user_domain: ' .. user_domain .. '<br/>' - content = content .. 'exists: ' .. tostring(exists) .. '<br/>' - - local body = string.format('<p>%s</p>', content) - - local data = string.format([[ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" -"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head> -<meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> -%s -</head> -<body> -%s -</body> -</html> - ]], head, body) - return data; -end - -local function handle_request(method, body, request) - module:log("debug", "Received request") - - -- Make sure the host is enabled - local host = split_host_port(request.headers.host) - if not hosts[host] then - return response_404 - end - - if request.url.path == "/"..base then - -- OpenID Provider Endpoint - return handle_endpoint(method, body, request) - else - local id = request.url.path:match("^/"..base.."/(.+)$") - if id then - -- OpenID Identifier - return handle_identifier(method, body, request, id) - else - return response_404 - end - end -end - -httpserver.new{ port = 5280, base = base, handler = handle_request, ssl = false}