Software / code / prosody
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 |