27
28
34
35 -module(mod_http_bind).
36
37 -author('[email protected]').
38
39
41
42 -behaviour(gen_mod).
43
44 -export([start/2, stop/1, process/2]).
45
46 -include_lib("exmpp/include/exmpp.hrl").
47
48 -include("ejabberd.hrl").
49
50 -include("jlib.hrl").
51
52 -include("ejabberd_http.hrl").
53
54 -include("http_bind.hrl").
55
56 -define(PROCNAME_MHB, ejabberd_mod_http_bind).
57
58
59
60 -record(http_bind, {id, pid, to, hold, wait, process_delay, version}).
61
62
66
67 process([], #request{method = 'POST', data = []}) ->
68 ?DEBUG("Bad Request: no data", []),
69 {400, ?HEADER,
70 #xmlel{name = h1,
71 children = [#xmlcdata{cdata = <<"400 Bad Request">>}]}};
72 process([], #request{method = 'POST', data = Data, ip = IP}) ->
73 ?DEBUG("Incoming data: ~s", [Data]), ejabberd_http_bind:process_request(Data, IP);
74 process([], #request{method = 'GET', data = []}) ->
75 {200, ?HEADER, get_human_html_xmlel()};
76 process([], #request{method = 'OPTIONS', data = []}) -> {200, ?OPTIONS_HEADER, []};
77 process(_Path, _Request) ->
78 ?DEBUG("Bad Request: ~p", [_Request]),
79 {400, ?HEADER,
80 #xmlel{name = h1,
81 children = [#xmlcdata{cdata = <<"400 Bad Request">>}]}}.
82
83 get_human_html_xmlel() ->
84 Heading = list_to_binary("ejabberd " ++ atom_to_list(?MODULE)),
85 H = #xmlel{name = h1, children = [#xmlcdata{cdata = Heading}]},
86 Par1 = #xmlel{name = p,
87 children =
88 [#xmlcdata{cdata = <<"An implementation of ">>},
89 #xmlel{name = a,
90 attrs =
91 [#xmlattr{name = <<"href">>,
92 value =
93 <<"http://xmpp.org/extensions/xep-0206.html">>}],
94 children =
95 [#xmlcdata{cdata =
96 <<"XMPP over BOSH (XEP-0206)">>}]}]},
97 Par2 = #xmlel{name = p,
98 children =
99 [#xmlcdata{cdata =
100 <<"This web page is only informative. To use HTTP-Bind you need a Jabber/XMPP client that supports it.">>}]},
101 #xmlel{name = html,
102 attrs =
103 [#xmlattr{name = <<"xmlns">>,
104 value = <<"http://www.w3.org/1999/xhtml">>}],
105 children =
106 [#xmlel{name = head,
107 children =
108 [#xmlel{name = title,
109 children = [#xmlcdata{cdata = Heading}]}]},
110 #xmlel{name = body, children = [H, Par1, Par2]}]}.
111
112
113
114
115 start(Host, Opts) when is_list(Host) -> start(list_to_binary(Host), Opts);
116 start(HostB, _Opts) ->
117 setup_database(),
118 Proc = gen_mod:get_module_proc(HostB, ?PROCNAME_MHB),
119 ChildSpec = {Proc, {ejabberd_tmp_sup, start_link, [Proc, ejabberd_http_bind]},
120 permanent, infinity, supervisor, [ejabberd_tmp_sup]},
121 supervisor:start_child(ejabberd_sup, ChildSpec).
122
123 stop(Host) ->
124 Proc = gen_mod:get_module_proc(Host, ?PROCNAME_MHB),
125 supervisor:terminate_child(ejabberd_sup, Proc),
126 supervisor:delete_child(ejabberd_sup, Proc).
127
128 setup_database() ->
129 migrate_database(),
130 mnesia:create_table(http_bind,
131 [{ram_copies, [node()]}, {local_content, true},
132 {attributes, record_info(fields, http_bind)}]),
133 mnesia:add_table_copy(http_bind, node(), ram_copies).
134
135 migrate_database() ->
136 case catch mnesia:table_info(http_bind, attributes) of
137 [id, pid, to, hold, wait, process_delay, version] -> ok;
138 _ ->
139
140
141 mnesia:delete_table(http_bind)
142 end,
143 case catch mnesia:table_info(http_bind, local_content) of
144 false -> mnesia:delete_table(http_bind);
145 _ -> ok
146 end.