Comparison

plugins/mod_bosh.lua @ 5648:f7f667c48d9a

mod_bosh: Clean up handling of response headers, set them only in one place
author Matthew Wild <mwild1@gmail.com>
date Wed, 05 Jun 2013 21:41:27 +0100
parent 5647:8767b47524c9
child 5649:c321f1fed851
comparison
equal deleted inserted replaced
5647:8767b47524c9 5648:f7f667c48d9a
33 local BOSH_DEFAULT_POLLING = module:get_option_number("bosh_max_polling", 5); 33 local BOSH_DEFAULT_POLLING = module:get_option_number("bosh_max_polling", 5);
34 local BOSH_DEFAULT_REQUESTS = module:get_option_number("bosh_max_requests", 2); 34 local BOSH_DEFAULT_REQUESTS = module:get_option_number("bosh_max_requests", 2);
35 local bosh_max_wait = module:get_option_number("bosh_max_wait", 120); 35 local bosh_max_wait = module:get_option_number("bosh_max_wait", 120);
36 36
37 local consider_bosh_secure = module:get_option_boolean("consider_bosh_secure"); 37 local consider_bosh_secure = module:get_option_boolean("consider_bosh_secure");
38
39 local default_headers = { ["Content-Type"] = "text/xml; charset=utf-8", ["Connection"] = "keep-alive" };
40
41 local cross_domain = module:get_option("cross_domain_bosh", false); 38 local cross_domain = module:get_option("cross_domain_bosh", false);
42 if cross_domain then 39
43 default_headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS"; 40 if type(cross_domain) == "table" then cross_domain = table.concat(cross_domain, ", "); end
44 default_headers["Access-Control-Allow-Headers"] = "Content-Type";
45 default_headers["Access-Control-Max-Age"] = "7200";
46
47 if cross_domain == true then
48 default_headers["Access-Control-Allow-Origin"] = "*";
49 elseif type(cross_domain) == "table" then
50 cross_domain = table.concat(cross_domain, ", ");
51 end
52 if type(cross_domain) == "string" then
53 default_headers["Access-Control-Allow-Origin"] = cross_domain;
54 end
55 end
56 41
57 local trusted_proxies = module:get_option_set("trusted_proxies", {"127.0.0.1"})._items; 42 local trusted_proxies = module:get_option_set("trusted_proxies", {"127.0.0.1"})._items;
58 43
59 local function get_ip_from_request(request) 44 local function get_ip_from_request(request)
60 local ip = request.conn:ip(); 45 local ip = request.conn:ip();
98 (session.log or log)("debug", "BOSH session marked as inactive (for %ds)", max_inactive); 83 (session.log or log)("debug", "BOSH session marked as inactive (for %ds)", max_inactive);
99 end 84 end
100 end 85 end
101 end 86 end
102 87
88 local function set_cross_domain_headers(response)
89 local headers = response.headers;
90 headers.access_control_allow_methods = "GET, POST, OPTIONS";
91 headers.access_control_allow_headers = "Content-Type";
92 headers.access_control_max_age = "7200";
93
94 if cross_domain == true then
95 headers.access_control_allow_origin = "*";
96 else
97 headers.access_control_allow_origin = cross_domain;
98 end
99 return response;
100 end
101
103 function handle_OPTIONS(request) 102 function handle_OPTIONS(request)
104 local headers = {}; 103 return set_cross_domain_headers(request.response);
105 for k,v in pairs(default_headers) do headers[k] = v; end
106 headers["Content-Type"] = nil;
107 return { headers = headers, body = "" };
108 end 104 end
109 105
110 function handle_POST(event) 106 function handle_POST(event)
111 log("debug", "Handling new request %s: %s\n----------", tostring(event.request), tostring(event.request.body)); 107 log("debug", "Handling new request %s: %s\n----------", tostring(event.request), tostring(event.request.body));
112 108
115 local body = request.body; 111 local body = request.body;
116 112
117 local context = { request = request, response = response, notopen = true }; 113 local context = { request = request, response = response, notopen = true };
118 local stream = new_xmpp_stream(context, stream_callbacks); 114 local stream = new_xmpp_stream(context, stream_callbacks);
119 response.context = context; 115 response.context = context;
116
117 local headers = response.headers;
118 headers.content_type = "text/xml; charset=utf-8";
119
120 if cross_domain then
121 set_cross_domain_headers(response);
122 end
120 123
121 -- stream:feed() calls the stream_callbacks, so all stanzas in 124 -- stream:feed() calls the stream_callbacks, so all stanzas in
122 -- the body are processed in this next line before it returns. 125 -- the body are processed in this next line before it returns.
123 -- In particular, the streamopened() stream callback is where 126 -- In particular, the streamopened() stream callback is where
124 -- much of the session logic happens, because it's where we first 127 -- much of the session logic happens, because it's where we first
215 log("info", "Disconnecting client, <stream:error> is: %s", tostring(close_reply)); 218 log("info", "Disconnecting client, <stream:error> is: %s", tostring(close_reply));
216 end 219 end
217 220
218 local response_body = tostring(close_reply); 221 local response_body = tostring(close_reply);
219 for _, held_request in ipairs(session.requests) do 222 for _, held_request in ipairs(session.requests) do
220 held_request.headers = default_headers;
221 held_request:send(response_body); 223 held_request:send(response_body);
222 end 224 end
223 sessions[session.sid] = nil; 225 sessions[session.sid] = nil;
224 inactive_sessions[session] = nil; 226 inactive_sessions[session] = nil;
225 sm_destroy_session(session); 227 sm_destroy_session(session);
309 311
310 local session = sessions[sid]; 312 local session = sessions[sid];
311 if not session then 313 if not session then
312 -- Unknown sid 314 -- Unknown sid
313 log("info", "Client tried to use sid '%s' which we don't know about", sid); 315 log("info", "Client tried to use sid '%s' which we don't know about", sid);
314 response.headers = default_headers;
315 response:send(tostring(st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", condition = "item-not-found" }))); 316 response:send(tostring(st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", condition = "item-not-found" })));
316 context.notopen = nil; 317 context.notopen = nil;
317 return; 318 return;
318 end 319 end
319 320
379 380
380 function stream_callbacks.error(context, error) 381 function stream_callbacks.error(context, error)
381 log("debug", "Error parsing BOSH request payload; %s", error); 382 log("debug", "Error parsing BOSH request payload; %s", error);
382 if not context.sid then 383 if not context.sid then
383 local response = context.response; 384 local response = context.response;
384 response.headers = default_headers;
385 response.status_code = 400; 385 response.status_code = 400;
386 response:send(); 386 response:send();
387 return; 387 return;
388 end 388 end
389 389