24
1
mirror of https://github.com/processone/ejabberd.git synced 2024-07-02 23:06:21 +02:00

Merge branch '2.1.x' of git+ssh://git@gitorious.process-one.net/ejabberd/mainline.git into 2.2.x

Conflicts:
	src/configure
	src/ejabberd.app
	src/ejabberd_receiver.erl
	src/tls/tls_drv.c
	src/web/ejabberd_http.erl
This commit is contained in:
Alexey Shchepin 2012-02-20 17:29:18 +02:00
commit 52df4fa024
15 changed files with 228 additions and 149 deletions

View File

@ -2,7 +2,7 @@
"http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>
<TITLE>Ejabberd 2.1.10 Developers Guide
<TITLE>Ejabberd 2.1.x Developers Guide
</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">
@ -49,7 +49,7 @@ TD P{margin:0px;}
<!--HEVEA command line is: /usr/bin/hevea -fix -pedantic dev.tex -->
<!--CUT DEF section 1 --><P><A NAME="titlepage"></A>
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.1.10 Developers Guide</H1><H3 CLASS="titlerest">Alexey Shchepin<BR>
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.1.x Developers Guide</H1><H3 CLASS="titlerest">Alexey Shchepin<BR>
<A HREF="mailto:alexey@sevcom.net"><TT>mailto:alexey@sevcom.net</TT></A><BR>
<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT></A></H3></TD></TR>
</TABLE><DIV CLASS="center">

View File

@ -2,7 +2,7 @@
"http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>
<TITLE>Ejabberd 2.1.10 Feature Sheet
<TITLE>Ejabberd 2.1.x Feature Sheet
</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">
@ -50,7 +50,7 @@ SPAN{width:20%; float:right; text-align:left; margin-left:auto;}
<!--HEVEA command line is: /usr/bin/hevea -fix -pedantic features.tex -->
<!--CUT DEF section 1 --><P><A NAME="titlepage"></A>
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.1.10 Feature Sheet</H1><H3 CLASS="titlerest">Sander Devrieze<BR>
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.1.x Feature Sheet</H1><H3 CLASS="titlerest">Sander Devrieze<BR>
<A HREF="mailto:s.devrieze@pandora.be"><TT>mailto:s.devrieze@pandora.be</TT></A><BR>
<A HREF="xmpp:sander@devrieze.dyndns.org"><TT>xmpp:sander@devrieze.dyndns.org</TT></A></H3></TD></TR>
</TABLE><DIV CLASS="center">

View File

@ -6,7 +6,7 @@
ejabberd 2.1.10
ejabberd 2.1.x
Installation and Operation Guide
@ -76,7 +76,7 @@ BLOCKQUOTE.figure DIV.center DIV.center HR{display:none;}
<HR SIZE=2><BR>
<BR>
<TABLE CELLSPACING=6 CELLPADDING=0><TR><TD ALIGN=right NOWRAP> <FONT SIZE=6><B>ejabberd 2.1.10 </B></FONT></TD></TR>
<TABLE CELLSPACING=6 CELLPADDING=0><TR><TD ALIGN=right NOWRAP> <FONT SIZE=6><B>ejabberd 2.1.x </B></FONT></TD></TR>
<TR><TD ALIGN=right NOWRAP>&nbsp;</TD></TR>
<TR><TD ALIGN=right NOWRAP> <FONT SIZE=6>Installation and Operation Guide</FONT></TD></TR>
</TABLE><BR>

View File

@ -829,7 +829,7 @@ The available modules, their purpose and the options allowed by each one are:
Options: \texttt{certfile}
\titem{\texttt{ejabberd\_http}}
Handles incoming HTTP connections.\\
Options: \texttt{captcha}, \texttt{certfile}, \texttt{http\_bind}, \texttt{http\_poll},
Options: \texttt{captcha}, \texttt{certfile}, \texttt{default\_host}, \texttt{http\_bind}, \texttt{http\_poll},
\texttt{request\_handlers}, \texttt{tls}, \texttt{trusted\_proxies}, \texttt{web\_admin}\\
\end{description}
@ -850,6 +850,11 @@ This is a detailed description of each option allowed by the listening modules:
Simple web page that allows a user to fill a CAPTCHA challenge (see section \ref{captcha}).
\titem{\{certfile, Path\}} Full path to a file containing the default SSL certificate.
To define a certificate file specific for a given domain, use the global option \term{domain\_certfile}.
\titem{\{default\_host, undefined|HostName\}}
If the HTTP request received by ejabberd contains the HTTP header \term{Host}
with an ambiguous virtual host that doesn't match any one defined in ejabberd (see \ref{hostnames}),
then this configured HostName is set as the request Host.
The default value of this option is: \term{undefined}.
\titem{\{hosts, [Hostname, ...], [HostOption, ...]\}} \ind{options!hosts}
The external Jabber component that connects to this \term{ejabberd\_service}
can serve one or more hostnames.
@ -1667,7 +1672,7 @@ The configurable options are:
\begin{description}
\titem{\{captcha\_cmd, Path\}}
Full path to a script that generates the image.
The default value is an empty string: \term{""}
The default value disables the feature: \term{undefined}
\titem{\{captcha\_host, ProtocolHostPort\}}
ProtocolHostPort is a string with the host, and optionally the Protocol and Port number.
It must identify where ejabberd listens for CAPTCHA requests.
@ -5882,6 +5887,7 @@ Thanks to all people who contributed to this guide:
\item Badlop (\ahrefurl{xmpp:badlop@jabberes.org})
\item Evgeniy Khramtsov (\ahrefurl{xmpp:xram@jabber.ru})
\item Florian Zumbiehl (\ahrefurl{xmpp:florz@florz.de})
\item Ludovic Bocquet (\ahrefurl{xmpp:lbocquet@jabber.org})
\item Marcin Owsiany (\ahrefurl{xmpp:marcin.owsiany@gmail.com})
\item Michael Grigutsch (\ahrefurl{xmpp:migri@jabber.i-pobox.net})
\item Mickael Remond (\ahrefurl{xmpp:mremond@process-one.net})

View File

@ -1,2 +1,2 @@
% ejabberd version (automatically generated).
\newcommand{\version}{2.1.10}
\newcommand{\version}{2.1.x}

View File

@ -89,19 +89,19 @@ change_shaper(Pid, Shaper) ->
gen_server:cast(Pid, {change_shaper, Shaper}).
reset_stream(Pid) ->
gen_server:call(Pid, reset_stream).
do_call(Pid, reset_stream).
starttls(Pid, TLSOpts) ->
starttls(Pid, TLSOpts, undefined).
starttls(Pid, TLSOpts, Data) ->
gen_server:call(Pid, {starttls, TLSOpts, Data}).
do_call(Pid, {starttls, TLSOpts, Data}).
compress(Pid, Data) ->
gen_server:call(Pid, {compress, Data}).
do_call(Pid, {compress, Data}).
become_controller(Pid, C2SPid) ->
gen_server:call(Pid, {become_controller, C2SPid}).
do_call(Pid, {become_controller, C2SPid}).
change_controller(Pid, C2SPid) ->
case catch gen_server:call(Pid, {change_controller, C2SPid}) of
@ -448,3 +448,11 @@ cancel_timer(TRef) when is_reference(TRef) ->
end;
cancel_timer(_) ->
ok.
do_call(Pid, Msg) ->
case catch gen_server:call(Pid, Msg) of
{'EXIT', Why} ->
{error, Why};
Res ->
Res
end.

View File

@ -101,6 +101,8 @@
[{"code", Code}, {"type", Type}],
[{xmlelement, Condition, [{"xmlns", ?NS_STANZAS}], []}]}).
-define(ERR_BAD_FORMAT,
?STANZA_ERROR("406", "modify", "bad-format")).
-define(ERR_BAD_REQUEST,
?STANZA_ERROR("400", "modify", "bad-request")).
-define(ERR_CONFLICT,
@ -155,6 +157,8 @@
{xmlelement, "text", [{"xmlns", ?NS_STANZAS}],
[{xmlcdata, translate:translate(Lang, Text)}]}]}).
-define(ERRT_BAD_FORMAT(Lang, Text),
?STANZA_ERRORT("406", "modify", "bad-format", Lang, Text)).
-define(ERRT_BAD_REQUEST(Lang, Text),
?STANZA_ERRORT("400", "modify", "bad-request", Lang, Text)).
-define(ERRT_CONFLICT(Lang, Text),

View File

@ -39,6 +39,11 @@
-record(private_storage, {usns, xml}).
-define(Xmlel_Query(Attrs, Children),
(
{xmlelement, "query", Attrs, Children}
)).
start(Host, Opts) ->
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
mnesia:create_table(private_storage,
@ -56,73 +61,97 @@ stop(Host) ->
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE).
process_sm_iq(From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
#jid{luser = LUser, lserver = LServer} = From,
case lists:member(LServer, ?MYHOSTS) of
true ->
{xmlelement, Name, Attrs, Els} = SubEl,
case Type of
set ->
F = fun() ->
lists:foreach(
fun(El) ->
set_data(LUser, LServer, El)
end, Els)
end,
mnesia:transaction(F),
IQ#iq{type = result,
sub_el = [{xmlelement, Name, Attrs, []}]};
get ->
case catch get_data(LUser, LServer, Els) of
{'EXIT', _Reason} ->
IQ#iq{type = error,
sub_el = [SubEl,
?ERR_INTERNAL_SERVER_ERROR]};
Res ->
IQ#iq{type = result,
sub_el = [{xmlelement, Name, Attrs, Res}]}
end
end;
false ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
process_sm_iq(#jid{luser = LUser, lserver = LServer},
#jid{luser = LUser, lserver = LServer}, IQ)
when IQ#iq.type == 'set' ->
case IQ#iq.sub_el of
{xmlelement, "query", _, Xmlels} ->
case filter_xmlels(Xmlels) of
[] ->
IQ#iq{
type = error,
sub_el = [IQ#iq.sub_el, ?ERR_NOT_ACCEPTABLE]
};
Data ->
mnesia:transaction(fun() ->
lists:foreach(fun
(Datum) ->
set_data(LUser, LServer, Datum)
end, Data)
end),
IQ#iq{type = result, sub_el = []}
end;
_ ->
IQ#iq{type = error, sub_el = [IQ#iq.sub_el, ?ERR_NOT_ACCEPTABLE]}
end;
%%
process_sm_iq(#jid{luser = LUser, lserver = LServer},
#jid{luser = LUser, lserver = LServer}, IQ)
when IQ#iq.type == 'get' ->
case IQ#iq.sub_el of
{xmlelement, "query", Attrs, Xmlels} ->
case filter_xmlels(Xmlels) of
[] ->
IQ#iq{
type = error,
sub_el = [IQ#iq.sub_el, ?ERR_BAD_FORMAT]
};
Data ->
case catch get_data(LUser, LServer, Data) of
{'EXIT', _Reason} ->
IQ#iq{
type = error,
sub_el = [IQ#iq.sub_el, ?ERR_INTERNAL_SERVER_ERROR]
};
Storage_Xmlels ->
IQ#iq{
type = result,
sub_el = [?Xmlel_Query(Attrs, Storage_Xmlels)]
}
end
end;
_ ->
IQ#iq{type = error, sub_el = [IQ#iq.sub_el, ?ERR_BAD_FORMAT]}
end;
%%
process_sm_iq(_From, _To, IQ) ->
IQ#iq{type = error, sub_el = [IQ#iq.sub_el, ?ERR_FORBIDDEN]}.
filter_xmlels(Xmlels) ->
filter_xmlels(Xmlels, []).
filter_xmlels([], Data) ->
lists:reverse(Data);
filter_xmlels([{xmlelement, _, Attrs, _} = Xmlel | Xmlels], Data) ->
case xml:get_attr_s("xmlns", Attrs) of
"" -> [];
XmlNS -> filter_xmlels(Xmlels, [{XmlNS, Xmlel} | Data])
end;
filter_xmlels([_ | Xmlels], Data) ->
filter_xmlels(Xmlels, Data).
set_data(LUser, LServer, {XmlNS, Xmlel}) ->
mnesia:write(#private_storage{
usns = {LUser, LServer, XmlNS},
xml = Xmlel
}).
get_data(LUser, LServer, Data) ->
get_data(LUser, LServer, Data, []).
get_data(_LUser, _LServer, [], Storage_Xmlels) ->
lists:reverse(Storage_Xmlels);
get_data(LUser, LServer, [{XmlNS, Xmlel} | Data], Storage_Xmlels) ->
case mnesia:dirty_read(private_storage, {LUser, LServer, XmlNS}) of
[#private_storage{xml = Storage_Xmlel}] ->
get_data(LUser, LServer, Data, [Storage_Xmlel | Storage_Xmlels]);
_ ->
get_data(LUser, LServer, Data, [Xmlel | Storage_Xmlels])
end.
set_data(LUser, LServer, El) ->
case El of
{xmlelement, _Name, Attrs, _Els} ->
XMLNS = xml:get_attr_s("xmlns", Attrs),
case XMLNS of
"" ->
ignore;
_ ->
mnesia:write(
#private_storage{usns = {LUser, LServer, XMLNS},
xml = El})
end;
_ ->
ignore
end.
get_data(LUser, LServer, Els) ->
get_data(LUser, LServer, Els, []).
get_data(_LUser, _LServer, [], Res) ->
lists:reverse(Res);
get_data(LUser, LServer, [El | Els], Res) ->
case El of
{xmlelement, _Name, Attrs, _} ->
XMLNS = xml:get_attr_s("xmlns", Attrs),
case mnesia:dirty_read(private_storage, {LUser, LServer, XMLNS}) of
[R] ->
get_data(LUser, LServer, Els,
[R#private_storage.xml | Res]);
[] ->
get_data(LUser, LServer, Els,
[El | Res])
end;
_ ->
get_data(LUser, LServer, Els, Res)
end.
remove_user(User, Server) ->
LUser = jlib:nodeprep(User),

View File

@ -631,7 +631,7 @@ add_user_to_group(Host, US, Group) ->
GroupOpts ++ MoreGroupOpts);
nomatch ->
%% Push this new user to members of groups where this group is displayed
push_user_to_displayed(LUser, LServer, Group, both),
push_user_to_displayed(LUser, LServer, Group, Host, both),
%% Push members of groups that are displayed to this group
push_displayed_to_user(LUser, LServer, Group, Host, both),
R = #sr_user{us = US, group_host = {Group, Host}},
@ -668,7 +668,7 @@ remove_user_from_group(Host, US, Group) ->
end,
Result = mnesia:transaction(F),
%% Push removal of the old user to members of groups where the group that this user was members was displayed
push_user_to_displayed(LUser, LServer, Group, remove),
push_user_to_displayed(LUser, LServer, Group, Host, remove),
%% Push removal of members of groups that where displayed to the group which this user has left
push_displayed_to_user(LUser, LServer, Group, Host, remove),
Result
@ -689,7 +689,7 @@ register_user(User, Server) ->
%% Get list of groups where this user is member
Groups = get_user_groups({User, Server}),
%% Push this user to members of groups where is displayed a group which this user is member
[push_user_to_displayed(User, Server, Group, both) || Group <- Groups].
[push_user_to_displayed(User, Server, Group, Server, both) || Group <- Groups].
remove_user(User, Server) ->
push_user_to_members(User, Server, remove).
@ -711,19 +711,19 @@ push_user_to_members(User, Server, Subscription) ->
end, get_group_users(LServer, Group, GroupOpts))
end, lists:usort(SpecialGroups++UserGroups)).
push_user_to_displayed(LUser, LServer, Group, Subscription) ->
GroupsOpts = groups_with_opts(LServer),
push_user_to_displayed(LUser, LServer, Group, Host, Subscription) ->
GroupsOpts = groups_with_opts(Host),
GroupOpts = proplists:get_value(Group, GroupsOpts, []),
GroupName = proplists:get_value(name, GroupOpts, Group),
DisplayedToGroupsOpts = displayed_to_groups(Group, LServer),
[push_user_to_group(LUser, LServer, GroupD, GroupName, Subscription) || {GroupD, _Opts} <- DisplayedToGroupsOpts].
DisplayedToGroupsOpts = displayed_to_groups(Group, Host),
[push_user_to_group(LUser, LServer, GroupD, Host, GroupName, Subscription) || {GroupD, _Opts} <- DisplayedToGroupsOpts].
push_user_to_group(LUser, LServer, Group, GroupName, Subscription) ->
push_user_to_group(LUser, LServer, Group, Host, GroupName, Subscription) ->
lists:foreach(
fun({U, S}) when (U == LUser) and (S == LServer) -> ok;
fun({U, S}) when (U == LUser) and (S == LServer) -> ok;
({U, S}) ->
push_roster_item(U, S, LUser, LServer, GroupName, Subscription)
end, get_group_users(LServer, Group)).
end, get_group_users(Host, Group)).
%% Get list of groups to which this group is displayed
displayed_to_groups(GroupName, LServer) ->
@ -819,7 +819,7 @@ user_available(New) ->
fun(OG) ->
?DEBUG("user_available: pushing ~p @ ~p grp ~p",
[LUser, LServer, OG ]),
push_user_to_displayed(LUser, LServer, OG, both)
push_user_to_displayed(LUser, LServer, OG, LServer, both)
end, OnlineGroups);
_ ->
ok
@ -840,7 +840,7 @@ unset_presence(LUser, LServer, Resource, Status) ->
fun(OG) ->
%% Push removal of the old user to members of groups
%% where the group that this uwas members was displayed
push_user_to_displayed(LUser, LServer, OG, remove),
push_user_to_displayed(LUser, LServer, OG, LServer, remove),
%% Push removal of members of groups that where
%% displayed to the group which thiuser has left
push_displayed_to_user(LUser, LServer, OG, LServer,remove)

View File

@ -219,17 +219,17 @@ set_vcard(User, LServer, VCARD) ->
end,
LUser = jlib:nodeprep(User),
LFN = string:to_lower(FN),
LFamily = string:to_lower(Family),
LGiven = string:to_lower(Given),
LMiddle = string:to_lower(Middle),
LNickname = string:to_lower(Nickname),
LBDay = string:to_lower(BDay),
LCTRY = string:to_lower(CTRY),
LLocality = string:to_lower(Locality),
LEMail = string:to_lower(EMail),
LOrgName = string:to_lower(OrgName),
LOrgUnit = string:to_lower(OrgUnit),
LFN = string2lower(FN),
LFamily = string2lower(Family),
LGiven = string2lower(Given),
LMiddle = string2lower(Middle),
LNickname = string2lower(Nickname),
LBDay = string2lower(BDay),
LCTRY = string2lower(CTRY),
LLocality = string2lower(Locality),
LEMail = string2lower(EMail),
LOrgName = string2lower(OrgName),
LOrgUnit = string2lower(OrgUnit),
US = {LUser, LServer},
@ -271,6 +271,12 @@ set_vcard(User, LServer, VCARD) ->
ejabberd_hooks:run(vcard_set, LServer, [LUser, LServer, VCARD])
end.
string2lower(String) ->
case stringprep:tolower(String) of
Lower when is_list(Lower) -> Lower;
error -> string:to_lower(String)
end.
-define(TLFIELD(Type, Label, Var),
{xmlelement, "field", [{"type", Type},
{"label", translate:translate(Lang, Label)},
@ -541,7 +547,7 @@ filter_fields([], Match, _LServer) ->
Match;
filter_fields([{SVar, [Val]} | Ds], Match, LServer)
when is_list(Val) and (Val /= "") ->
LVal = string:to_lower(Val),
LVal = string2lower(Val),
NewMatch = case SVar of
"user" ->
case gen_mod:get_module_opt(LServer, ?MODULE,
@ -618,17 +624,17 @@ set_vcard_t(R, _) ->
OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
{LUser, _LServer} = US,
LFN = string:to_lower(FN),
LFamily = string:to_lower(Family),
LGiven = string:to_lower(Given),
LMiddle = string:to_lower(Middle),
LNickname = string:to_lower(Nickname),
LBDay = string:to_lower(BDay),
LCTRY = string:to_lower(CTRY),
LLocality = string:to_lower(Locality),
LEMail = string:to_lower(EMail),
LOrgName = string:to_lower(OrgName),
LOrgUnit = string:to_lower(OrgUnit),
LFN = string2lower(FN),
LFamily = string2lower(Family),
LGiven = string2lower(Given),
LMiddle = string2lower(Middle),
LNickname = string2lower(Nickname),
LBDay = string2lower(BDay),
LCTRY = string2lower(CTRY),
LLocality = string2lower(Locality),
LEMail = string2lower(EMail),
LOrgName = string2lower(OrgName),
LOrgUnit = string2lower(OrgUnit),
if
(LUser == error) or

View File

@ -186,17 +186,17 @@ set_vcard(User, LServer, VCARD) ->
end,
LUser = jlib:nodeprep(User),
LFN = string:to_lower(FN),
LFamily = string:to_lower(Family),
LGiven = string:to_lower(Given),
LMiddle = string:to_lower(Middle),
LNickname = string:to_lower(Nickname),
LBDay = string:to_lower(BDay),
LCTRY = string:to_lower(CTRY),
LLocality = string:to_lower(Locality),
LEMail = string:to_lower(EMail),
LOrgName = string:to_lower(OrgName),
LOrgUnit = string:to_lower(OrgUnit),
LFN = string2lower(FN),
LFamily = string2lower(Family),
LGiven = string2lower(Given),
LMiddle = string2lower(Middle),
LNickname = string2lower(Nickname),
LBDay = string2lower(BDay),
LCTRY = string2lower(CTRY),
LLocality = string2lower(Locality),
LEMail = string2lower(EMail),
LOrgName = string2lower(OrgName),
LOrgUnit = string2lower(OrgUnit),
if
(LUser == error) or
@ -252,6 +252,12 @@ set_vcard(User, LServer, VCARD) ->
ejabberd_hooks:run(vcard_set, LServer, [LUser, LServer, VCARD])
end.
string2lower(String) ->
case stringprep:tolower(String) of
Lower when is_list(Lower) -> Lower;
error -> string:to_lower(String)
end.
-define(TLFIELD(Type, Label, Var),
{xmlelement, "field", [{"type", Type},
{"label", translate:translate(Lang, Label)},
@ -531,7 +537,7 @@ filter_fields([], Match, _LServer) ->
end;
filter_fields([{SVar, [Val]} | Ds], Match, LServer)
when is_list(Val) and (Val /= "") ->
LVal = string:to_lower(Val),
LVal = string2lower(Val),
NewMatch = case SVar of
"user" -> make_val(Match, "lusername", LVal);
"fn" -> make_val(Match, "lfn", LVal);

View File

@ -575,7 +575,7 @@ escape($\n) -> "\\n";
escape($\t) -> "\\t";
escape($\b) -> "\\b";
escape($\r) -> "\\r";
escape($') -> "\\'";
escape($') -> "''";
escape($") -> "\\\"";
escape($\\) -> "\\\\";
escape(C) -> C.

View File

@ -433,30 +433,37 @@ static ErlDrvSSizeT tls_drv_control(ErlDrvData handle,
die_unless(SSL_get_error(d->ssl, res) == SSL_ERROR_WANT_READ,
"SSL_do_handshake failed");
}
rlen = 1;
b = driver_alloc_binary(rlen + BUF_SIZE);
b->orig_bytes[0] = 0;
if (SSL_is_init_finished(d->ssl)) {
size = BUF_SIZE + 1;
rlen = 1;
b = driver_alloc_binary(size);
b->orig_bytes[0] = 0;
while ((res = SSL_read(d->ssl,
b->orig_bytes + rlen, BUF_SIZE)) > 0)
{
//printf("%d bytes of decrypted data read from state machine\r\n",res);
rlen += res;
b = driver_realloc_binary(b, rlen + BUF_SIZE);
}
while ((res = SSL_read(d->ssl,
b->orig_bytes + rlen, BUF_SIZE)) > 0)
{
//printf("%d bytes of decrypted data read from state machine\r\n",res);
rlen += res;
size += BUF_SIZE;
b = driver_realloc_binary(b, size);
}
if (res < 0)
{
int err = SSL_get_error(d->ssl, res);
if (res < 0)
{
int err = SSL_get_error(d->ssl, res);
if (err != SSL_ERROR_WANT_READ)
{
// TODO
}
}
b = driver_realloc_binary(b, rlen);
*rbuf = (char *)b;
return rlen;
if (err == SSL_ERROR_WANT_READ)
{
//printf("SSL_read wants more data\r\n");
//return 0;
}
// TODO
}
b = driver_realloc_binary(b, rlen);
*rbuf = (char *)b;
return rlen;
}
break;
case GET_PEER_CERTIFICATE:
cert = SSL_get_peer_certificate(d->ssl);
if (cert == NULL)

View File

@ -65,6 +65,7 @@
request_tp,
request_headers = [],
end_of_request = false,
default_host,
trail = "",
websocket_handlers = []
}).
@ -145,9 +146,11 @@ init({SockMod, Socket}, Opts) ->
false -> []
end,
?DEBUG("WS: ~p~n", [WebSocketHandlers]),
DefaultHost = gen_mod:get_opt(default_host, Opts, undefined),
?INFO_MSG("started: ~p", [{SockMod1, Socket1}]),
State = #state{sockmod = SockMod1,
socket = Socket1,
default_host = DefaultHost,
request_handlers = RequestHandlers,
websocket_handlers = WebSocketHandlers},
receive_headers(State).
@ -278,8 +281,9 @@ process_header(State, Data) ->
[State#state.socket,
State#state.request_method,
element(2, State#state.request_path)]),
{Host, Port, TP} = get_transfer_protocol(SockMod,
{HostProvided, Port, TP} = get_transfer_protocol(SockMod,
State#state.request_host),
Host = get_host_really_served(State#state.default_host, HostProvided),
State2 = State#state{request_host = Host,
request_port = Port,
request_tp = TP},
@ -316,6 +320,15 @@ add_header(Name, Value, State) ->
{value, {Param, V}} -> V;
false -> undefined
end).
get_host_really_served(undefined, Provided) ->
Provided;
get_host_really_served(Default, Provided) ->
case lists:member(Provided, ?MYHOSTS) of
true -> Provided;
false -> Default
end.
%% @spec (SockMod, HostPort) -> {Host::string(), Port::integer(), TP}
%% where
%% SockMod = gen_tcp | tls

View File

@ -1,7 +1,7 @@
%%%----------------------------------------------------------------------
%%% File : ejabberd_http_bind.erl
%%% Author : Stefan Strigler <steve@zeank.in-berlin.de>
%%% Purpose : Implements XMPP over BOSH (XEP-0205) (formerly known as
%%% Purpose : Implements XMPP over BOSH (XEP-0206) (formerly known as
%%% HTTP Binding)
%%% Created : 21 Sep 2005 by Stefan Strigler <steve@zeank.in-berlin.de>
%%% Modified: may 2009 by Mickael Remond, Alexey Schepin