Diff

plugins/mod_bosh.lua @ 2484:cf924f587410

mod_bosh: Support for cross-domain access control using CORS
author Matthew Wild <mwild1@gmail.com>
date Thu, 21 Jan 2010 15:07:52 +0000
parent 2473:3f4cfa375bd6
child 2485:ace62f19076d
line wrap: on
line diff
--- a/plugins/mod_bosh.lua	Thu Jan 21 14:53:01 2010 +0000
+++ b/plugins/mod_bosh.lua	Thu Jan 21 15:07:52 2010 +0000
@@ -34,6 +34,23 @@
 local default_headers = { ["Content-Type"] = "text/xml; charset=utf-8" };
 local session_close_reply = { headers = default_headers, body = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate" }), attr = {} };
 
+local http_options, http_denied_options = { headers = {} }, { headers = {} };
+local cross_domain = module:get_option("cross_domain_bosh");
+if cross_domain ~= false then
+	http_options.headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS";
+	http_options.headers["Access-Control-Allow-Headers"] = "Content-Type";
+	http_options.headers["Access-Control-Max-Age"] = "86400";
+
+	if cross_domain == true then
+		http_options.headers["Access-Control-Allow-Origin"] = "*";
+	elseif type(cross_domain) == "table" then
+		cross_domain = table.concat(cross_domain, ", ");
+	end
+	if type(cross_domain) == "string" then
+		http_options.headers["Access-Control-Allow-Origin"] = cross_domain;
+	end
+end
+
 local t_insert, t_remove, t_concat = table.insert, table.remove, table.concat;
 local os_time = os.time;
 
@@ -59,9 +76,25 @@
 	end
 end
 
+local function send_options_headers(request)
+	if cross_domain == nil then
+		local host = request.headers.host and request.headers.host:match("^[^:]+");
+		if hosts[host] then
+			http_options.headers["Access-Control-Allow-Origin"] = "http://"..host;
+		else
+			return http_denied_options; -- We don't want to reveal the hosts we serve
+		end
+	end
+	return http_options;
+end
+
 function handle_request(method, body, request)
 	if (not body) or request.method ~= "POST" then
-		return "<html><body>You really don't look like a BOSH client to me... what do you want?</body></html>";
+		if request.method == "OPTIONS" then
+			return send_options_headers(request);
+		else
+			return "<html><body>You really don't look like a BOSH client to me... what do you want?</body></html>";
+		end
 	end
 	if not method then
 		log("debug", "Request %s suffered error %s", tostring(request.id), body);