Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/processone/ejabberd.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Shchepin <alexey@process-one.net>2006-04-22 07:35:13 +0400
committerAlexey Shchepin <alexey@process-one.net>2006-04-22 07:35:13 +0400
commitc4b976881ebcc554cba65147899b57c30144b6e2 (patch)
treeb585e77c58acfcbecbbb74202cb30a7363154477
parente0c700e725aedaca0316aab43eb170e033284654 (diff)
* src/msgs/pt-br.msg: Updated (thanks to Lucius Curado)
* src/xml_stream.erl: Support for stanza size limit (thanks to Igor Goryachev) * src/ejabberd_receiver.erl: Likewise * src/ejabberd_c2s.erl: Likewise * src/ejabberd_s2s_in.erl: Likewise * src/ejabberd.cfg.example: Updated * src/ejabberd_auth.erl: Fixed try_register/3 behaviour SVN Revision: 537
-rw-r--r--ChangeLog17
-rw-r--r--src/ejabberd_auth.erl22
-rw-r--r--src/ejabberd_c2s.erl11
-rw-r--r--src/ejabberd_receiver.erl37
-rw-r--r--src/ejabberd_s2s_in.erl8
-rw-r--r--src/msgs/pt-br.msg158
-rw-r--r--src/xml_stream.erl41
7 files changed, 251 insertions, 43 deletions
diff --git a/ChangeLog b/ChangeLog
index 265c64de6..12e777f8e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2006-04-22 Alexey Shchepin <alexey@sevcom.net>
+
+ * src/msgs/pt-br.msg: Updated (thanks to Lucius Curado)
+
+ * src/xml_stream.erl: Support for stanza size limit (thanks to
+ Igor Goryachev)
+ * src/ejabberd_receiver.erl: Likewise
+ * src/ejabberd_c2s.erl: Likewise
+ * src/ejabberd_s2s_in.erl: Likewise
+ * src/ejabberd.cfg.example: Updated
+
+ * src/ejabberd_auth.erl: Fixed try_register/3 behaviour
+
2006-04-20 Mickael Remond <mickael.remond@process-one.net>
* src/ejabberd.cfg.example: Update of the example for anonymous.
@@ -5,8 +18,8 @@
* src/ejabberd_auth_anonymous.erl: Removed unnecessary parameter /
bugfix.
* src/ejabberd_auth.erl: Bugfix: We now are forced to check is an
- anonymous user is log under a given user name before trying to register
- it.
+ anonymous user is log under a given user name before trying to
+ register it.
* doc/guide.tex: Updated (SASL anonymous and anonymous login).
2006-04-19 Alexey Shchepin <alexey@sevcom.net>
diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl
index e7316ec55..f2c3f4b50 100644
--- a/src/ejabberd_auth.erl
+++ b/src/ejabberd_auth.erl
@@ -75,17 +75,21 @@ set_password(User, Server, Password) ->
end, {error, not_allowed}, auth_modules(Server)).
try_register(User, Server, Password) ->
- case lists:member(jlib:nameprep(Server), ?MYHOSTS) and
- not is_user_exists(User,Server) of
+ case is_user_exists(User,Server) of
true ->
- lists:foldl(
- fun(_M, {atomic, ok} = Res) ->
- Res;
- (M, _) ->
- M:try_register(User, Server, Password)
- end, {error, not_allowed}, auth_modules(Server));
+ {atomic, exists};
false ->
- {error, not_allowed}
+ case lists:member(jlib:nameprep(Server), ?MYHOSTS) of
+ true ->
+ lists:foldl(
+ fun(_M, {atomic, ok} = Res) ->
+ Res;
+ (M, _) ->
+ M:try_register(User, Server, Password)
+ end, {error, not_allowed}, auth_modules(Server));
+ false ->
+ {error, not_allowed}
+ end
end.
%% Registered users list do not include anonymous users logged
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index b9a940d98..1b2639b86 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -127,6 +127,11 @@ init([{SockMod, Socket}, Opts]) ->
{value, {_, S}} -> S;
_ -> none
end,
+ MaxStanzaSize =
+ case lists:keysearch(max_stanza_size, 1, Opts) of
+ {value, {_, Size}} -> Size;
+ _ -> infinity
+ end,
Zlib = lists:member(zlib, Opts),
StartTLS = lists:member(starttls, Opts),
StartTLSRequired = lists:member(starttls_required, Opts),
@@ -139,10 +144,12 @@ init([{SockMod, Socket}, Opts]) ->
if
TLSEnabled ->
{ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
- RecPid = ejabberd_receiver:start(TLSSocket, tls, none),
+ RecPid = ejabberd_receiver:start(
+ TLSSocket, tls, none, MaxStanzaSize),
{tls, TLSSocket, RecPid};
true ->
- RecPid = ejabberd_receiver:start(Socket, SockMod, none),
+ RecPid = ejabberd_receiver:start(
+ Socket, SockMod, none, MaxStanzaSize),
{SockMod, Socket, RecPid}
end,
{ok, wait_for_stream, #state{socket = Socket1,
diff --git a/src/ejabberd_receiver.erl b/src/ejabberd_receiver.erl
index 03618b520..9591bd9c0 100644
--- a/src/ejabberd_receiver.erl
+++ b/src/ejabberd_receiver.erl
@@ -13,8 +13,9 @@
-behaviour(gen_server).
%% API
--export([start_link/4,
+-export([start_link/5,
start/3,
+ start/4,
change_shaper/2,
reset_stream/1,
starttls/2,
@@ -32,6 +33,7 @@
sock_mod,
shaper_state,
c2s_pid,
+ max_stanza_size,
xml_stream_state,
timeout}).
@@ -42,16 +44,21 @@
%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
%% Description: Starts the server
%%--------------------------------------------------------------------
-start_link(Socket, SockMod, Shaper, C2SPid) ->
- gen_server:start_link(?MODULE, [Socket, SockMod, Shaper, C2SPid], []).
+start_link(Socket, SockMod, Shaper, MaxStanzaSize, C2SPid) ->
+ gen_server:start_link(
+ ?MODULE, [Socket, SockMod, Shaper, MaxStanzaSize, C2SPid], []).
%%--------------------------------------------------------------------
%% Function: start() -> {ok,Pid} | ignore | {error,Error}
%% Description: Starts the server
%%--------------------------------------------------------------------
start(Socket, SockMod, Shaper) ->
- {ok, Pid} = supervisor:start_child(ejabberd_receiver_sup,
- [Socket, SockMod, Shaper, self()]),
+ start(Socket, SockMod, Shaper, infinity).
+
+start(Socket, SockMod, Shaper, MaxStanzaSize) ->
+ {ok, Pid} = supervisor:start_child(
+ ejabberd_receiver_sup,
+ [Socket, SockMod, Shaper, MaxStanzaSize, self()]),
Pid.
change_shaper(Pid, Shaper) ->
@@ -83,8 +90,8 @@ close(Pid) ->
%% {stop, Reason}
%% Description: Initiates the server
%%--------------------------------------------------------------------
-init([Socket, SockMod, Shaper, C2SPid]) ->
- XMLStreamState = xml_stream:new(C2SPid),
+init([Socket, SockMod, Shaper, MaxStanzaSize, C2SPid]) ->
+ XMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
ShaperState = shaper:new(Shaper),
Timeout = case SockMod of
ssl ->
@@ -96,6 +103,7 @@ init([Socket, SockMod, Shaper, C2SPid]) ->
sock_mod = SockMod,
shaper_state = ShaperState,
c2s_pid = C2SPid,
+ max_stanza_size = MaxStanzaSize,
xml_stream_state = XMLStreamState,
timeout = Timeout}}.
@@ -110,9 +118,10 @@ init([Socket, SockMod, Shaper, C2SPid]) ->
%%--------------------------------------------------------------------
handle_call({starttls, TLSSocket}, _From,
#state{xml_stream_state = XMLStreamState,
- c2s_pid = C2SPid} = State) ->
+ c2s_pid = C2SPid,
+ max_stanza_size = MaxStanzaSize} = State) ->
xml_stream:close(XMLStreamState),
- NewXMLStreamState = xml_stream:new(C2SPid),
+ NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
NewState = State#state{socket = TLSSocket,
sock_mod = tls,
xml_stream_state = NewXMLStreamState},
@@ -124,9 +133,10 @@ handle_call({starttls, TLSSocket}, _From,
end;
handle_call({compress, ZlibSocket}, _From,
#state{xml_stream_state = XMLStreamState,
- c2s_pid = C2SPid} = State) ->
+ c2s_pid = C2SPid,
+ max_stanza_size = MaxStanzaSize} = State) ->
xml_stream:close(XMLStreamState),
- NewXMLStreamState = xml_stream:new(C2SPid),
+ NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
NewState = State#state{socket = ZlibSocket,
sock_mod = ejabberd_zlib,
xml_stream_state = NewXMLStreamState},
@@ -138,9 +148,10 @@ handle_call({compress, ZlibSocket}, _From,
end;
handle_call(reset_stream, _From,
#state{xml_stream_state = XMLStreamState,
- c2s_pid = C2SPid} = State) ->
+ c2s_pid = C2SPid,
+ max_stanza_size = MaxStanzaSize} = State) ->
xml_stream:close(XMLStreamState),
- NewXMLStreamState = xml_stream:new(C2SPid),
+ NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
Reply = ok,
{reply, Reply, State#state{xml_stream_state = NewXMLStreamState}};
handle_call(become_controller, _From, State) ->
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 0f07ad4dd..ec6b4ddea 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -104,11 +104,17 @@ become_controller(Pid) ->
%%----------------------------------------------------------------------
init([{SockMod, Socket}, Opts]) ->
?INFO_MSG("started: ~p", [{SockMod, Socket}]),
- ReceiverPid = ejabberd_receiver:start(Socket, SockMod, none),
Shaper = case lists:keysearch(shaper, 1, Opts) of
{value, {_, S}} -> S;
_ -> none
end,
+ MaxStanzaSize =
+ case lists:keysearch(max_stanza_size, 1, Opts) of
+ {value, {_, Size}} -> Size;
+ _ -> infinity
+ end,
+ ReceiverPid = ejabberd_receiver:start(
+ Socket, SockMod, none, MaxStanzaSize),
StartTLS = case ejabberd_config:get_local_option(s2s_use_starttls) of
undefined ->
false;
diff --git a/src/msgs/pt-br.msg b/src/msgs/pt-br.msg
index de179e493..371911e44 100644
--- a/src/msgs/pt-br.msg
+++ b/src/msgs/pt-br.msg
@@ -1,6 +1,6 @@
% $Id$
% Brazilian Portuguese translation
-% Author: Victor Hugo dos Santos
+% Authors: Victor Hugo dos Santos, Lucius Curado
@@ -73,9 +73,9 @@
{"Birthday","Aniversário"}.
{"City", "Cidade"}.
{"Country","País"}.
-{"ejabberd vCard module\nCopyright (c) 2003-2005 Alexey Shchepin", "Módulo vCard para ejabberd\nCopyright (c) 2002-2005 Alexey Shchepin"}.
+{"ejabberd vCard module\nCopyright (c) 2003-2006 Alexey Shchepin", "Módulo vCard para ejabberd\nCopyright (c) 2002-2006 Alexey Shchepin"}.
{"email", "e-mail"}.
-{"Erlang Jabber Server\nCopyright (c) 2002-2005 Alexey Shchepin", "Servidor Jabber em Erlang\nCopyright (c) 2002-2005 Alexey Shchepin"}.
+{"Erlang Jabber Server\nCopyright (c) 2002-2006 Alexey Shchepin", "Servidor Jabber em Erlang\nCopyright (c) 2002-2006 Alexey Shchepin"}.
{"Family Name", "Nome de família"}.
{"Fill in fields to search for any matching Jabber User", "Preencha os campos para procurar usuários Jabber coincidentes"}.
{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)", "Preencha o formulário para buscar usuários Jabber. Agrega * ao final de um campo para buscar sub-palavras."}.
@@ -94,7 +94,7 @@
{[], " "}.
{"Deliver payloads with event notifications", "Enviar payloads junto com as notificações de eventos"}.
-{"ejabberd pub/sub module\nCopyright (c) 2003-2005 Alexey Shchepin", "Módulo Pub/Sub para ejabberd\nCopyright (c) 2002-2005 Alexey Shchepin"}.
+{"ejabberd pub/sub module\nCopyright (c) 2003-2006 Alexey Shchepin", "Módulo Pub/Sub para ejabberd\nCopyright (c) 2002-2006 Alexey Shchepin"}.
{"Max # of items to persist", "Máximo # de elementos que persistem"}.
{"Max payload size in bytes", "Máximo tamanho do payload em bytes"}.
{"Node Creator", "Criador do nodo"}.
@@ -118,7 +118,7 @@
{"Enable logging?", "Salvar históricos?"}.
{"Access denied by service policy", "Aceso denegado por la política do serviço"}.
{"Conference room does not exist", "La sala de conferencias não existe"}.
-{"ejabberd MUC module\nCopyright (c) 2003-2005 Alexey Shchepin", "Módulo de MUC para ejabbed\nCopyright (c) 2002-2005 Alexey Shchepin"}.
+{"ejabberd MUC module\nCopyright (c) 2003-2006 Alexey Shchepin", "Módulo de MUC para ejabbed\nCopyright (c) 2002-2006 Alexey Shchepin"}.
{"Enter nickname you want to register", "Introduza o apelido que quer registrar"}.
{"Incorrect password", "Senha incorreta"}.
{"Make room anonymous?", "Tornar a sala anônima?"}.
@@ -181,7 +181,7 @@
% mod_irc/mod_irc.erl
-{"ejabberd IRC module\nCopyright (c) 2003-2005 Alexey Shchepin", "Módulo de IRC para ejabberd\nCopyright (c) 2002-2005 Alexey Shchepin"}.
+{"ejabberd IRC module\nCopyright (c) 2003-2006 Alexey Shchepin", "Módulo de IRC para ejabberd\nCopyright (c) 2002-2006 Alexey Shchepin"}.
{"Encodings", "Codificação"}.
{"Enter username and encodings you wish to use for connecting to IRC servers", "Introduza o nome de usuário e codificações de caracteres que quer usar ao conectar-se aos servidores de IRC"}.
{"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].", "Exemplo: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}]."}.
@@ -209,7 +209,7 @@
{"ejabberd access control lists configuration", "Configuração das Listas de Controle de Acesso do ejabberd"}.
{"ejabberd access rules configuration", "Configuração de las Regras de Aceso de ejabberd"}.
{"ejabberd administration", "Administração de ejabberd"}.
-{"ejabberd (c) 2002-2005 Alexey Shchepin, 2004-2005 Process One", "ejabberd (c) 2002-2005 Alexey Shchepin, 2004-2005 Process One"}.
+{"ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One", "ejabberd (c) 2002-2006 Alexey Shchepin, 2004-2006 Process One"}.
{"ejabberd stats", "Estatísticas de ejabberd"}.
{"ejabberd users", "Usuários do ejabberd"}.
{"ejabberd virtual hosts", "Maquinas virtuais de ejabberd"}.
@@ -292,6 +292,150 @@
{"JID", "JID"}.
+% mod_adhoc.erl
+{"Commands", "Comandos"}.
+{"Ping", "Ping"}.
+{"Pong", "Pong"}.
+
+% mod_vcard_odbc.erl
+{"Email", "e-mail"}.
+{"Search Results for ", "Resultados de pesquisa para"}.
+{"Jabber ID", "ID Jabber"}.
+
+% ejabberd_c2s.erl
+{"Replaced by new connection", "Substituído por nova conexão"}.
+
+% mod_announce.erl
+{"Really delete message of the day?", "Deletar realmente a mensagem do dia?"}.
+{"Subject", "Assunto"}.
+{"Message body", "Corpo da mensagem"}.
+{"No body provided for announce message", "Nenhum corpo de texto fornecido para anunciar mensagem"}.
+{"Announcements", "Anúncios"}.
+{"Send announcement to all users", "Enviar anúncio a todos os usuários"}.
+{"Send announcement to all online users", "Enviar anúncio a todos os usuárions online"}.
+{"Send announcement to all online users on all hosts", "Enviar anúncio a todos usuários online em todas as máquinas"}.
+{"Set message of the day and send to online users", "Definir mensagem do dia e enviar a todos usuários online"}.
+{"Update message of the day (don't send)", "Atualizar mensagem do dia (não enviar)"}.
+{"Delete message of the day", "Apagar mensagem do dia"}.
+
+% mod_configure.erl
+{"Database", "Base de dados"}.
+{"Host Name", "Nome da máquina"}.
+{"Outgoing s2s Connections", "Conexões que partam de s2s"}.
+{"Import Users From jabberd 1.4 Spool Files", "Importar usuários de arquivos jabberd 1.4"}.
+{"Database Tables Configuration at ", "Configuração de Tabelas de Base de dados em "}.
+{"Stop Modules at ", "Parar módulos em "}.
+{"List of modules to start", "Listas de módulos para inicializar"}.
+{"Hostname Configuration", "Configuração do Hostname"}.
+{"Choose host name", "Definir nome da máquina"}.
+{"Host name", "Nome da máquina"}.
+
+% mod_pubsub/mod_pubsub.erl
+
+% web/ejabberd_web_admin.erl
+{"ejabberd Web Interface", "Interface Web do ejabberd"}.
+{"Administration", "Administração"}.
+{"Nodes", "Nós"}.
+{"(Raw)", "(Intocado)"}.
+{"Submitted", "Submetido"}.
+{"Bad format", "Formato incorreto"}.
+{"Raw", "Intocado"}.
+{"Users Last Activity", "Ultimas atividades dos usuários"}.
+{"Node not found", "Nó não encontrado"}.
+{"Registered Users", "Usuários Registrados"}.
+{"Offline Messages", "Mensagens offline"}.
+{"Registered Users:", "Usuários registrados"}.
+{"Authenticated Users:", "Usuários Autenticados"}.
+{"Online Users:", "Usuários online"}.
+{"Outgoing s2s Connections:", "Conexões que partem de s2s"}.
+{"Outgoing s2s Servers:", "Servidores que partem de s2s"}.
+{"None", "Nenhum"}.
+{"Offline Messages:", "Mensagens offline"}.
+{"~s's Offline Messages Queue", "~s's Fila de Mensagens Offline"}.
+{"Add Jabber ID", "Adicionar ID jabber"}.
+{"No Data", "Nenhum dado"}.
+{"Node ", "Nó"}.
+{"Listened Ports", "Portas escutadas"}.
+{"RPC Call Error", "Erro de chamada RPC"}.
+{"Database Tables at ", "Tabelas de base de dados em"}.
+{"Backup of ", "Backup de"}.
+{"Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.", "Observe que tais opções farão backup apenas da base de dados Mnesia. Caso você esteja utilizando o modulo ODBC, você precisará fazer backup de sua base de dados SQL separadamente."}.
+{"Store binary backup:", "Armazenar backup binário:"}.
+{"OK", "OK"}.
+{"Restore binary backup immediately:", "Restaurar backup binário imediatamente"}.
+{"Restore binary backup after next ejabberd restart (requires less memory):", "Restaurar backup binário após próximo reinicialização do ejabberd (requer menos memória):"}.
+{"Store plain text backup:", "Armazenar backup plain text"}.
+{"Restore plain text backup immediately:", "Restaurar backup plain text imediatamente:"}.
+{"Statistics of ~p", "Estatísticas de ~p"}.
+{"Uptime:", "Uptime:"}.
+{"CPU Time:", "Tempo de CPU"}.
+{"Transactions Commited:", "Transações:"}.
+{"Transactions Aborted:", "Transações abortadas:"}.
+{"Transactions Restarted:", "Transações restauradas:"}.
+{"Transactions Logged:", "Transações de log:"}.
+{"Update ", "Atualizar"}.
+{"Update plan", "Plano de Atualização"}.
+{"Updated modules", "Módulos atualizados"}.
+{"Update script", "Script de atualização"}.
+{"Low level update script", "Script de atualização low level"}.
+{"Script check", "Verificação de Script"}.
+{"Not Found", "Não encontrado"}.
+{"Shared Roster Groups", "Grupos Shared Roster"}.
+{"Description:", "Descrição:"}.
+{"Displayed Groups:", "Grupos Indicados"}.
+
+% mod_irc/mod_irc.erl
+
+% mod_muc/mod_muc_log.erl
+{"Chatroom configuration modified", "Configuração da sala de bate-papo modificada"}.
+{"joins the room", "Entrar na sala"}.
+{"leaves the room", "Sair da sala"}.
+{"has been kicked", "foi removido"}.
+{"has been banned", "foi banido"}.
+{"is now known as", ""}.
+{"Monday", "Segunda"}.
+{"Tuesday", "Terça"}.
+{"Wednesday", "Quarta"}.
+{"Thursday", "Quinta"}.
+{"Friday", "Sexta"}.
+{"Saturday", "Sábado"}.
+{"Sunday", "Domingo"}.
+{"January", "Janeiro"}.
+{"February", "Fevereiro"}.
+{"March", "Março"}.
+{"April", "Abril"}.
+{"May", "Maio"}.
+{"June", "Junho"}.
+{"July", "Julho"}.
+{"August", "Agosto"}.
+{"September", "Setembro"}.
+{"October", "Outubro"}.
+{"November", "Novembro"}.
+{"December", "Dezembro"}.
+{"Room Configuration", "Configuração de salas"}.
+
+% mod_muc/mod_muc.erl
+{"Only service administrators are allowed to send service messages", "Apenas administradores possuem permissão para enviar mensagens de serviço"}.
+{"You must fill in field \"Nickname\" in the form", "Você deve completar o campo \"Apelido\" no formulário"}.
+
+% mod_muc/mod_muc_room.erl
+{"This room is not anonymous", "Essa sala não é anônima"}.
+{"Make room persistent", "Tornar sala persistente"}.
+{"Make room public searchable", "Tornar sala pública possível de ser encontrada"}.
+{"Make participants list public", "Tornar pública a lista de participantes"}.
+{"Make room password protected", "Tornar protegida a senha da sala"}.
+{"Make room semianonymous", "Tornar sala semi-anônima"}.
+{"Make room members-only", "Tornar sala apenas para membros"}.
+{"Make room moderated", "Tornar a sala moderada"}.
+{"Default users as participants", "Usuários padrões como participantes"}.
+{"Allow users to change subject", "Permitir a usuários modificar o assunto"}.
+{"Allow users to send private messages", "Permitir a usuários enviarem mensagens privadas"}.
+{"Allow users to query other users", "Permitir a usuários pesquisar informações sobre os demais"}.
+{"Allow users to send invites", "Permitir a usuários envio de convites"}.
+{"Enable logging", "Permitir criação de logs"}.
+{"Description", "Descrição"}.
+{"Number of occupants", "Número de participantes"}.
+
% Local Variables:
% mode: erlang
% End:
diff --git a/src/xml_stream.erl b/src/xml_stream.erl
index 324796d8d..c923b6ae7 100644
--- a/src/xml_stream.erl
+++ b/src/xml_stream.erl
@@ -11,6 +11,7 @@
-vsn('$Revision$ ').
-export([new/1,
+ new/2,
parse/2,
close/1,
parse_element/1]).
@@ -23,7 +24,7 @@
-define(PARSE_COMMAND, 0).
-define(PARSE_FINAL_COMMAND, 1).
--record(xml_stream_state, {callback_pid, port, stack}).
+-record(xml_stream_state, {callback_pid, port, stack, size, maxsize}).
process_data(CallbackPid, Stack, Data) ->
case Data of
@@ -68,23 +69,45 @@ process_data(CallbackPid, Stack, Data) ->
end.
-
new(CallbackPid) ->
+ new(CallbackPid, infinity).
+
+new(CallbackPid, MaxSize) ->
Port = open_port({spawn, expat_erl}, [binary]),
#xml_stream_state{callback_pid = CallbackPid,
port = Port,
- stack = []}.
+ stack = [],
+ size = 0,
+ maxsize = MaxSize}.
parse(#xml_stream_state{callback_pid = CallbackPid,
port = Port,
- stack = Stack} = State, Str) ->
+ stack = Stack,
+ size = Size,
+ maxsize = MaxSize} = State, Str) ->
+ StrSize = if
+ is_list(Str) -> length(Str);
+ is_binary(Str) -> size(Str)
+ end,
Res = port_control(Port, ?PARSE_COMMAND, Str),
- NewStack = lists:foldl(
- fun(Data, St) ->
- process_data(CallbackPid, St, Data)
- end, Stack, binary_to_term(Res)),
- State#xml_stream_state{stack = NewStack}.
+ {NewStack, NewSize} =
+ lists:foldl(
+ fun(Data, {St, Sz}) ->
+ NewSt = process_data(CallbackPid, St, Data),
+ case NewSt of
+ [_] -> {NewSt, 0};
+ _ -> {NewSt, Sz}
+ end
+ end, {Stack, Size + StrSize}, binary_to_term(Res)),
+ if
+ NewSize > MaxSize ->
+ catch gen_fsm:send_event(CallbackPid,
+ {xmlstreamerror, "XML stanza is too big"});
+ true ->
+ ok
+ end,
+ State#xml_stream_state{stack = NewStack, size = NewSize}.
close(#xml_stream_state{port = Port}) ->
port_close(Port).