Software / code / prosody
Annotate
plugins/mod_websocket.lua @ 13801:a5d5fefb8b68 13.0
mod_tls: Enable Prosody's certificate checking for incoming s2s connections (fixes #1916) (thanks Damian, Zash)
Various options in Prosody allow control over the behaviour of the certificate
verification process For example, some deployments choose to allow falling
back to traditional "dialback" authentication (XEP-0220), while others verify
via DANE, hard-coded fingerprints, or other custom plugins.
Implementing this flexibility requires us to override OpenSSL's default
certificate verification, to allow Prosody to verify the certificate itself,
apply custom policies and make decisions based on the outcome.
To enable our custom logic, we have to suppress OpenSSL's default behaviour of
aborting the connection with a TLS alert message. With LuaSec, this can be
achieved by using the verifyext "lsec_continue" flag.
We also need to use the lsec_ignore_purpose flag, because XMPP s2s uses server
certificates as "client" certificates (for mutual TLS verification in outgoing
s2s connections).
Commit 99d2100d2918 moved these settings out of the defaults and into mod_s2s,
because we only really need these changes for s2s, and they should be opt-in,
rather than automatically applied to all TLS services we offer.
That commit was incomplete, because it only added the flags for incoming
direct TLS connections. StartTLS connections are handled by mod_tls, which was
not applying the lsec_* flags. It previously worked because they were already
in the defaults.
This resulted in incoming s2s connections with "invalid" certificates being
aborted early by OpenSSL, even if settings such as `s2s_secure_auth = false`
or DANE were present in the config.
Outgoing s2s connections inherit verify "none" from the defaults, which means
OpenSSL will receive the cert but will not terminate the connection when it is
deemed invalid. This means we don't need lsec_continue there, and we also
don't need lsec_ignore_purpose (because the remote peer is a "server").
Wondering why we can't just use verify "none" for incoming s2s? It's because
in that mode, OpenSSL won't request a certificate from the peer for incoming
connections. Setting verify "peer" is how you ask OpenSSL to request a
certificate from the client, but also what triggers its built-in verification.
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Tue, 01 Apr 2025 17:26:56 +0100 |
| parent | 13765:7c57fb2ffbb0 |
| rev | line source |
|---|---|
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
1 -- Prosody IM |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
2 -- Copyright (C) 2012-2014 Florian Zeitz |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
3 -- |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
4 -- This project is MIT/X11 licensed. Please see the |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
5 -- COPYING file in the source package for more information. |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
6 -- |
|
6894
f7203c7cb7ff
mod_websocket: Silence luacheck warnings
Kim Alvefur <zash@zash.se>
parents:
6893
diff
changeset
|
7 -- luacheck: ignore 431/log |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
8 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
9 module:set_global(); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
10 |
|
12977
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12894
diff
changeset
|
11 local add_task = require "prosody.util.timer".add_task; |
|
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12894
diff
changeset
|
12 local add_filter = require "prosody.util.filters".add_filter; |
|
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12894
diff
changeset
|
13 local sha1 = require "prosody.util.hashes".sha1; |
|
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12894
diff
changeset
|
14 local base64 = require "prosody.util.encodings".base64.encode; |
|
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12894
diff
changeset
|
15 local st = require "prosody.util.stanza"; |
|
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12894
diff
changeset
|
16 local parse_xml = require "prosody.util.xml".parse; |
|
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12894
diff
changeset
|
17 local contains_token = require "prosody.util.http".contains_token; |
|
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12894
diff
changeset
|
18 local portmanager = require "prosody.core.portmanager"; |
|
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12894
diff
changeset
|
19 local sm_destroy_session = require"prosody.core.sessionmanager".destroy_session; |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
20 local log = module._log; |
|
12977
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12894
diff
changeset
|
21 local dbuffer = require "prosody.util.dbuffer"; |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
22 |
|
12977
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12894
diff
changeset
|
23 local websocket_frames = require"prosody.net.websocket.frames"; |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
24 local parse_frame = websocket_frames.parse; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
25 local build_frame = websocket_frames.build; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
26 local build_close = websocket_frames.build_close; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
27 local parse_close = websocket_frames.parse_close; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
28 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
29 local t_concat = table.concat; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
30 |
|
13213
50324f66ca2a
plugins: Use integer config API with interval specification where sensible
Kim Alvefur <zash@zash.se>
parents:
13209
diff
changeset
|
31 local stanza_size_limit = module:get_option_integer("c2s_stanza_size_limit", 1024 * 256, 10000); |
|
50324f66ca2a
plugins: Use integer config API with interval specification where sensible
Kim Alvefur <zash@zash.se>
parents:
13209
diff
changeset
|
32 local frame_buffer_limit = module:get_option_integer("websocket_frame_buffer_limit", 2 * stanza_size_limit, 0); |
|
50324f66ca2a
plugins: Use integer config API with interval specification where sensible
Kim Alvefur <zash@zash.se>
parents:
13209
diff
changeset
|
33 local frame_fragment_limit = module:get_option_integer("websocket_frame_fragment_limit", 8, 0); |
|
13209
c8d949cf6b09
plugins: Switch to :get_option_period() for time range options
Kim Alvefur <zash@zash.se>
parents:
12977
diff
changeset
|
34 local stream_close_timeout = module:get_option_period("c2s_close_timeout", 5); |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
35 local consider_websocket_secure = module:get_option_boolean("consider_websocket_secure"); |
|
9795
02735bc82126
mod_websocket: Drop CORS code in favor of that in mod_http
Kim Alvefur <zash@zash.se>
parents:
9415
diff
changeset
|
36 local cross_domain = module:get_option("cross_domain_websocket"); |
|
02735bc82126
mod_websocket: Drop CORS code in favor of that in mod_http
Kim Alvefur <zash@zash.se>
parents:
9415
diff
changeset
|
37 if cross_domain ~= nil then |
|
02735bc82126
mod_websocket: Drop CORS code in favor of that in mod_http
Kim Alvefur <zash@zash.se>
parents:
9415
diff
changeset
|
38 module:log("info", "The 'cross_domain_websocket' option has been deprecated"); |
|
7762
2208e6cd0d9f
mod_websocket: Verify that the client-sent Origin header matches cross_domain_websocket (fixes #652)
Kim Alvefur <zash@zash.se>
parents:
7761
diff
changeset
|
39 end |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
40 local xmlns_framing = "urn:ietf:params:xml:ns:xmpp-framing"; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
41 local xmlns_streams = "http://etherx.jabber.org/streams"; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
42 local xmlns_client = "jabber:client"; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
43 local stream_xmlns_attr = {xmlns='urn:ietf:params:xml:ns:xmpp-streams'}; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
44 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
45 module:depends("c2s") |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
46 local sessions = module:shared("c2s/sessions"); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
47 local c2s_listener = portmanager.get_service("c2s").listener; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
48 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
49 --- Session methods |
|
7938
3629f03817f8
mod_websocket: Make open_stream method behave like the one from util.xmppstream
Kim Alvefur <zash@zash.se>
parents:
7937
diff
changeset
|
50 local function session_open_stream(session, from, to) |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
51 local attr = { |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
52 xmlns = xmlns_framing, |
|
7937
5b03a8003659
mod_websocket: Include xml:lang attribute on stream <open> (fixes #840)
Kim Alvefur <zash@zash.se>
parents:
7914
diff
changeset
|
53 ["xml:lang"] = "en", |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
54 version = "1.0", |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
55 id = session.streamid or "", |
|
7938
3629f03817f8
mod_websocket: Make open_stream method behave like the one from util.xmppstream
Kim Alvefur <zash@zash.se>
parents:
7937
diff
changeset
|
56 from = from or session.host, to = to, |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
57 }; |
|
7938
3629f03817f8
mod_websocket: Make open_stream method behave like the one from util.xmppstream
Kim Alvefur <zash@zash.se>
parents:
7937
diff
changeset
|
58 if session.stream_attrs then |
|
3629f03817f8
mod_websocket: Make open_stream method behave like the one from util.xmppstream
Kim Alvefur <zash@zash.se>
parents:
7937
diff
changeset
|
59 session:stream_attrs(from, to, attr) |
|
3629f03817f8
mod_websocket: Make open_stream method behave like the one from util.xmppstream
Kim Alvefur <zash@zash.se>
parents:
7937
diff
changeset
|
60 end |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
61 session.send(st.stanza("open", attr)); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
62 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
63 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
64 local function session_close(session, reason) |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
65 local log = session.log or log; |
|
12894
0598d822614f
mod_websocket: Fire pre-session-close event (fixes #1800)
Matthew Wild <mwild1@gmail.com>
parents:
12444
diff
changeset
|
66 local close_event_payload = { session = session, reason = reason }; |
|
0598d822614f
mod_websocket: Fire pre-session-close event (fixes #1800)
Matthew Wild <mwild1@gmail.com>
parents:
12444
diff
changeset
|
67 module:context(session.host):fire_event("pre-session-close", close_event_payload); |
|
0598d822614f
mod_websocket: Fire pre-session-close event (fixes #1800)
Matthew Wild <mwild1@gmail.com>
parents:
12444
diff
changeset
|
68 reason = close_event_payload.reason; |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
69 if session.conn then |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
70 if session.notopen then |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
71 session:open_stream(); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
72 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
73 if reason then -- nil == no err, initiated by us, false == initiated by client |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
74 local stream_error = st.stanza("stream:error"); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
75 if type(reason) == "string" then -- assume stream error |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
76 stream_error:tag(reason, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' }); |
|
11868
ae093c259da2
mod_c2s,etc: Identify stanza object with appropriate function
Kim Alvefur <zash@zash.se>
parents:
11771
diff
changeset
|
77 elseif st.is_stanza(reason) then |
|
ae093c259da2
mod_c2s,etc: Identify stanza object with appropriate function
Kim Alvefur <zash@zash.se>
parents:
11771
diff
changeset
|
78 stream_error = reason; |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
79 elseif type(reason) == "table" then |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
80 if reason.condition then |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
81 stream_error:tag(reason.condition, stream_xmlns_attr):up(); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
82 if reason.text then |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
83 stream_error:tag("text", stream_xmlns_attr):text(reason.text):up(); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
84 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
85 if reason.extra then |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
86 stream_error:add_child(reason.extra); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
87 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
88 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
89 end |
|
13765
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
90 stream_error = tostring(stream_error); |
|
10111
0f335815244f
plugins: Remove tostring call from logging
Kim Alvefur <zash@zash.se>
parents:
10097
diff
changeset
|
91 log("debug", "Disconnecting client, <stream:error> is: %s", stream_error); |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
92 session.send(stream_error); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
93 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
94 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
95 session.send(st.stanza("close", { xmlns = xmlns_framing })); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
96 function session.send() return false; end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
97 |
|
13765
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
98 local reason_text = (reason and (reason.name or reason.text or reason.condition)) or reason; |
|
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
99 session.log("debug", "c2s stream for %s closed: %s", session.full_jid or session.ip or "<unknown>", reason_text or "session closed"); |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
100 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
101 -- Authenticated incoming stream may still be sending us stanzas, so wait for </stream:stream> from remote |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
102 local conn = session.conn; |
|
13765
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
103 if reason_text == nil and not session.notopen and session.type == "c2s" then |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
104 -- Grace time to process data from authenticated cleanly-closed stream |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
105 add_task(stream_close_timeout, function () |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
106 if not session.destroyed then |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
107 session.log("warn", "Failed to receive a stream close response, closing connection anyway..."); |
|
13765
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
108 sm_destroy_session(session, reason_text); |
|
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
109 if conn then |
|
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
110 conn:write(build_close(1000, "Stream closed")); |
|
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
111 conn:close(); |
|
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
112 end |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
113 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
114 end); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
115 else |
|
13765
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
116 sm_destroy_session(session, reason_text); |
|
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
117 if conn then |
|
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
118 conn:write(build_close(1000, "Stream closed")); |
|
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
119 conn:close(); |
|
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
120 end |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
121 end |
|
13765
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
122 else |
|
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
123 local reason_text = (reason and (reason.name or reason.text or reason.condition)) or reason; |
|
7c57fb2ffbb0
mod_websocket: Merge session close handling changes from mod_c2s (bug fixes)
Matthew Wild <mwild1@gmail.com>
parents:
13749
diff
changeset
|
124 sm_destroy_session(session, reason_text); |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
125 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
126 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
127 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
128 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
129 --- Filters |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
130 local function filter_open_close(data) |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
131 if not data:find(xmlns_framing, 1, true) then return data; end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
132 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
133 local oc = parse_xml(data); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
134 if not oc then return data; end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
135 if oc.attr.xmlns ~= xmlns_framing then return data; end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
136 if oc.name == "close" then return "</stream:stream>"; end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
137 if oc.name == "open" then |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
138 oc.name = "stream:stream"; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
139 oc.attr.xmlns = nil; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
140 oc.attr["xmlns:stream"] = xmlns_streams; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
141 return oc:top_tag(); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
142 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
143 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
144 return data; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
145 end |
|
11113
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
146 |
|
11393
e6122e6a40a0
mod_websocket: Use mod_http_errors html template #1172
Kim Alvefur <zash@zash.se>
parents:
11384
diff
changeset
|
147 local default_get_response_text = "It works! Now point your WebSocket client to this URL to connect to Prosody." |
|
e6122e6a40a0
mod_websocket: Use mod_http_errors html template #1172
Kim Alvefur <zash@zash.se>
parents:
11384
diff
changeset
|
148 local websocket_get_response_text = module:get_option_string("websocket_get_response_text", default_get_response_text) |
|
e6122e6a40a0
mod_websocket: Use mod_http_errors html template #1172
Kim Alvefur <zash@zash.se>
parents:
11384
diff
changeset
|
149 |
|
10728
2764beb552cd
mod_bosh, mod_websocket: Add config options to override GET responses
Matthew Wild <mwild1@gmail.com>
parents:
10617
diff
changeset
|
150 local default_get_response_body = [[<!DOCTYPE html><html><head><title>Websocket</title></head><body> |
|
11393
e6122e6a40a0
mod_websocket: Use mod_http_errors html template #1172
Kim Alvefur <zash@zash.se>
parents:
11384
diff
changeset
|
151 <p>]]..websocket_get_response_text..[[</p> |
|
10728
2764beb552cd
mod_bosh, mod_websocket: Add config options to override GET responses
Matthew Wild <mwild1@gmail.com>
parents:
10617
diff
changeset
|
152 </body></html>]] |
|
2764beb552cd
mod_bosh, mod_websocket: Add config options to override GET responses
Matthew Wild <mwild1@gmail.com>
parents:
10617
diff
changeset
|
153 local websocket_get_response_body = module:get_option_string("websocket_get_response_body", default_get_response_body) |
|
2764beb552cd
mod_bosh, mod_websocket: Add config options to override GET responses
Matthew Wild <mwild1@gmail.com>
parents:
10617
diff
changeset
|
154 |
|
11113
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
155 local function validate_frame(frame, max_length) |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
156 local opcode, length = frame.opcode, frame.length; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
157 |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
158 if max_length and length > max_length then |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
159 return false, 1009, "Payload too large"; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
160 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
161 |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
162 -- Error cases |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
163 if frame.RSV1 or frame.RSV2 or frame.RSV3 then -- Reserved bits non zero |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
164 return false, 1002, "Reserved bits not zero"; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
165 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
166 |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
167 if opcode == 0x8 and frame.data then -- close frame |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
168 if length == 1 then |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
169 return false, 1002, "Close frame with payload, but too short for status code"; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
170 elseif length >= 2 then |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
171 local status_code = parse_close(frame.data) |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
172 if status_code < 1000 then |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
173 return false, 1002, "Closed with invalid status code"; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
174 elseif ((status_code > 1003 and status_code < 1007) or status_code > 1011) and status_code < 3000 then |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
175 return false, 1002, "Closed with reserved status code"; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
176 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
177 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
178 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
179 |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
180 if opcode >= 0x8 then |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
181 if length > 125 then -- Control frame with too much payload |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
182 return false, 1002, "Payload too large"; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
183 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
184 |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
185 if not frame.FIN then -- Fragmented control frame |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
186 return false, 1002, "Fragmented control frame"; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
187 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
188 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
189 |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
190 if (opcode > 0x2 and opcode < 0x8) or (opcode > 0xA) then |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
191 return false, 1002, "Reserved opcode"; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
192 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
193 |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
194 -- Check opcode |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
195 if opcode == 0x2 then -- Binary frame |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
196 return false, 1003, "Only text frames are supported, RFC 7395 3.2"; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
197 elseif opcode == 0x8 then -- Close request |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
198 return false, 1000, "Goodbye"; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
199 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
200 |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
201 -- Other (XMPP-specific) validity checks |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
202 if not frame.FIN then |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
203 return false, 1003, "Continuation frames are not supported, RFC 7395 3.3.3"; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
204 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
205 if opcode == 0x01 and frame.data and frame.data:byte(1, 1) ~= 60 then |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
206 return false, 1007, "Invalid payload start character, RFC 7395 3.3.3"; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
207 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
208 |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
209 return true; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
210 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
211 |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
212 |
|
6894
f7203c7cb7ff
mod_websocket: Silence luacheck warnings
Kim Alvefur <zash@zash.se>
parents:
6893
diff
changeset
|
213 function handle_request(event) |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
214 local request, response = event.request, event.response; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
215 local conn = response.conn; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
216 |
|
7914
a6eb3b6bf903
mod_websocket: Set connections starttls method to false to prevent mod_tls from offering starttls (fixes #837)
Kim Alvefur <zash@zash.se>
parents:
7764
diff
changeset
|
217 conn.starttls = false; -- Prevent mod_tls from believing starttls can be done |
|
a6eb3b6bf903
mod_websocket: Set connections starttls method to false to prevent mod_tls from offering starttls (fixes #837)
Kim Alvefur <zash@zash.se>
parents:
7764
diff
changeset
|
218 |
|
10325
f2bbad04cf64
mod_websocket: Guard against upgrading to websocket from a HEAD request
Kim Alvefur <zash@zash.se>
parents:
10111
diff
changeset
|
219 if not request.headers.sec_websocket_key or request.method ~= "GET" then |
|
11393
e6122e6a40a0
mod_websocket: Use mod_http_errors html template #1172
Kim Alvefur <zash@zash.se>
parents:
11384
diff
changeset
|
220 return module:fire_event("http-message", { |
|
e6122e6a40a0
mod_websocket: Use mod_http_errors html template #1172
Kim Alvefur <zash@zash.se>
parents:
11384
diff
changeset
|
221 response = event.response; |
|
e6122e6a40a0
mod_websocket: Use mod_http_errors html template #1172
Kim Alvefur <zash@zash.se>
parents:
11384
diff
changeset
|
222 --- |
|
e6122e6a40a0
mod_websocket: Use mod_http_errors html template #1172
Kim Alvefur <zash@zash.se>
parents:
11384
diff
changeset
|
223 title = "Prosody WebSocket endpoint"; |
|
e6122e6a40a0
mod_websocket: Use mod_http_errors html template #1172
Kim Alvefur <zash@zash.se>
parents:
11384
diff
changeset
|
224 message = websocket_get_response_text; |
|
e6122e6a40a0
mod_websocket: Use mod_http_errors html template #1172
Kim Alvefur <zash@zash.se>
parents:
11384
diff
changeset
|
225 warning = not (consider_websocket_secure or request.secure) and "This endpoint is not considered secure!" or nil; |
|
e6122e6a40a0
mod_websocket: Use mod_http_errors html template #1172
Kim Alvefur <zash@zash.se>
parents:
11384
diff
changeset
|
226 }) or websocket_get_response_body; |
|
e6122e6a40a0
mod_websocket: Use mod_http_errors html template #1172
Kim Alvefur <zash@zash.se>
parents:
11384
diff
changeset
|
227 end |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
228 |
|
7761
e0e1f6d6fb4f
mod_websocket: Use contains_token from util.http for checking if the requested WebSocket sub-protocols include XMPP
Kim Alvefur <zash@zash.se>
parents:
7760
diff
changeset
|
229 local wants_xmpp = contains_token(request.headers.sec_websocket_protocol or "", "xmpp"); |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
230 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
231 if not wants_xmpp then |
|
7760
801d4c8e0f58
mod_websocket: Add some debug messages
Kim Alvefur <zash@zash.se>
parents:
7716
diff
changeset
|
232 module:log("debug", "Client didn't want to talk XMPP, list of protocols was %s", request.headers.sec_websocket_protocol or "(empty)"); |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
233 return 501; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
234 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
235 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
236 local function websocket_close(code, message) |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
237 conn:write(build_close(code, message)); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
238 conn:close(); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
239 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
240 |
|
11113
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
241 local function websocket_handle_error(session, code, message) |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
242 if code == 1009 then -- stanza size limit exceeded |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
243 -- we close the session, rather than the connection, |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
244 -- otherwise a resuming client will simply resend the |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
245 -- offending stanza |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
246 session:close({ condition = "policy-violation", text = "stanza too large" }); |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
247 else |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
248 websocket_close(code, message); |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
249 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
250 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
251 |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
252 local function handle_frame(frame) |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
253 module:log("debug", "Websocket received frame: opcode=%0x, %i bytes", frame.opcode, #frame.data); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
254 |
|
11113
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
255 -- Check frame makes sense |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
256 local frame_ok, err_status, err_text = validate_frame(frame, stanza_size_limit); |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
257 if not frame_ok then |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
258 return frame_ok, err_status, err_text; |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
259 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
260 |
|
11113
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
261 local opcode = frame.opcode; |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
262 if opcode == 0x9 then -- Ping frame |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
263 frame.opcode = 0xA; |
|
10581
10d6d0d91f4e
mod_websocket: Clear mask bit when reflecting ping frames (fixes #1484)
Kim Alvefur <zash@zash.se>
parents:
10092
diff
changeset
|
264 frame.MASK = false; -- Clients send masked frames, servers don't, see #1484 |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
265 conn:write(build_frame(frame)); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
266 return ""; |
|
7314
e327e5b592f5
mod_websocket: Remove warning about unsolicited pong frames "MAY be sent unsolicited" per RFC 6455 (thanks mt)
Kim Alvefur <zash@zash.se>
parents:
7294
diff
changeset
|
267 elseif opcode == 0xA then -- Pong frame, MAY be sent unsolicited, eg as keepalive |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
268 return ""; |
|
11113
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
269 elseif opcode ~= 0x1 then -- Not text frame (which is all we support) |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
270 log("warn", "Received frame with unsupported opcode %i", opcode); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
271 return ""; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
272 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
273 |
|
11113
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
274 return frame.data; |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
275 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
276 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
277 conn:setlistener(c2s_listener); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
278 c2s_listener.onconnect(conn); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
279 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
280 local session = sessions[conn]; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
281 |
|
8595
d3bbff01df9d
mod_websocket: Transfer IP address derived by mod_http
Kim Alvefur <zash@zash.se>
parents:
8145
diff
changeset
|
282 -- Use upstream IP if a HTTP proxy was used |
|
d3bbff01df9d
mod_websocket: Transfer IP address derived by mod_http
Kim Alvefur <zash@zash.se>
parents:
8145
diff
changeset
|
283 -- See mod_http and #540 |
|
d3bbff01df9d
mod_websocket: Transfer IP address derived by mod_http
Kim Alvefur <zash@zash.se>
parents:
8145
diff
changeset
|
284 session.ip = request.ip; |
|
d3bbff01df9d
mod_websocket: Transfer IP address derived by mod_http
Kim Alvefur <zash@zash.se>
parents:
8145
diff
changeset
|
285 |
|
11384
f9edf26c66fc
mod_websocket: Inherit security status from http request
Kim Alvefur <zash@zash.se>
parents:
11114
diff
changeset
|
286 session.secure = consider_websocket_secure or request.secure or session.secure; |
|
8789
4ae8dd415e94
mod_websocket: Store the request object on the session for use by other modules
Matthew Wild <mwild1@gmail.com>
parents:
8145
diff
changeset
|
287 session.websocket_request = request; |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
288 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
289 session.open_stream = session_open_stream; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
290 session.close = session_close; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
291 |
|
11109
7ec7dba7ba8b
mod_websocket: Add separate limit for frame buffer size
Matthew Wild <mwild1@gmail.com>
parents:
11108
diff
changeset
|
292 local frameBuffer = dbuffer.new(frame_buffer_limit, frame_fragment_limit); |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
293 add_filter(session, "bytes/in", function(data) |
|
11108
fa1821b56f75
mod_websocket: handle full frame buffer and raise stream error
Matthew Wild <mwild1@gmail.com>
parents:
11107
diff
changeset
|
294 if not frameBuffer:write(data) then |
|
fa1821b56f75
mod_websocket: handle full frame buffer and raise stream error
Matthew Wild <mwild1@gmail.com>
parents:
11107
diff
changeset
|
295 session.log("warn", "websocket frame buffer full - terminating session"); |
|
fa1821b56f75
mod_websocket: handle full frame buffer and raise stream error
Matthew Wild <mwild1@gmail.com>
parents:
11107
diff
changeset
|
296 session:close({ condition = "resource-constraint", text = "frame buffer exceeded" }); |
|
fa1821b56f75
mod_websocket: handle full frame buffer and raise stream error
Matthew Wild <mwild1@gmail.com>
parents:
11107
diff
changeset
|
297 return; |
|
fa1821b56f75
mod_websocket: handle full frame buffer and raise stream error
Matthew Wild <mwild1@gmail.com>
parents:
11107
diff
changeset
|
298 end |
|
11107
ddd0007e0f1b
mod_websocket: Switch partial frame buffering to util.dbuffer
Matthew Wild <mwild1@gmail.com>
parents:
10616
diff
changeset
|
299 |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
300 local cache = {}; |
|
11113
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
301 local frame, length, partial = parse_frame(frameBuffer); |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
302 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
303 while frame do |
|
11113
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
304 frameBuffer:discard(length); |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
305 local result, err_status, err_text = handle_frame(frame); |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
306 if not result then |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
307 websocket_handle_error(session, err_status, err_text); |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
308 break; |
|
11110
67fb92e312f1
mod_websocket: Enforce stanza size limit and close stream
Matthew Wild <mwild1@gmail.com>
parents:
11109
diff
changeset
|
309 end |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
310 cache[#cache+1] = filter_open_close(result); |
|
11113
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
311 frame, length, partial = parse_frame(frameBuffer); |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
312 end |
|
11113
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
313 |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
314 if partial then |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
315 -- The header of the next frame is already in the buffer, run |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
316 -- some early validation here |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
317 local frame_ok, err_status, err_text = validate_frame(partial, stanza_size_limit); |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
318 if not frame_ok then |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
319 websocket_handle_error(session, err_status, err_text); |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
320 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
321 end |
|
10301c214f4e
mod_websocket: Refactor frame validity checking, also check partially-received frames against constraints
Matthew Wild <mwild1@gmail.com>
parents:
11111
diff
changeset
|
322 |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
323 return t_concat(cache, ""); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
324 end); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
325 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
326 add_filter(session, "stanzas/out", function(stanza) |
|
10092
4b3c129e96f2
mod_websocket: Clone stanza before mutating (fixes #1398)
Kim Alvefur <zash@zash.se>
parents:
9805
diff
changeset
|
327 stanza = st.clone(stanza); |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
328 local attr = stanza.attr; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
329 attr.xmlns = attr.xmlns or xmlns_client; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
330 if stanza.name:find("^stream:") then |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
331 attr["xmlns:stream"] = attr["xmlns:stream"] or xmlns_streams; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
332 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
333 return stanza; |
|
7294
5f4d0753c818
mod_websocket: Make sure stanza xmlns filter runs late in the chain
Kim Alvefur <zash@zash.se>
parents:
6894
diff
changeset
|
334 end, -1000); |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
335 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
336 add_filter(session, "bytes/out", function(data) |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
337 return build_frame({ FIN = true, opcode = 0x01, data = tostring(data)}); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
338 end); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
339 |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
340 response.status_code = 101; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
341 response.headers.upgrade = "websocket"; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
342 response.headers.connection = "Upgrade"; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
343 response.headers.sec_webSocket_accept = base64(sha1(request.headers.sec_websocket_key .. "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")); |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
344 response.headers.sec_webSocket_protocol = "xmpp"; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
345 |
|
10616
37936c72846d
mod_websocket: Fire event on session creation (thanks Aaron van Meerten)
Matthew Wild <mwild1@gmail.com>
parents:
10581
diff
changeset
|
346 module:fire_event("websocket-session", { session = session, request = request }); |
|
37936c72846d
mod_websocket: Fire event on session creation (thanks Aaron van Meerten)
Matthew Wild <mwild1@gmail.com>
parents:
10581
diff
changeset
|
347 |
|
7760
801d4c8e0f58
mod_websocket: Add some debug messages
Kim Alvefur <zash@zash.se>
parents:
7716
diff
changeset
|
348 session.log("debug", "Sending WebSocket handshake"); |
|
801d4c8e0f58
mod_websocket: Add some debug messages
Kim Alvefur <zash@zash.se>
parents:
7716
diff
changeset
|
349 |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
350 return ""; |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
351 end |
|
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
352 |
|
7315
4fd984d1e445
mod_websocket: Send a ping on read timeout
Kim Alvefur <zash@zash.se>
parents:
7314
diff
changeset
|
353 local function keepalive(event) |
|
7340
7dea28dafc49
mod_websocket: Fix read timeout handler (thanks mt)
Kim Alvefur <zash@zash.se>
parents:
7315
diff
changeset
|
354 local session = event.session; |
|
7dea28dafc49
mod_websocket: Fix read timeout handler (thanks mt)
Kim Alvefur <zash@zash.se>
parents:
7315
diff
changeset
|
355 if session.open_stream == session_open_stream then |
|
7716
779a9ef6b4fd
mod_websocket: Set FIN flag on ping frames (fixes #773)
Kim Alvefur <zash@zash.se>
parents:
7340
diff
changeset
|
356 return session.conn:write(build_frame({ opcode = 0x9, FIN = true })); |
|
7340
7dea28dafc49
mod_websocket: Fix read timeout handler (thanks mt)
Kim Alvefur <zash@zash.se>
parents:
7315
diff
changeset
|
357 end |
|
7315
4fd984d1e445
mod_websocket: Send a ping on read timeout
Kim Alvefur <zash@zash.se>
parents:
7314
diff
changeset
|
358 end |
|
4fd984d1e445
mod_websocket: Send a ping on read timeout
Kim Alvefur <zash@zash.se>
parents:
7314
diff
changeset
|
359 |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
360 function module.add_host(module) |
|
7315
4fd984d1e445
mod_websocket: Send a ping on read timeout
Kim Alvefur <zash@zash.se>
parents:
7314
diff
changeset
|
361 module:hook("c2s-read-timeout", keepalive, -0.9); |
|
11771
4c0802b52673
mod_bosh,mod_websocket: Make into global-shared modules (...again)
Kim Alvefur <zash@zash.se>
parents:
11560
diff
changeset
|
362 |
|
4c0802b52673
mod_bosh,mod_websocket: Make into global-shared modules (...again)
Kim Alvefur <zash@zash.se>
parents:
11560
diff
changeset
|
363 module:depends("http"); |
|
4c0802b52673
mod_bosh,mod_websocket: Make into global-shared modules (...again)
Kim Alvefur <zash@zash.se>
parents:
11560
diff
changeset
|
364 module:provides("http", { |
|
4c0802b52673
mod_bosh,mod_websocket: Make into global-shared modules (...again)
Kim Alvefur <zash@zash.se>
parents:
11560
diff
changeset
|
365 name = "websocket"; |
|
4c0802b52673
mod_bosh,mod_websocket: Make into global-shared modules (...again)
Kim Alvefur <zash@zash.se>
parents:
11560
diff
changeset
|
366 default_path = "xmpp-websocket"; |
|
12444
b33558969b3e
mod_http (and dependent modules): Make CORS opt-in by default (fixes #1731)
Matthew Wild <mwild1@gmail.com>
parents:
12263
diff
changeset
|
367 cors = { |
|
b33558969b3e
mod_http (and dependent modules): Make CORS opt-in by default (fixes #1731)
Matthew Wild <mwild1@gmail.com>
parents:
12263
diff
changeset
|
368 enabled = true; |
|
b33558969b3e
mod_http (and dependent modules): Make CORS opt-in by default (fixes #1731)
Matthew Wild <mwild1@gmail.com>
parents:
12263
diff
changeset
|
369 }; |
|
11771
4c0802b52673
mod_bosh,mod_websocket: Make into global-shared modules (...again)
Kim Alvefur <zash@zash.se>
parents:
11560
diff
changeset
|
370 route = { |
|
4c0802b52673
mod_bosh,mod_websocket: Make into global-shared modules (...again)
Kim Alvefur <zash@zash.se>
parents:
11560
diff
changeset
|
371 ["GET"] = handle_request; |
|
4c0802b52673
mod_bosh,mod_websocket: Make into global-shared modules (...again)
Kim Alvefur <zash@zash.se>
parents:
11560
diff
changeset
|
372 ["GET /"] = handle_request; |
|
4c0802b52673
mod_bosh,mod_websocket: Make into global-shared modules (...again)
Kim Alvefur <zash@zash.se>
parents:
11560
diff
changeset
|
373 }; |
|
4c0802b52673
mod_bosh,mod_websocket: Make into global-shared modules (...again)
Kim Alvefur <zash@zash.se>
parents:
11560
diff
changeset
|
374 }); |
|
4c0802b52673
mod_bosh,mod_websocket: Make into global-shared modules (...again)
Kim Alvefur <zash@zash.se>
parents:
11560
diff
changeset
|
375 |
|
13749
08c2b7accd94
mod_bosh,mod_websocket: Don't load mod_http_altconnect in global context
Kim Alvefur <zash@zash.se>
parents:
13720
diff
changeset
|
376 if module.host ~= "*" then |
|
08c2b7accd94
mod_bosh,mod_websocket: Don't load mod_http_altconnect in global context
Kim Alvefur <zash@zash.se>
parents:
13720
diff
changeset
|
377 module:depends("http_altconnect", true); |
|
08c2b7accd94
mod_bosh,mod_websocket: Don't load mod_http_altconnect in global context
Kim Alvefur <zash@zash.se>
parents:
13720
diff
changeset
|
378 end |
|
13720
c3c4281c1339
mod_bosh, mod_websocket: Add soft dependency on mod_http_altconnect
Matthew Wild <mwild1@gmail.com>
parents:
13213
diff
changeset
|
379 |
|
11771
4c0802b52673
mod_bosh,mod_websocket: Make into global-shared modules (...again)
Kim Alvefur <zash@zash.se>
parents:
11560
diff
changeset
|
380 module:hook("c2s-read-timeout", keepalive, -0.9); |
|
6397
6f75f8043936
mod_websocket: Initial commit (based on the prosody-modules version)
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
381 end |
|
11771
4c0802b52673
mod_bosh,mod_websocket: Make into global-shared modules (...again)
Kim Alvefur <zash@zash.se>
parents:
11560
diff
changeset
|
382 |
|
12977
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12894
diff
changeset
|
383 if require"prosody.core.modulemanager".get_modules_for_host("*"):contains(module.name) then |
|
12263
168970ce8543
mod_websocket: Only enable host-agnostic HTTP routing when enabled globally
Kim Alvefur <zash@zash.se>
parents:
11868
diff
changeset
|
384 module:add_host(); |
|
168970ce8543
mod_websocket: Only enable host-agnostic HTTP routing when enabled globally
Kim Alvefur <zash@zash.se>
parents:
11868
diff
changeset
|
385 end |