Permalink
Browse files

http: user_agent is now customizable in the xml config file.

SVN Revision: 483
  • Loading branch information...
1 parent 6282132 commit c640d11e82aecac8f017d6dc5cb147fb58dc23db @nniclausse nniclausse committed Jul 11, 2005
View
@@ -42,13 +42,13 @@
unit (hour | minute | second) #REQUIRED
maxnumber NMTOKEN #IMPLIED>
-<!ELEMENT default EMPTY>
+<!ELEMENT default (user_agent*)>
<!ATTLIST default
name NMTOKEN #REQUIRED
override (true|false) #IMPLIED
random (true | false) #IMPLIED
type NMTOKEN #IMPLIED
- value CDATA #REQUIRED>
+ value CDATA #IMPLIED>
<!ELEMENT session ( request | thinktime | transaction )*>
<!ATTLIST session
@@ -68,6 +68,11 @@
random (true|false) #IMPLIED
value NMTOKEN #REQUIRED>
+<!ELEMENT user_agent (#PCDATA)*>
+<!ATTLIST user_agent
+ frequency CDATA #REQUIRED
+ >
+
<!ELEMENT transaction (request+)>
<!ATTLIST transaction name NMTOKEN #REQUIRED>
View
@@ -68,6 +68,11 @@
<default type="ts_jabber" name="username" value="glop"></default>
<default type="ts_jabber" name="passwd" value="glop"></default>
+ <default type="ts_http" name="user_agent">
+ <user_agent frequency="80">Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.8) Gecko/20050513 Galeon/1.3.21</user_agent>
+ <user_agent frequency="20">Mozilla/5.0 (Windows; U; Windows NT 5.2; fr-FR; rv:1.7.8) Gecko/20050511 Firefox/1.0.4</user_agent>
+ </default>
+
<!-- ********************************************** -->
<!-- start a session for a http user. the popularity is the
frequency of this type os session. The sum of all session's
View
@@ -30,21 +30,23 @@
url,
version="1.1", % default is HTTP/1.1
server_name, % use for the 'Host:' header
- get_ims_date, % used when the method is getims
- cookie=none,
- method=get,
- content_type=[],
- headers=[],
- body=[],
+ get_ims_date, % used when the method is getims
+ cookie = none,
+ method = get,
+ content_type = [],
+ headers = [],
+ body = [],
id = 0,
+ user_agent,
userid, % for www_authentication
passwd, % for www_authentication
soap_action % for SOAP support
}).
-record(http_dyndata,
{
- cookies=[] % HTTP Cookies
+ user_agent,
+ cookies = [] % HTTP Cookies
}
).
View
@@ -96,23 +96,27 @@ add_dynparams(true, DynData, Param, HostData) ->
NewParam = subst(Param, DynData#dyndata.dynvars),
add_dynparams(DynData#dyndata.proto,NewParam, HostData).
-% Function: add_dynparams/3
-% no cookies
-add_dynparams(#http_dyndata{cookies=[]},Param, {Host, 80}) -> % don't print port
- %in "Host:" if it's the default
- Param#http_request{server_name=Host};
-add_dynparams(#http_dyndata{cookies=[]},Param, {Host, Port}) ->
- Param#http_request{server_name=Host++":"++ integer_to_list(Port)};
-% cookies
-add_dynparams(#http_dyndata{cookies=DynData}, Param, {Host, 80}) ->
- Param#http_request{cookie=DynData,server_name=Host};
-add_dynparams(#http_dyndata{cookies=DynData}, Param, {Host, Port}) ->
+%% Function: add_dynparams/3
+%% no cookies
+add_dynparams(#http_dyndata{cookies=[], user_agent=UA},Param, {Host, 80}) ->
+ %% don't print port in "Host:" if it's the default
+ Param#http_request{server_name=Host, user_agent=UA};
+add_dynparams(#http_dyndata{cookies=[],user_agent=UA},Param, {Host, Port}) ->
+ Param#http_request{server_name=Host++":"++ integer_to_list(Port), user_agent=UA};
+%% cookies
+add_dynparams(#http_dyndata{cookies=DynData,user_agent=UA}, Param, {Host, 80}) ->
+ %% don't print port in "Host:" if it's the default
+ Param#http_request{cookie=DynData,server_name=Host, user_agent=UA};
+add_dynparams(#http_dyndata{cookies=DynData, user_agent=UA}, Param, {Host, Port}) ->
%% FIXME: should we use the Port value in the Cookie ?
- Param#http_request{cookie=DynData,
+ Param#http_request{cookie=DynData,user_agent=UA,
server_name=Host++":"++ integer_to_list(Port)}.
init_dynparams() ->
- #dyndata{proto=#http_dyndata{}}.
+ %% FIXME: optimization: suppress this call if we don't need
+ %% customised users agents
+ UserAgent = ts_session_cache:get_user_agent(),
+ #dyndata{proto=#http_dyndata{user_agent=UserAgent}}.
%%----------------------------------------------------------------------
@@ -47,24 +47,24 @@
%% Func: http_get/1
%% Args: #http_request
%%----------------------------------------------------------------------
-http_get(#http_request{url=URL, version=Version, cookie=Cookie,
+http_get(#http_request{url=URL, version=Version, cookie=Cookie, user_agent=UA,
get_ims_date=undefined, soap_action=SOAPAction,
server_name=Host, userid=UserId, passwd=Passwd})->
list_to_binary([?GET, " ", URL," ", "HTTP/", Version, ?CRLF,
"Host: ", Host, ?CRLF,
- user_agent(),
+ user_agent(UA),
authenticate(UserId,Passwd),
soap_action(SOAPAction),
set_cookie_header({Cookie, Host, URL}),
?CRLF]);
-http_get(#http_request{url=URL, version=Version, cookie=Cookie,
+http_get(#http_request{url=URL, version=Version, cookie=Cookie,user_agent=UA,
get_ims_date=Date, soap_action=SOAPAction,
server_name=Host, userid=UserId, passwd=Passwd}) ->
list_to_binary([?GET, " ", URL," ", "HTTP/", Version, ?CRLF,
["If-Modified-Since: ", Date, ?CRLF],
"Host: ", Host, ?CRLF,
- user_agent(),
+ user_agent(UA),
soap_action(SOAPAction),
authenticate(UserId,Passwd),
set_cookie_header({Cookie, Host, URL}),
@@ -74,15 +74,15 @@ http_get(#http_request{url=URL, version=Version, cookie=Cookie,
%% Func: http_post/1
%% Args: #http_request
%%----------------------------------------------------------------------
-http_post(#http_request{url=URL, version=Version, cookie=Cookie,
+http_post(#http_request{url=URL, version=Version, cookie=Cookie,user_agent=UA,
soap_action=SOAPAction, content_type=ContentType,
body=Content, server_name=Host,
userid=UserId, passwd=Passwd}) ->
ContentLength=integer_to_list(size(Content)),
?DebugF("Content Length of POST: ~p~n.", [ContentLength]),
Headers = [?POST, " ", URL," ", "HTTP/", Version, ?CRLF,
"Host: ", Host, ?CRLF,
- user_agent(),
+ user_agent(UA),
authenticate(UserId,Passwd),
soap_action(SOAPAction),
set_cookie_header({Cookie, Host, URL}),
@@ -101,8 +101,10 @@ authenticate(UserId,Passwd)->
AuthStr = httpd_util:encode_base64(lists:append([UserId,":",Passwd])),
["Authorization: Basic ",AuthStr,?CRLF].
-user_agent() ->
- ["User-Agent: ", ?USER_AGENT, ?CRLF].
+user_agent(undefined) ->
+ ["User-Agent: ", ?USER_AGENT, ?CRLF];
+user_agent(UA) ->
+ ["User-Agent: ", UA, ?CRLF].
soap_action(undefined) -> [];
soap_action(SOAPAction) -> ["SOAPAction: \"", SOAPAction, "\"", ?CRLF].
@@ -330,9 +332,10 @@ splitcookie([Char|Rest],Cur,Acc)->splitcookie(Rest, [Char|Cur], Acc).
%% Purpose: add new cookies to a list of old ones. If the keys already
%% exists, replace with the new ones
%%----------------------------------------------------------------------
-concat_cookies(New, DynData=#dyndata{proto=#http_dyndata{cookies=Cookies}}) ->
+concat_cookies(New, DynData=#dyndata{proto=HTTPDyn}) ->
+ Cookies = HTTPDyn#http_dyndata.cookies,
NewCookies = concat_cookies(New, Cookies),
- DynData#dyndata{proto=#http_dyndata{cookies=NewCookies}};
+ DynData#dyndata{proto=HTTPDyn#http_dyndata{cookies=NewCookies}};
concat_cookies([], DynData) -> DynData;
concat_cookies(New, []) -> New;
concat_cookies([New=#cookie{}|Rest], OldCookies)->
@@ -35,7 +35,7 @@
%%--------------------------------------------------------------------
%% External exports
--export([start/0, get_req/2]).
+-export([start/0, get_req/2, get_user_agent/0]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
@@ -63,6 +63,9 @@ start() ->
get_req(Id, Count)->
gen_server:call(?MODULE,{get_req, Id, Count}).
+get_user_agent()->
+ gen_server:call(?MODULE,{get_user_agent}).
+
%%====================================================================
%% Server functions
%%====================================================================
@@ -111,6 +114,24 @@ handle_call({get_req, Id, N}, From, State) ->
{reply, {error, Other}, State}
end;
+handle_call({get_user_agent}, From, State) ->
+ Tab = State#state.table,
+ case ets:lookup(Tab, {http_user_agent, value}) of
+ [] -> %% no match, ask the config_server
+ ?Debug("user agents not found in cache~n"),
+ UserAgents = ts_config_server:get_user_agents(),
+ %% cache the response FIXME: handle bad response ?
+ ?DebugF("Useragents: got from config_server~p~n",[UserAgents]),
+ ets:insert(Tab, {{http_user_agent, value}, UserAgents}),
+ {ok, Reply} = choose_user_agent(UserAgents),
+ {reply, Reply, State};
+ [{_, [{_Freq, Value}]}] -> %single user agent defined
+ {reply, Value, State};
+ [{_, UserAgents }] when is_list(UserAgents)->
+ {ok, Reply} = choose_user_agent(UserAgents),
+ {reply, Reply, State}
+ end;
+
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
@@ -155,3 +176,12 @@ code_change(_OldVsn, State, _Extra) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
+
+choose_user_agent(UserAgents) ->
+ choose_user_agent(UserAgents, random:uniform(100),0).
+
+choose_user_agent([{P, Val} | _],Rand, Cur) when Rand =< P+Cur->
+ {ok, Val};
+choose_user_agent([{P, _Val} | SList], Rand, Cur) ->
+ choose_user_agent(SList, Rand, Cur+P).
+
@@ -43,6 +43,7 @@
-export([read/1,
getAttr/2,
getAttr/3,
+ getText/1,
parse/2,
get_default/3,
mark_prev_req/3
@@ -107,9 +107,26 @@ parse_config(Element = #xmlElement{name=default}, Conf = #config{session_tab = T
case ts_config:getAttr(Element#xmlElement.attributes, name) of
"server_name" ->
Val = ts_config:getAttr(Element#xmlElement.attributes, value),
- ets:insert(Tab,{{http_server_name, value}, Val})
+ ets:insert(Tab,{{http_server_name, value}, Val});
+ "user_agent" ->
+ Val = ts_config:getAttr(Element#xmlElement.attributes, value), %FIXME: useless
+ lists:foldl( fun(A,B)->parse_config(A,B) end, Conf, Element#xmlElement.content)
end,
lists:foldl( fun(A,B)->ts_config:parse(A,B) end, Conf, Element#xmlElement.content);
+%% Parsing user_agent
+parse_config(Element = #xmlElement{name=user_agent}, Conf = #config{session_tab = Tab}) ->
+ FreqStr= ts_config:getAttr(Element#xmlElement.attributes, frequency),
+ [Val]= ts_config:getText(Element#xmlElement.content),
+ {ok, [{integer,1,Freq}],1} = erl_scan:string(FreqStr),
+ ?LOGF("Get user agent: ~p ~p ~n",[Freq, Val],?WARN),
+ Previous = case ets:lookup(Tab, {http_user_agent, value}) of
+ [] ->
+ [];
+ [{Key,Old}] ->
+ Old
+ end,
+ ets:insert(Tab,{{http_user_agent, value}, [{Freq, Val}|Previous]}),
+ lists:foldl( fun(A,B)->parse_config(A,B) end, Conf, Element#xmlElement.content);
%% Parsing other elements
parse_config(Element = #xmlElement{}, Conf = #config{}) ->
ts_config:parse(Element,Conf);
@@ -50,7 +50,7 @@
-export([start_link/1, read_config/1, get_req/2, get_next_session/1,
get_client_config/1, newbeam/1, newbeam/2, get_server_config/0,
get_monitor_hosts/0, encode_filename/1, decode_filename/1,
- endlaunching/1, status/0, start_file_server/1]).
+ endlaunching/1, status/0, start_file_server/1, get_user_agents/0]).
%%debug
-export([choose_client_ip/2, choose_session/1]).
@@ -103,6 +103,14 @@ get_req(Id, Count)->
gen_server:call({global, ?MODULE},{get_req, Id, Count}).
%%--------------------------------------------------------------------
+%% Function: get_user_agents/0
+%% Description:
+%% Returns: List
+%%--------------------------------------------------------------------
+get_user_agents()->
+ gen_server:call({global, ?MODULE},{get_user_agents}).
+
+%%--------------------------------------------------------------------
%% Function: read_config/1
%% Description: Read Config file
%% Returns: ok | {error, Reason}
@@ -209,6 +217,16 @@ handle_call({get_req, Id, N}, From, State) ->
{reply, {error, Other}, State}
end;
+%%
+handle_call({get_user_agents}, From, State) ->
+ Config = State#state.config,
+ case ets:lookup(Config#config.session_tab, {http_user_agent, value}) of
+ [] ->
+ {reply, empty, State};
+ [{_Key, UserAgents}] ->
+ {reply, UserAgents, State}
+ end;
+
%% get a new session id and an ip for the given node
handle_call({get_next_session, HostName}, From, State) ->
Config = State#state.config,

0 comments on commit c640d11

Please sign in to comment.