1%%%  This code was developped by IDEALX (http://IDEALX.org/) and
2%%%  contributors (their names can be found in the CONTRIBUTORS file).
3%%%  Copyright (C) 2000-2001 IDEALX
4%%%
5%%%  This program is free software; you can redistribute it and/or modify
6%%%  it under the terms of the GNU General Public License as published by
7%%%  the Free Software Foundation; either version 2 of the License, or
8%%%  (at your option) any later version.
9%%%
10%%%  This program is distributed in the hope that it will be useful,
11%%%  but WITHOUT ANY WARRANTY; without even the implied warranty of
12%%%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13%%%  GNU General Public License for more details.
14%%%
15%%%  You should have received a copy of the GNU General Public License
16%%%  along with this program; if not, write to the Free Software
17%%%  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
18%%%
19%%%  In addition, as a special exception, you have the permission to
20%%%  link the code of this program with any library released under
21%%%  the EPL license and distribute linked combinations including
22%%%  the two; the MPL (Mozilla Public License), which EPL (Erlang
23%%%  Public License) is based on, is included in this exception.
24
25-vc('$Id$ ').
26-author('nicolas.niclausse@niclux.org').
27
28-record(match,
29        { regexp,
30          subst = false,
31         'when' = false,
32		  name,
33          do    = continue, %(continue | loop | abort | log )
34          sleep_loop,       % in seconds
35          apply_to_content,
36          skip_headers = no,
37          max_loop,
38          loop_back,
39          max_restart
40       }).
41
42-record(ts_request,
43        {
44         ack,
45         subst=false,
46         match=[],
47         dynvar_specs=[], % [] | [{VarName, Regexp} |...]
48         param,
49         endpage=false,
50         host,       % override global server hostname
51         port,       % override global server port
52         scheme      % override global server type (ssl or gen_tcp)
53        }).
54
55% protocol options
56-record(proto_opts,
57        {ssl_ciphers   = negotiate, % for ssl only
58         ssl_versions  = negotiate, % for ssl only
59         bosh_path = "/http-bind/",  % for bash only
60         tcp_reuseaddr  = false,  % for tcp reuseaddr
61         tcp_reuseport  = false,  % for tcp reuseport
62         ip_transparent = false,  % set IP_TRANSPARENT option on the socket
63         websocket_path = "/chat",  % for websocket only
64         websocket_frame = "binary",  % for websocket only
65         websocket_subprotocols = [],     % for websocket only
66         retry_timeout = 10,        % retry sending in milliseconds
67         max_retries = 3,           % maximum number of retries
68         idle_timeout  = 600000,    % timeout for local ack
69         connect_timeout  = infinity,   % timeout for gen_tcp:connect/4 (infinity OR time in milliseconds)
70         global_ack_timeout = infinity, % timeout for global ack
71         tcp_rcv_size  = 32768,     % tcp buffers size
72         tcp_snd_size  = 32768,
73         udp_rcv_size  = 32768,     % udp buffers size
74         udp_snd_size  = 32768,
75         certificate = [],          % for ssl
76         reuse_sessions = true,     % for ssl
77         is_first_connect = true   % whether it's the first connection
78        }).
79
80-record(token_bucket,
81        {rate,
82         burst,
83         last_packet_date = 0,
84         current_size     = 0
85         }).
86-define(size_mon_thresh, 524288).   % 512KB
87-define(short_timeout, 1).
88
89% state of ts_client gen_server
90-record(state_rcv,
91        {socket=none, %
92         ip,          % local ip to bind to
93         timeout,     % ?
94         retries=0,   % number of connect retries
95         hibernate = 10000, % hibernate if thinktime is >= to this (10sec by default)
96         host,        % hostname (or IP) of remote server
97         port,        % server port
98         protocol,    % gen_udp, gen_tcp or ssl
99         proto_opts = #proto_opts{},  %
100         bidi = false,% true if bidirectional protocol
101
102         session_id,
103         request,     % current request specs
104         persistent,  % if true, don't exit when connection is closed
105         timestamp,   % previous message date
106         starttime,   % date of the beginning of the session
107         count,       % number of requests waiting to be sent
108         maxcount,        % number of requests waiting to be sent
109         ack_done=false,  % 'true' if the ack was sent, else 'false' (unused if ack=no_ack)
110         send_timestamp,  % date when the 'request' was sent
111         page_timestamp=0,% date when the first 'request' of a page was sent
112         acc=[],     % Accumulator to store temporary unparsable data
113                     % (Waiting for more data)
114         buffer = <<>>, % buffer when we have to keep the response (we need
115                     % all the response to do pattern matching)
116         session,    % record of session status; depends on 'clienttype' (can be
117                     % used to store data dynamically generated during the
118                     % session (e.g. cookies))
119         datasize=0,
120         id,         % user id
121         size_mon_thresh=?size_mon_thresh, % if rcv data is > to this, update stats
122         size_mon=0, % current size (used for threshold computation)
123         dynvars=[], %
124         clienttype, % module name (ts_jabber, etc.)
125         transactions=[], % current transactions
126         rate_limit, % rate limiting parameters
127         dump        % type of dump (full, light, none)
128        }).
129
130-record(phase,
131        {
132          id ,
133          intensity,
134          nusers,      % total number of users to start in the current phase
135          duration,    % expected phase duration
136          start,       % timestamp.
137          wait_all_sessions_end = false % wait for all users to finish before launching next session
138        }).
139
140-record(launcher,
141        {nusers,
142         phases = [],
143         current_phase = #phase{},
144         myhostname,
145         static_done = false,
146         started_users = 0,
147         start_date,
148         short_timeout = ?short_timeout,
149         maxusers %% if maxusers are currently active, launch a
150                  %% new beam to handle the new users
151        }).
152