2009-06-16 19:43:35 +02:00
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
%%% File : mod_http_bind.erl
|
|
|
|
%%% Author : Stefan Strigler <steve@zeank.in-berlin.de>
|
|
|
|
%%% Purpose : Implementation of XMPP over BOSH (XEP-0206)
|
|
|
|
%%% Created : Tue Feb 20 13:15:52 CET 2007
|
2009-06-16 19:48:27 +02:00
|
|
|
%%%
|
|
|
|
%%%
|
2011-02-14 13:47:22 +01:00
|
|
|
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne
|
2009-06-16 19:48:27 +02:00
|
|
|
%%%
|
|
|
|
%%% This program is free software; you can redistribute it and/or
|
|
|
|
%%% modify it under the terms of the GNU General Public License as
|
|
|
|
%%% published by the Free Software Foundation; either version 2 of the
|
|
|
|
%%% License, or (at your option) any later version.
|
|
|
|
%%%
|
|
|
|
%%% This program is distributed in the hope that it will be useful,
|
|
|
|
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
%%% General Public License for more details.
|
|
|
|
%%%
|
|
|
|
%%% You should have received a copy of the GNU General Public License
|
|
|
|
%%% along with this program; if not, write to the Free Software
|
|
|
|
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
|
|
%%% 02111-1307 USA
|
|
|
|
%%%
|
2009-06-16 19:43:35 +02:00
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
|
|
|
|
%%%----------------------------------------------------------------------
|
2009-06-16 19:48:27 +02:00
|
|
|
%%% This module acts as a bridge to ejabberd_http_bind which implements
|
2009-06-16 19:43:35 +02:00
|
|
|
%%% the real stuff, this is to handle the new pluggable architecture for
|
2009-06-16 19:48:27 +02:00
|
|
|
%%% extending ejabberd's http service.
|
2009-06-16 19:43:35 +02:00
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
|
|
|
|
-module(mod_http_bind).
|
|
|
|
-author('steve@zeank.in-berlin.de').
|
|
|
|
|
2009-06-16 19:44:04 +02:00
|
|
|
%%-define(ejabberd_debug, true).
|
2009-06-16 19:43:35 +02:00
|
|
|
|
|
|
|
-behaviour(gen_mod).
|
|
|
|
|
|
|
|
-export([
|
2009-06-16 19:44:38 +02:00
|
|
|
start/2,
|
|
|
|
stop/1,
|
|
|
|
process/2
|
2009-06-16 19:43:35 +02:00
|
|
|
]).
|
|
|
|
|
2009-11-23 16:22:45 +01:00
|
|
|
-include_lib("exmpp/include/exmpp.hrl").
|
2009-06-16 19:43:35 +02:00
|
|
|
-include("ejabberd.hrl").
|
|
|
|
-include("jlib.hrl").
|
|
|
|
-include("ejabberd_http.hrl").
|
2010-02-15 22:39:32 +01:00
|
|
|
-include("http_bind.hrl").
|
2009-06-16 19:43:35 +02:00
|
|
|
|
2010-11-17 20:29:36 +01:00
|
|
|
-define(PROCNAME_MHB, ejabberd_mod_http_bind).
|
|
|
|
|
2009-06-16 19:47:47 +02:00
|
|
|
%% Duplicated from ejabberd_http_bind.
|
|
|
|
%% TODO: move to hrl file.
|
2010-06-07 13:44:55 +02:00
|
|
|
-record(http_bind, {id, pid, to, hold, wait, process_delay, version}).
|
2009-06-16 19:43:35 +02:00
|
|
|
|
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
%%% API
|
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
|
|
|
|
process([], #request{method = 'POST',
|
|
|
|
data = []}) ->
|
|
|
|
?DEBUG("Bad Request: no data", []),
|
2010-02-15 22:39:32 +01:00
|
|
|
{400, ?HEADER, #xmlel{name = h1, children =
|
|
|
|
[#xmlcdata{cdata = <<"400 Bad Request">>}]}};
|
2009-06-16 19:43:35 +02:00
|
|
|
process([], #request{method = 'POST',
|
2009-06-16 19:46:51 +02:00
|
|
|
data = Data,
|
|
|
|
ip = IP}) ->
|
2009-06-16 19:44:04 +02:00
|
|
|
?DEBUG("Incoming data: ~s", [Data]),
|
2009-06-16 19:46:51 +02:00
|
|
|
ejabberd_http_bind:process_request(Data, IP);
|
2009-06-16 19:43:35 +02:00
|
|
|
process([], #request{method = 'GET',
|
|
|
|
data = []}) ->
|
2010-02-15 22:39:32 +01:00
|
|
|
{200, ?HEADER, get_human_html_xmlel()};
|
|
|
|
process([], #request{method = 'OPTIONS',
|
|
|
|
data = []}) ->
|
|
|
|
{200, ?OPTIONS_HEADER, []};
|
2009-06-16 19:43:35 +02:00
|
|
|
process(_Path, _Request) ->
|
|
|
|
?DEBUG("Bad Request: ~p", [_Request]),
|
2010-02-15 22:39:32 +01:00
|
|
|
{400, ?HEADER, #xmlel{name = h1, children =
|
|
|
|
[#xmlcdata{cdata = <<"400 Bad Request">>}]}}.
|
2009-06-16 19:43:35 +02:00
|
|
|
|
2009-11-23 16:22:45 +01:00
|
|
|
get_human_html_xmlel() ->
|
2010-07-26 20:20:15 +02:00
|
|
|
Heading = list_to_binary("ejabberd " ++ atom_to_list(?MODULE)),
|
2009-11-23 16:22:45 +01:00
|
|
|
H = #xmlel{name = h1, children = [#xmlcdata{cdata = Heading}]},
|
|
|
|
Par1 = #xmlel{name = p, children =
|
|
|
|
[#xmlcdata{cdata = <<"An implementation of ">>},
|
|
|
|
#xmlel{name = a,
|
2010-11-29 20:44:31 +01:00
|
|
|
attrs = [#xmlattr{name = <<"href">>, value = <<"http://xmpp.org/extensions/xep-0206.html">>}],
|
2009-11-23 16:22:45 +01:00
|
|
|
children = [#xmlcdata{cdata = <<"XMPP over BOSH (XEP-0206)">>}]
|
|
|
|
}
|
|
|
|
]},
|
|
|
|
Par2 = #xmlel{name = p, children =
|
|
|
|
[#xmlcdata{cdata = <<"This web page is only informative. "
|
|
|
|
"To use HTTP-Bind you need a Jabber/XMPP client that supports it.">>}
|
|
|
|
]},
|
|
|
|
#xmlel{name = html,
|
2010-11-29 20:44:31 +01:00
|
|
|
attrs = [#xmlattr{name = <<"xmlns">>, value= <<"http://www.w3.org/1999/xhtml">>}],
|
2009-11-23 16:22:45 +01:00
|
|
|
children =
|
|
|
|
[#xmlel{name = head, children = [#xmlel{name = title, children = [#xmlcdata{cdata = Heading}]}]},
|
|
|
|
#xmlel{name = body, children = [H, Par1, Par2]}]}.
|
2009-06-16 19:44:13 +02:00
|
|
|
|
2009-06-16 19:43:35 +02:00
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
%%% BEHAVIOUR CALLBACKS
|
|
|
|
%%%----------------------------------------------------------------------
|
2011-07-15 02:50:45 +02:00
|
|
|
start(Host, Opts) when is_list(Host) ->
|
|
|
|
start(list_to_binary(Host), Opts);
|
|
|
|
start(HostB, _Opts) ->
|
2009-06-16 19:47:47 +02:00
|
|
|
setup_database(),
|
2011-07-15 02:50:45 +02:00
|
|
|
Proc = gen_mod:get_module_proc(HostB, ?PROCNAME_MHB),
|
2010-11-17 20:29:36 +01:00
|
|
|
ChildSpec =
|
|
|
|
{Proc,
|
2009-06-16 19:44:00 +02:00
|
|
|
{ejabberd_tmp_sup, start_link,
|
2010-11-17 20:29:36 +01:00
|
|
|
[Proc, ejabberd_http_bind]},
|
2009-06-16 19:44:00 +02:00
|
|
|
permanent,
|
|
|
|
infinity,
|
|
|
|
supervisor,
|
|
|
|
[ejabberd_tmp_sup]},
|
2010-11-17 20:29:36 +01:00
|
|
|
supervisor:start_child(ejabberd_sup, ChildSpec).
|
2009-06-16 19:43:35 +02:00
|
|
|
|
2010-11-17 20:29:36 +01:00
|
|
|
stop(Host) ->
|
|
|
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME_MHB),
|
|
|
|
supervisor:terminate_child(ejabberd_sup, Proc),
|
|
|
|
supervisor:delete_child(ejabberd_sup, Proc).
|
2009-06-16 19:47:47 +02:00
|
|
|
|
|
|
|
setup_database() ->
|
|
|
|
migrate_database(),
|
|
|
|
mnesia:create_table(http_bind,
|
|
|
|
[{ram_copies, [node()]},
|
2010-06-02 16:01:36 +02:00
|
|
|
{local_content, true},
|
|
|
|
{attributes, record_info(fields, http_bind)}]),
|
|
|
|
mnesia:add_table_copy(http_bind, node(), ram_copies).
|
2009-06-16 19:47:47 +02:00
|
|
|
|
|
|
|
migrate_database() ->
|
|
|
|
case catch mnesia:table_info(http_bind, attributes) of
|
2010-06-07 13:44:55 +02:00
|
|
|
[id, pid, to, hold, wait, process_delay, version] ->
|
2009-06-16 19:47:47 +02:00
|
|
|
ok;
|
|
|
|
_ ->
|
|
|
|
%% Since the stored information is not important, instead
|
|
|
|
%% of actually migrating data, let's just destroy the table
|
|
|
|
mnesia:delete_table(http_bind)
|
2010-06-02 16:01:36 +02:00
|
|
|
end,
|
|
|
|
case catch mnesia:table_info(http_bind, local_content) of
|
|
|
|
false ->
|
|
|
|
mnesia:delete_table(http_bind);
|
|
|
|
_ ->
|
|
|
|
ok
|
2009-06-16 19:47:47 +02:00
|
|
|
end.
|