Permalink
Browse files

Merge branch 're'

Conflicts:
	src/test/ts_test_proxy.erl
	src/test/ts_test_recorder.erl
	src/tsung/ts_search.erl
	src/tsung/ts_utils.erl
	src/tsung_controller/ts_config_server.erl
	tsung-1.0.dtd
  • Loading branch information...
2 parents 3f2cada + 8e62c8e commit d03a2207fc6314dccf8aeb29963f1844caed3781 @nniclausse nniclausse committed Aug 18, 2010
View
3 include/ts_config.hrl
@@ -33,6 +33,9 @@
-define(DEF_REGEXP_DYNVAR_BEGIN, "name=(\"|')").%'
-define(DEF_REGEXP_DYNVAR_END, "(\"|') ([^>]* )?value=(\"|')\\([^(\"|')]*\\)(\"|')").%'
+-define(DEF_RE_DYNVAR_BEGIN, "name=[\"']").%'
+-define(DEF_RE_DYNVAR_END, "[\"'] ([^>]* )?value=[\"']([^\"']*)[\"']").%'
+
-record(config, {
name,
duration, % max duration of test (by default: end when all clients are done)
View
5 src/test/ts_test_config.erl
@@ -34,6 +34,11 @@ read_config_jabber_muc_test() ->
ts_user_server:start([]),
?assertMatch({ok, Config}, ts_config:read("./examples/jabber_muc.xml",".")).
+read_config_xmpp_muc_test() ->
+ myset_env(),
+ ts_user_server:start([]),
+ ?assertMatch({ok, Config}, ts_config:read("./src/test/xmpp-muc.xml",".")).
+
config_get_session_test() ->
myset_env(),
ts_user_server:start([]),
View
8 src/test/ts_test_jabber.erl
@@ -1,7 +1,7 @@
%%%
%%% Copyright © Nicolas Niclausse 2007
%%%
-%%% Author : Nicolas Niclausse <Nicolas.Niclausse@niclux.org>
+%%% Author : Nicolas Niclausse <Nicolas.Niclausse@niclux.org>
%%% Created: 17 Mar 2007 by Nicolas Niclausse <Nicolas.Niclausse@niclux.org>
%%%
%%% This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@
%%% 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.
-%%%
+%%%
-module(ts_test_jabber).
-vc('$Id$ ').
@@ -69,4 +69,6 @@ bidi_nok_test()->
?assertMatch({nodata,State}, ts_jabber:parse_bidi(Req,State)).
myset_env()->
- application:set_env(stdlib,debug_level,0).
+ myset_env(0).
+myset_env(Val)->
+ application:set_env(stdlib,debug_level,Val).
View
34 src/test/ts_test_proxy.erl
@@ -54,8 +54,8 @@ Content-Length: 30
<h1>http://-foo.bar/toto</h1>
</body></html>
",
- ?assertMatch({ok,NewData},
- ts_utils:from_https(Data)).
+ {ok,Res}=ts_utils:from_https(Data),
+ ?assertEqual(list_to_binary(NewData),iolist_to_binary(Res) ).
rewrite_http_location_test()->
myset_env(),
@@ -75,8 +75,8 @@ Content-Length: 30
<h1>http://-foo.bar/toto or http://-foo.bar/glop</h1>
</body></html>
",
- ?assertMatch({ok,NewData},
- ts_utils:from_https(Data)).
+ {ok, Res}=ts_utils:from_https(Data),
+ ?assertEqual(list_to_binary(NewData),iolist_to_binary(Res) ).
rewrite_http_location_nourl_test()->
myset_env(),
@@ -94,43 +94,45 @@ Content-Length: 30
<html><head></head><body>
</body></html>
",
- ?assertMatch({ok,NewData},
- ts_utils:from_https(Data)).
+ {ok, Res} = ts_utils:from_https(Data),
+ ?assertEqual(list_to_binary(NewData), iolist_to_binary(Res)).
rewrite_http_encode_test()->
myset_env(),
Data="GET http://-foobar.foo42.fr/ HTTP/1.1\r\nHost: -foobar.foo42.fr\r\nAccept-Encoding: gzip,deflate\r\nAccept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7\r\n\r\n",
NewData="GET https://foobar.foo42.fr/ HTTP/1.1\r\nHost: foobar.foo42.fr\r\nAccept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7\r\n\r\n",
- ?assertMatch({ok,NewData},
- ts_utils:to_https({request,Data})).
+ {ok, Res} = ts_utils:to_https({request,Data}),
+ ?assertEqual(list_to_binary(NewData), iolist_to_binary(Res)).
rewrite_http_encode2_test()->
myset_env(),
Data="GET http://gforge-qualif.foo.fr/ HTTP/1.1\r\nHost: gforge-qualif.foo.fr\r\nUser-Agent: Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.1.6) Gecko/20100107 Fedora/3.5.6-1.fc12 Firefox/3.5.6\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: fr,en-us;q=0.7,en;q=0.3\r\nAccept-Encoding: gzip,deflate\r\nAccept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7\r\nKeep-Alive: 300\r\nProxy-Connection: keep-alive\r\nPragma: no-cache\r\nCache-Control: no-cache\r\n\r\n",
NewData="GET http://gforge-qualif.foo.fr/ HTTP/1.1\r\nHost: gforge-qualif.foo.fr\r\nUser-Agent: Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.1.6) Gecko/20100107 Fedora/3.5.6-1.fc12 Firefox/3.5.6\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: fr,en-us;q=0.7,en;q=0.3\r\nAccept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7\r\nKeep-Alive: 300\r\nProxy-Connection: keep-alive\r\nPragma: no-cache\r\nCache-Control: no-cache\r\n\r\n",
- ?assertMatch({ok,NewData},
- ts_utils:to_https({request,Data})).
+ {ok, Res} = ts_utils:to_https({request,Data}),
+ ?assertEqual(list_to_binary(NewData), iolist_to_binary(Res)).
rewrite_webdav_test()->
- myset_env(),
+ myset_env(),
Data = "REPORT /tsung/!svn/vcc/default HTTP/1.1\r\nUser-Agent: SVN/1.4.4 (r25188) neon/0.25.5\r\nConnection: TE\r\nTE: trailers\r\nContent-Length: 172\r\nContent-Type: text/xml\r\nAccept-Encoding: svndiff1;q=0.9,svndiff;q=0.8\r\nAccept-Encoding: gzip\r\nAccept-Encoding: gzip\r\n\r\n<S:update-report send-all=\"true\" xmlns:S=\"svn:\"><S:src-path>http://-svn.process-one.net/tsung/trunk/examples</S:src-path><S:entry rev=\"816\" ></S:entry></S:update-report>",
NewData="REPORT /tsung/!svn/vcc/default HTTP/1.1\r\nUser-Agent: SVN/1.4.4 (r25188) neon/0.25.5\r\nConnection: TE\r\nTE: trailers\r\nContent-Length: 172\r\nContent-Type: text/xml\r\nAccept-Encoding: svndiff1;q=0.9,svndiff;q=0.8\r\n\r\n<S:update-report send-all=\"true\" xmlns:S=\"svn:\"><S:src-path>https://svn.process-one.net/tsung/trunk/examples</S:src-path><S:entry rev=\"816\" ></S:entry></S:update-report>",
- ?assertMatch({ok,NewData},
- ts_utils:to_https({request,Data})).
-
+ {ok, Res} = ts_utils:to_https({request,Data}),
+ ?assertEqual(list_to_binary(NewData), iolist_to_binary(Res)).
rewrite_http_encode_post_test()->
myset_env(),
Data="POST http://-foobar.foo42.fr/ HTTP/1.1\r\nHost: -foobar.foo42.fr\r\nAccept-Encoding: gzip,deflate\r\nAccept-Charset: ISO-8859-15,utf-8;q=0.7,;q=0.7Content-Type: application/x-www-form-urlencoded\r\nContent-Length: 24\r\n\r\nuname=admin&upass=*****",
NewData="POST https://foobar.foo42.fr/ HTTP/1.1\r\nHost: foobar.foo42.fr\r\nAccept-Charset: ISO-8859-15,utf-8;q=0.7,;q=0.7Content-Type: application/x-www-form-urlencoded\r\nContent-Length: 24\r\n\r\nuname=admin&upass=*****",
- ?assertMatch({ok,NewData},ts_utils:to_https({request,Data})).
+ {ok,Res}=ts_utils:to_https({request,Data}),
+ ?assertEqual(list_to_binary(NewData),iolist_to_binary(Res)).
%% parse_http_test()->
%% myset_env(),
%% ?assertMatch({ok,""},
%% ts_proxy_http:parse(State,ClientSocket,Socket,Data)).
+myset_env(Val)->
+ application:set_env(stdlib,debug_level,Val).
myset_env()->
- application:set_env(stdlib,debug_level,0).
+ myset_env(0).
View
8 src/test/ts_test_recorder.erl
@@ -64,11 +64,11 @@ encode_base64_test()->
rewrite_http_secure_cookie_test()->
Data="HTTP/1.1 200 OK\r\nSet-Cookie: JSESSIONID=F949C9182402EB74258F43FDC3F3C63F; Path=/; Secure\r\nLocation: https://foo.bar/\r\nContent-Length: 0\r\n\r\n",
NewData="HTTP/1.1 200 OK\r\nSet-Cookie: JSESSIONID=F949C9182402EB74258F43FDC3F3C63F; Path=/\r\nLocation: http://-foo.bar/\r\nContent-Length: 0\r\n\r\n",
- ?assertEqual({ok,NewData},
- ts_utils:from_https(Data)).
+ {ok,Res} = ts_utils:from_https(Data),
+ ?assertEqual(list_to_binary(NewData),iolist_to_binary(Res) ).
rewrite_http_secure_cookies_test()->
Data="HTTP/1.1 200 OK\r\nSet-Cookie: JSESSIONID=F949C9182402EB74258F43FDC3F3C63F; Path=/; Secure\r\nSet-Cookie: JSESSIONID=32; Path=/foo; Secure\r\nLocation: https://foo.bar/\r\nContent-Length: 0\r\n\r\n",
NewData="HTTP/1.1 200 OK\r\nSet-Cookie: JSESSIONID=F949C9182402EB74258F43FDC3F3C63F; Path=/\r\nSet-Cookie: JSESSIONID=32; Path=/foo\r\nLocation: http://-foo.bar/\r\nContent-Length: 0\r\n\r\n",
- ?assertMatch({ok,Data2},
- ts_utils:from_https(Data)).
+ {ok,Res} = ts_utils:from_https(Data),
+ ?assertEqual(list_to_binary(NewData),iolist_to_binary(Res) ).
View
28 src/test/ts_test_search.erl
@@ -120,6 +120,16 @@ parse_dyn_var_many_test() ->
erlang:display([?MANY," regexp:", Time]),
?assertMatch(Res, Out).
+parse_dyn_var_many_re_test() ->
+ myset_env(),
+ {Data, Res}= setdata(?MANY),
+ RegexpFun = fun(A) -> {re,list_to_atom(A), ?DEF_RE_DYNVAR_BEGIN++ A ++?DEF_RE_DYNVAR_END} end,%'
+ B=lists:map(fun(A)->"random"++integer_to_list(A) end, lists:seq(1,?MANY)),
+ C=lists:map(RegexpFun, B),
+ {Time, Out}=timer:tc( ts_search,parse_dynvar,[C,list_to_binary(Data)]),
+ erlang:display([?MANY," re:", Time]),
+ ?assertMatch(Res, Out).
+
parse_dyn_var_many_xpath_test() ->
myset_env(),
{Data, Res}= setdata(?MANY),
@@ -148,6 +158,16 @@ parse_dyn_var_many_big_test() ->
erlang:display([?MANY," regexp_big:", Time]),
?assertMatch(Res, Out).
+parse_dyn_var_many_big_re_test() ->
+ myset_env(),
+ {Data, Res}= setdata_big(?MANY),
+ RegexpFun = fun(A) -> {re,list_to_atom(A), ?DEF_RE_DYNVAR_BEGIN++ A ++?DEF_RE_DYNVAR_END} end,%'
+ B=lists:map(fun(A)->"random"++integer_to_list(A) end, lists:seq(1,?MANY)),
+ C=lists:map(RegexpFun, B),
+ {Time, Out}=timer:tc( ts_search,parse_dynvar,[C,list_to_binary(Data)]),
+ erlang:display([?MANY," re_big:", Time]),
+ ?assertMatch(Res, Out).
+
parse_dyn_var_many_big_xpath_test() ->
myset_env(),
{Data, Res}= setdata_big(?MANY),
@@ -196,6 +216,14 @@ parse_subst1_test() ->
[{Name,Value}] = ts_search:parse_dynvar([{regexp, 'jsf_tree_64', Regexp }],list_to_binary(Data)),
?assertMatch("H4sIAAAAAAAAAK1VS2/TQBBeo+kalCKAA", ts_search:subst("%%_jsf_tree_64%%",[{Name,Value}])).
+parse_subst1_re_test() ->
+ myset_env(),
+ Data=?FORMDATA,
+ StrName="jsf_tree_64",
+ Regexp = ?DEF_RE_DYNVAR_BEGIN++ StrName ++?DEF_RE_DYNVAR_END,%'
+ [{Name,Value}] = ts_search:parse_dynvar([{re, 'jsf_tree_64', Regexp }],list_to_binary(Data)),
+ ?assertMatch("H4sIAAAAAAAAAK1VS2/TQBBeo+kalCKAA", ts_search:subst("%%_jsf_tree_64%%",[{Name,Value}])).
+
parse_extract_fun1_test() ->
myset_env(),
Data="/echo?symbol=%%ts_test_search:new%%",
View
136 src/test/xmpp-muc.xml.in
@@ -0,0 +1,136 @@
+<?xml version="1.0"?>
+<!DOCTYPE tsung SYSTEM "@prefix@/share/@PACKAGE_NAME@/@DTD@">
+<tsung loglevel="notice" version="1.0">
+<clients>
+<client host="localhost" use_controller_vm="true" maxusers="20000"></client>
+ </clients>
+
+ <!-- Server side setup -->
+<servers>
+ <server host="deepblue" port="5222" type="tcp"></server>
+</servers>
+ <load>
+ <arrivalphase phase="1" duration="360" unit="minute">
+ <users interarrival="0.02" unit="second"></users>
+ </arrivalphase>
+ </load>
+
+ <!-- JABBER parameters -->
+ <!-- to synchronise users, use a global acknoledgement -->
+<options>
+ <option type="ts_jabber" name="global_number" value="9999"></option>
+ <option type="ts_jabber" name="userid_max" value="9999"></option>
+ <option type="ts_jabber" name="domain" value="deepblue"></option>
+ <option type="ts_jabber" name="username" value="tsung1"></option>
+ <option type="ts_jabber" name="passwd" value="tsung1"></option>
+
+ <option type="ts_jabber" name="muc_service" value="conference.deepblue"/>
+ <!-- full name of the MUC component -->
+</options>
+
+ <sessions>
+ <session bidi="true" probability="60" name="jabber-muc" type="ts_jabber">
+
+ <request> <jabber type="connect" ack="no_ack"></jabber> </request>
+ <thinktime value="2"></thinktime>
+
+ <transaction name="authenticate">
+ <request> <jabber type="auth_get" ack="local"></jabber> </request>
+ <request> <jabber type="auth_set_plain" ack="local"></jabber> </request>
+ </transaction>
+
+ <thinktime value="2"></thinktime>
+ <request> <jabber type="presence:initial" ack="no_ack"/> </request>
+
+<for from="1" to="100" var="i">
+<setdynvars sourcetype="random_number" start="1" end="100000">
+<var name="room"/>
+</setdynvars>
+<setdynvars sourcetype="random_string" length="10">
+<var name="nick1"/>
+</setdynvars>
+ <!-- join an existing room or create a new one -->
+ <request subst="true">
+ <jabber type='muc:join' ack = "local" room = "room%%_room%%" nick = "%%_nick1%%"/>
+ </request>
+<thinktime value="10"/>
+ <for from="1" to="10" var="b">
+ <request subst="true"><jabber type="muc:chat" ack="local" room="room%%_room%%"/></request>
+ <thinktime value="5"/>
+ </for>
+</for>
+ <!-- choose a new nickname -->
+ <thinktime value="2"/>
+<transaction name="close">
+<request> <jabber type="close" ack="no_ack"></jabber> </request>
+ </transaction>
+
+</session>
+<!-- ========================================== -->
+ <session bidi="true" probability="30" name="jabber-muc2" type="ts_jabber">
+
+ <request> <jabber type="connect" ack="no_ack"></jabber> </request>
+ <thinktime value="2"></thinktime>
+
+ <transaction name="authenticate">
+ <request> <jabber type="auth_get" ack="local"></jabber> </request>
+ <request> <jabber type="auth_set_plain" ack="local"></jabber> </request>
+ </transaction>
+
+ <thinktime value="2"></thinktime>
+ <request> <jabber type="presence:initial" ack="no_ack"/> </request>
+
+<for from="1" to="1000" var="i">
+<setdynvars sourcetype="random_number" start="1" end="100000">
+<var name="room"/>
+</setdynvars>
+<setdynvars sourcetype="random_string" length="10">
+<var name="nick1"/>
+</setdynvars>
+ <!-- join an existing room or create a new one -->
+ <request subst="true">
+ <jabber type='muc:join' ack = "local" room = "room%%_room%%" nick = "%%_nick1%%"/>
+ </request>
+<thinktime value="10"/>
+</for>
+ <!-- choose a new nickname -->
+ <thinktime value="2"/>
+<transaction name="close">
+<request> <jabber type="close" ack="no_ack"></jabber> </request>
+ </transaction>
+</session>
+<!-- ========================================== -->
+ <session bidi="true" probability="10" name="jabber-muc3" type="ts_jabber">
+
+ <request> <jabber type="connect" ack="no_ack"></jabber> </request>
+ <thinktime value="2"></thinktime>
+
+ <transaction name="authenticate">
+ <request> <jabber type="auth_get" ack="local"></jabber> </request>
+ <request> <jabber type="auth_set_plain" ack="local"></jabber> </request>
+ </transaction>
+
+ <thinktime value="2"></thinktime>
+ <request> <jabber type="presence:initial" ack="no_ack"/> </request>
+
+<setdynvars sourcetype="random_number" start="1" end="100000">
+<var name="room"/>
+</setdynvars>
+<setdynvars sourcetype="random_string" length="10">
+<var name="nick1"/>
+</setdynvars>
+ <!-- join an existing room or create a new one -->
+ <request subst="true">
+ <jabber type='muc:join' ack = "local" room = "room%%_room%%" nick = "%%_nick1%%"/>
+ </request>
+<thinktime value="10"/>
+ <!-- choose a new nickname -->
+ <thinktime value="2"/>
+<transaction name="close">
+<request> <jabber type="close" ack="no_ack"></jabber> </request>
+ </transaction>
+</session>
+
+
+</sessions>
+</tsung>
View
9 src/tsung/ts_fs.erl
@@ -32,6 +32,7 @@
get_message/1,
session_defaults/0,
parse/2,
+ parse_bidi/2,
parse_config/2,
new_session/0]).
@@ -127,21 +128,21 @@ subst(Req=#fs{path=Path,size=Size}, DynVars) ->
%% Setting Close to true will cause tsung to close the connection to
%% the server.
%% @end
-parse({file, open, Args, {ok,IODevice}},State=#state_rcv{dyndata=DynData}) ->
+parse({file, open, _Args, {ok,IODevice}},State=#state_rcv{dyndata=DynData}) ->
NewDyn=(DynData#dyndata.proto)#fs_dyndata{iodev=IODevice,position=0},
{State#state_rcv{ack_done=true,datasize=0,dyndata=DynData#dyndata{proto=NewDyn}}, [], false};
parse({file, open, [Path,_], {error,Reason}},State) ->
?LOGF("error while opening file: ~p(~p)~n",[Path, Reason],?ERR),
ts_mon:add({count,error_fs_open}),
{State#state_rcv{ack_done=true,datasize=0}, [], false};
-parse({file, close, [IODevice], ok},State=#state_rcv{dyndata=DynData}) ->
+parse({file, close, [_IODevice], ok},State=#state_rcv{dyndata=DynData}) ->
NewDyn=(DynData#dyndata.proto)#fs_dyndata{iodev=undefined,position=0},
{State#state_rcv{ack_done=true,datasize=0,dyndata=DynData#dyndata{proto=NewDyn}}, [], false};
-parse({file, pread, [IODev,Pos,Size], {ok,_Data}},State=#state_rcv{dyndata=DynData,datasize=DataSize}) ->
+parse({file, pread, [_IODev,Pos,Size], {ok,_Data}},State=#state_rcv{dyndata=DynData,datasize=DataSize}) ->
NewDyn=(DynData#dyndata.proto)#fs_dyndata{position=Pos+Size},
{State#state_rcv{ack_done=true,datasize=DataSize+Size,dyndata=DynData#dyndata{proto=NewDyn}}, [], false};
-parse({file, pread, [IODev,Pos,Size], eof},State=#state_rcv{dyndata=DynData,datasize=DataSize}) ->
+parse({file, pread, [_IODev,Pos,Size], eof},State=#state_rcv{dyndata=DynData,datasize=DataSize}) ->
NewDyn=(DynData#dyndata.proto)#fs_dyndata{position=0},
{State#state_rcv{ack_done=true,datasize=DataSize+Size,dyndata=DynData#dyndata{proto=NewDyn}}, [], false};
View
16 src/tsung/ts_jabber.erl
@@ -88,10 +88,10 @@ parse(_Data, State) ->
%%----------------------------------------------------------------------
parse_bidi(Data, State) ->
RcvdXml = binary_to_list(Data),
- case regexp:first_match(RcvdXml,"<presence[^>]*subscribe[\"\']") of
- {match,_,_} ->
+ case re:run(RcvdXml,"<presence[^>]*subscribe[\"']") of
+ {match,_} ->
?LOGF("RECEIVED : ~p~n",[RcvdXml],?DEB),
- {match,SubMatches} = regexp:matches(RcvdXml,"<presence[^>]*subscribe[\"\'][^>]*>"),
+ {match,SubMatches} = re:run(RcvdXml,"<presence[^>]*subscribe[\"\'][^>]*>",[global]),
bidi_resp(subscribed,RcvdXml,SubMatches,State);
_Else ->
{nodata,State}
@@ -110,11 +110,11 @@ parse_bidi(Data, State) ->
%% subscribed: Complete a pending subscription request
bidi_resp(subscribed,RcvdXml,SubMatches,State) ->
JoinedXml=lists:foldl(fun(X,Foo) ->
- {Start,Len}=X,
- SubStr = string:substr(RcvdXml,Start,Len),
- case regexp:first_match(SubStr,"from=[\"\'][^\s]*[\"\'][\s\/\>]") of
- {match,Start1,Length1} ->
- MyId=string:substr(SubStr,Start1 +6, Length1 -8),
+ [{Start,Len}]=X,
+ SubStr = string:substr(RcvdXml,Start+1,Len),
+ case re:run(SubStr,"from=[\"']([^\s]*)[\"'][\s\/\>]",[{capture,[1],list}]) of
+ {match,[MyId]} ->
+ %% MyId=string:substr(SubStr,Start1 +6, Length1 -8),
?LOGF("Subscription request from : ~p~n",[MyId],?DEB),
MyXml = ["<presence to='", MyId, "' type='subscribed'/>"],
lists:append([Foo],[MyXml]);
View
1 src/tsung/ts_pgsql.erl
@@ -211,6 +211,7 @@ process_head(<<Code:8/integer, Size:4/integer-unit:8, Tail/binary>>) ->
true ->
<< Packet:RealSize/binary, Data/binary >> = Tail,
{ok, Pair} = pgsql_proto:decode_packet(Code, Packet),
+ ?DebugF("PGSQL: data as string: ~p~n",[pgsql_util:to_string(Packet)]),
?LOGF("PGSQL: Pair=~p ~n",[Pair],?DEB),
{ok, Pair, Data };
false -> more
View
21 src/tsung/ts_search.erl
@@ -157,14 +157,14 @@ match([Match=#match{regexp=RawRegExp,subst=Subst, do=Action, 'when'=When}
_ -> RawRegExp
end,
?DebugF("RegExp was ~p and now is ~p after substitution (~p)~n",[RawRegExp,RegExp,Subst]),
- case regexp:first_match(String, RegExp) of
- {When,_, _} ->
+ case re:run(String, RegExp) of
+ {When,_} ->
?LOGF("Ok Match (regexp=~p) do=~p~n",[RegExp,Action], ?INFO),
setcount(Match, Counts, [{count, match}| Stats]);
When -> % nomatch
?LOGF("Bad Match (regexp=~p) do=~p~n",[RegExp, Action], ?INFO),
setcount(Match, Counts, [{count, nomatch} | Stats]);
- {match,_, _} -> % match but when=nomatch
+ {match,_} -> % match but when=nomatch
?LOGF("Ok Match (regexp=~p)~n",[RegExp], ?INFO),
case Action of
loop -> put(loop_count, 0);
@@ -258,6 +258,21 @@ parse_dynvar(DynVarSpecs, _Data) ->
% regexp or xpath variables respectively
parse_dynvar([],_Binary , _String,_Tree, DynVars) -> DynVars;
+
+
+parse_dynvar(D=[{re,_, _}| _],Binary,undefined,Tree,DynVars) ->
+ parse_dynvar(D,Binary,Binary,Tree,DynVars);
+parse_dynvar([{re,VarName, RegExp}| DynVarsSpecs],Binary,Data,Tree,DynVars) ->
+ case re:run(Data, RegExp,[{capture,[2],list}]) of
+ {match,[Value]} ->
+ ?LOGF("DynVar: Match (~p=~p) ~n",[VarName, Value], ?DEB),
+ parse_dynvar(DynVarsSpecs, Binary,Data,Tree,
+ ts_dynvars:set(VarName,Value,DynVars));
+ nomatch ->
+ ?LOGF("Dyn Var: no Match (varname=~p), ~n",[VarName], ?WARN),
+ parse_dynvar(DynVarsSpecs, Binary,Data,Tree, ts_dynvars:set(VarName,"",DynVars))
+ end;
+
parse_dynvar(D=[{regexp,_VarName, _RegExp}| _DynVarsSpecs],
Binary,undefined,Tree, DynVars) ->
parse_dynvar(D,Binary,binary_to_list(Binary),Tree,DynVars);
View
90 src/tsung/ts_utils.erl
@@ -189,31 +189,13 @@ node_to_hostname(Node) ->
{ok, Hostname}.
to_lower(String)->
- case check_httpd_old_version() of
- false ->
- string:to_lower(String);
- true ->
- httpd_util:to_lower(String)
- end.
+ string:to_lower(String).
encode_base64(String)->
- case check_httpd_old_version() of
- false ->
- base64:encode_to_string(String);
- true ->
- httpd_util:encode_base64(String)
- end.
+ base64:encode_to_string(String).
decode_base64(Base64)->
- case check_httpd_old_version() of
- false ->
- base64:decode_to_string(Base64);
- true ->
- httpd_util:decode_base64(Base64)
- end.
-
-%% check erlang version to know if we need to use the old httpd_utils functions
-check_httpd_old_version()-> not release_is_newer_or_eq("5.5.4").
+ base64:decode_to_string(Base64).
% return true if current version of erlang is newer or equal
release_is_newer_or_eq(Release)->
@@ -226,12 +208,7 @@ release_is_newer_or_eq(Release)->
%% these functions will be added to the stdlib)
%%----------------------------------------------------------------------
key1search(Tuple,String)->
- case release_is_newer_or_eq("5.7") of %% should be removed in R13B
- true ->
- proplists:get_value(String,Tuple);
- false ->
- httpd_util:key1search(Tuple,String)
- end.
+ proplists:get_value(String,Tuple).
%%----------------------------------------------------------------------
%% Func: mkey1search/2
@@ -429,8 +406,8 @@ make_dir_rec(Path, [Parent|Childs]) ->
is_ip(String) when is_list(String) ->
EightBit="(2[0-4][0-9]|25[0-5]|1[0-9][0-9]|[0-9][0-9]|[0-9])",
RegExp = lists:append(["^",EightBit,"\.",EightBit,"\.",EightBit,"\.",EightBit,"$"]), %"
- case regexp:first_match(String, RegExp) of
- {match,_,_} -> true;
+ case re:run(String, RegExp) of
+ {match,_} -> true;
_ -> false
end;
is_ip(_) -> false.
@@ -443,39 +420,41 @@ to_https({url, "http://-"++Rest})-> "https://" ++ Rest;
to_https({url, URL})-> URL;
to_https({request, {body,Data}}) when is_list(Data) ->
%% body request, no headers
- {ok,RealBody,_Count} = regexp:gsub(Data,"http://ssl-","https://"),
- {ok, RealBody};
+ re:replace(Data,"http://-","https://",[global]);
to_https({request, S="CONNECT"++Rest}) -> {ok,S};
to_https({request, String}) when is_list(String) ->
EndOfHeader = string:str(String, "\r\n\r\n"),
Header = string:substr(String, 1, EndOfHeader - 1) ++ "\r\n",
Body = string:substr(String, EndOfHeader + 4),
- {ok,TmpHeader,_} = regexp:gsub(Header,"http://-","https://"),
- {ok,TmpHeader2,_} = regexp:gsub(TmpHeader,"Accept-Encoding: [0-9,a-zA-Z_]+\r\n",""),
- {ok,RealHeader,_} = regexp:gsub(TmpHeader2,"Host: -","Host: "),
- {ok,RealBody,Count} = regexp:gsub(Body,"http://-","https://"),
- RealString = RealHeader ++ "\r\n" ++ RealBody,
+ ReOpts=[global],
+ TmpHeader = re:replace(Header,"http://-","https://",ReOpts),
+ TmpHeader2 = re:replace(TmpHeader,"Accept-Encoding: [0-9,a-zA-Z_]+\r\n","",ReOpts),
+ RealHeader = re:replace(TmpHeader2,"Host: -","Host: ",ReOpts),
+ RealBody = re:replace(Body,"http://-","https://",ReOpts),
+ RealString = [RealHeader, "\r\n" , RealBody],
{ok, RealString}.
+
+%% an iolist can be an improper list, so length fails. but we want the length anyway!
+%% first element should be a binary
+length_iolist([B|Tail]) when is_binary(B)->
+ length_iolist(Tail,1);
+length_iolist([]) ->0;
+length_iolist(_) ->1. % string -> one element
+length_iolist(Tail,Acc) when not is_list(Tail) ->
+ Acc+1;
+length_iolist([_A|Tail],Acc)->
+ length_iolist(Tail,Acc+1);
+length_iolist([],Acc)-> Acc.
+
+
+%% @spec from_https(string()) -> {ok, String::string() | Data::iodata}
from_https(String) when is_list(String)->
+ ReOpts=[{newline,crlf},multiline,global,caseless],
%% remove Secure from Set-Cookie (TSUN-120)
- {match, Matches} = regexp:matches(String, "Set-Cookie: [^\r]*\r\n"),
- Fun = fun({0,Length}, {StrAcc, Pos}) ->
- {StrAcc ++ string:substr(String, Pos), -1};
- ({Start,Length}, {StrAcc, Pos}) ->
- SetCookie = string:substr(String, Start, Length),
- {ok, WithoutSecure, _} = regexp:gsub(SetCookie, "; *Secure", ""),
- {StrAcc ++ string:substr(String, Pos, Start - Pos) ++ WithoutSecure, Start + Length}
- end,
- {TmpString, _} = lists:foldl(Fun, {"", 1}, Matches ++ [{0, 0}]),
- %% if location is defined, don't count it (not included in Content-Length)
- Location = case regexp:first_match(TmpString,"Location: https") of
- {match,_,_} -> -1;
- _ -> 0
- end,
- {ok,NewString,RepCount} = regexp:gsub(TmpString,"https://","http://-"),
- {ok, NewString}.
-
+ TmpData = re:replace(String,"(.*set-cookie:.*); *secure(.*$.*$)","\\1\\2",ReOpts),
+ Data=re:replace(TmpData,"https://","http://-",[global]),
+ {ok, Data}.
%% A Perl-style join --- concatenates all strings in Strings,
%% separated by Sep.
@@ -491,8 +470,7 @@ join2(Sep, [First | List]) when is_list(First)->
%% split a string (at first occurence of char)
split(String,Chr) ->
- {ok, List} = regexp:split(String,Chr),
- List.
+ re:split(String,Chr,[{return,list}]).
%% split a string in 2 (at first occurence of char)
split2(String,Chr) ->
@@ -743,7 +721,7 @@ jsonpath(JSONPath,JSON) ->
case catch list_to_integer(A) of
I when is_integer(I) ->
I+1;
- E ->
+ _Error ->
list_to_binary(A)
end
end,
View
6 src/tsung_controller/ts_config.erl
@@ -474,11 +474,15 @@ parse(#xmlElement{name=dyn_variable, attributes=Attrs},
?LOGF("Add new regexp: ~s ~n", [Expr],?INFO),
{ok, CompiledRegExp} = gregexp:parse(FlattenExpr),
{regexp,Name,CompiledRegExp};
+ re ->
+ ?LOGF("Add new re: ~s ~n", [Expr],?INFO),
+ {ok, CompiledRegExp} = re:compile(FlattenExpr),
+ {regexp,Name,CompiledRegExp};
xpath ->
?LOGF("Add new xpath: ~s ~n", [Expr],?INFO),
CompiledXPathExp = mochiweb_xpath:compile_xpath(FlattenExpr),
{xpath,Name,CompiledXPathExp};
- Other ->
+ _Other ->
?LOGF("Add ~s ~s ~p ~n", [Type,Name,Expr],?INFO),
{Type,Name,Expr}
end,
View
2 src/tsung_controller/ts_config_fs.erl
@@ -40,7 +40,7 @@
parse_config(Element = #xmlElement{name=dyn_variable}, Conf = #config{}) ->
ts_config:parse(Element,Conf);
parse_config(Element = #xmlElement{name=fs},
- Config=#config{curid = Id, session_tab = Tab, servers = Servers,
+ Config=#config{curid = Id, session_tab = Tab,
sessions = [CurS | _], dynvar=DynVar,
subst = SubstFlag, match=MatchRegExp}) ->
View
2 src/tsung_controller/ts_config_http.erl
@@ -214,7 +214,7 @@ set_msg(_, {_, _, true, _Server, [],_Tab,_Id}) ->
?LOG("Need absolute URL when using a proxy ! Abort",?ERR),
throw({error, badurl_proxy});
%% url head is a dynvar, don't preset host header
-set_msg(HTTP=#http_request{url="%%" ++ TailURL}, {true, MatchRegExp, _Proxy, _Servers, _Headers,_Tab,_Id}) ->
+set_msg(HTTP=#http_request{url="%%" ++ _TailURL}, {true, MatchRegExp, _Proxy, _Servers, _Headers,_Tab,_Id}) ->
set_msg2(HTTP,
#ts_request{ack = parse, subst = true, match = MatchRegExp });
%% relative URL, no proxy, a single server => we can preset host header at configuration time
View
4 src/tsung_controller/ts_config_server.erl
@@ -562,7 +562,7 @@ decode_filename("ts_encoded" ++ String)->
lists:foldl(fun replace_str/2, String, Transform).
replace_str({A,B},X) ->
- {ok, Str, _} = regexp:gsub(X,A,B),
+ {ok, Str, _} = re:gsub(X,A,B),
Str.
%%----------------------------------------------------------------------
@@ -758,7 +758,7 @@ set_remote_args(LogDir,PortsRange)->
{ok, PAList} = init:get_argument(pa),
PA = lists:flatmap(fun(A) -> [" -pa "] ++A end,PAList),
?DebugF("PA list ~p ~n", [PA]),
- {ok, Boot, _} = regexp:gsub(BootController,"tsung_controller","tsung"),
+ {ok, Boot, _} = re:gsub(BootController,"tsung_controller","tsung"),
?DebugF("Boot ~p~n", [Boot]),
Sys_Args= ts_utils:erl_system_args(),
LogDirEnc = encode_filename(LogDir),
View
24 src/tsung_recorder/ts_client_proxy.erl
@@ -117,13 +117,13 @@ handle_info({tcp, ClientSock, String}, State=#proxy{plugin=Plugin})
{noreply, NewState, ?lifetime};
% server data, send it to the client
-handle_info({Type, ServerSock, String}, State=#proxy{plugin=Plugin})
+handle_info({Type, ServerSock, Data}, State=#proxy{plugin=Plugin})
when ServerSock == State#proxy.serversock, ((Type == tcp) or (Type == ssl)) ->
ts_utils:inet_setopts(Type, ServerSock,[{active, once}]),
- ?LOGF("Received data from server: ~s~n",[String],?DEB),
- {ok,NewString} = Plugin:rewrite_serverdata(String),
- send(State#proxy.clientsock, NewString, Plugin),
- case regexp:first_match(NewString, "[cC]onnection: [cC]lose") of
+ ?LOGF("Received data from server: ~s~n",[Data],?DEB),
+ {ok,NewData} = Plugin:rewrite_serverdata(Data),
+ send(State#proxy.clientsock, NewData, Plugin),
+ case re:run(NewData, "[cC]onnection: [cC]lose",[{capture,none}]) of
nomatch ->
{noreply, State, ?lifetime};
_ ->
@@ -206,15 +206,15 @@ peername(Socket) -> prim_inet:peername(Socket).
send(_,[],_) -> ok; % no data
-send({sslsocket,A,B},String, Plugin) ->
- ?LOGF("Received data to send to an ssl socket ~p, using plugin ~p ~n", [String,Plugin],?DEB),
- {ok, RealString } = Plugin:rewrite_ssl({request,String}),
- ?LOGF("Sending data to ssl socket ~p ~p (~p)~n", [A, B, RealString],?DEB),
- ssl:send({sslsocket,A,B}, RealString);
+send({sslsocket,A,B},Data, Plugin) ->
+ ?LOGF("Received data to send to an ssl socket ~p, using plugin ~p ~n", [Data,Plugin],?DEB),
+ {ok, RealData } = Plugin:rewrite_ssl({request,Data}),
+ ?LOGF("Sending data to ssl socket ~p ~p (~p)~n", [A, B, RealData],?DEB),
+ ssl:send({sslsocket,A,B}, Data);
send(undefined,_,_) ->
?LOG("No socket ! Error ~n",?CRIT),
erlang:error(error_no_socket_open);
-send(Socket,String,_) ->
- gen_tcp:send(Socket,String).
+send(Socket,Data,_) ->
+ gen_tcp:send(Socket,Data).
View
4 src/tsung_recorder/ts_proxy_http.erl
@@ -172,7 +172,7 @@ relative_url(true,String,_RequestURI,_RelURL)->
relative_url(false,String,RequestURI,RelURL)->
[FullURL_noargs|_] = string:tokens(RequestURI,"?"),
[RelURL_noargs|_] = string:tokens(RelURL,"?"),
- {ok,RealString,_Count} = regexp:sub(String,FullURL_noargs,RelURL_noargs),
+ RealString = re:replace(String,FullURL_noargs,RelURL_noargs,[{return,list}]),
{ok, RealString}.
%%--------------------------------------------------------------------
@@ -349,7 +349,7 @@ record_header(Fd, Headers,HeaderName, Msg, Fun)->
end.
append_to_filename(Filename, From, To) ->
- case regexp:gsub(Filename,From,To ) of
+ case re:gsub(Filename,From,To ) of
{ok, RealName, _ } -> RealName;
_ -> Filename ++"." ++ To
end.
View
2 src/tsung_recorder/ts_proxy_recorder.erl
@@ -98,7 +98,7 @@ recordtag(Host, Args) when is_list(Args)->
init(Filename) ->
Date = ts_utils:datestr(),
%% add date to filename
- File = case regexp:gsub(Filename,"\.xml$", Date ++ ".xml") of %% "
+ File = case re:gsub(Filename,"\.xml$", Date ++ ".xml") of %% "
{ok, RealName, _ } -> RealName;
_ -> Date ++ "-" ++ Filename
end,
View
1 tsung-1.0.dtd
@@ -166,6 +166,7 @@ repeat | if | change_type )*>
<!ATTLIST dyn_variable
name CDATA #REQUIRED
xpath CDATA #IMPLIED
+ re CDATA #IMPLIED
jsonpath CDATA #IMPLIED
pgsql_expr CDATA #IMPLIED
regexp CDATA #IMPLIED >

0 comments on commit d03a220

Please sign in to comment.