mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
authorMatthew Wild <mwild1@gmail.com>
Fri, 18 May 2012 04:24:33 +0100
changeset 4892 6c8074f47ca4
parent 4891 189cfe565d03
child 4893 98ff89ab5d1d
mod_http: Add module:http_url([app_name,][default_path]) for a module to get a guess at its external URL
plugins/mod_http.lua
--- a/plugins/mod_http.lua	Fri May 18 04:22:51 2012 +0100
+++ b/plugins/mod_http.lua	Fri May 18 04:24:33 2012 +0100
@@ -9,6 +9,9 @@
 module:set_global();
 module:depends("http_errors");
 
+local moduleapi = require "core.moduleapi";
+local url_parse = require "socket.url".parse;
+
 local server = require "net.http.server";
 
 server.set_default_host(module:get_option_string("http_default_host"));
@@ -31,9 +34,27 @@
 end
 
 local function get_base_path(host_module, app_name, default_app_path)
-	return host_module:get_option("http_paths", {})[app_name] -- Host
+	return normalize_path(host_module:get_option("http_paths", {})[app_name] -- Host
 		or module:get_option("http_paths", {})[app_name] -- Global
-		or default_app_path; -- Default
+		or default_app_path); -- Default
+end
+
+-- Helper to deduce a module's external URL
+function moduleapi.http_url(module, app_name, default_path)
+	app_name = app_name or (module.name:gsub("^http_", ""));
+	local ext = url_parse(module:get_option_string("http_external_url")) or {};
+	local services = portmanager.get_active_services();
+	local http_services = services:get("https") or services:get("http");
+	for interface, ports in pairs(http_services) do
+		for port, services in pairs(ports) do
+			local path = get_base_path(module, app_name, default_path or "/"..app_name);
+			port = tonumber(ext.port) or port or 80;
+			if port == 80 then port = ""; else port = ":"..port; end
+			return (ext.scheme or services[1].service.name).."://"
+				..(ext.host or module.host)..port
+				..normalize_path(ext.path or "/")..(path:sub(2));
+		end
+	end
 end
 
 function module.add_host(module)
@@ -43,8 +64,8 @@
 	local function http_app_added(event)
 		local app_name = event.item.name;
 		local default_app_path = event.item.default_path or "/"..app_name;
-		local app_path = normalize_path(get_base_path(module, app_name, default_app_path));
-		if not app_name then		
+		local app_path = get_base_path(module, app_name, default_app_path);
+		if not app_name then
 			-- TODO: Link to docs
 			module:log("error", "HTTP app has no 'name', add one or use module:provides('http', app)");
 			return;