1 #***************************************************************************
3 # Project ___| | | | _ \| |
5 # | (__| |_| | _ <| |___
6 # \___|\___/|_| \_\_____|
8 # Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
10 # This software is licensed as described in the file COPYING, which
11 # you should have received as part of this distribution. The terms
12 # are also available at https://curl.se/docs/copyright.html.
14 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 # copies of the Software, and permit persons to whom the Software is
16 # furnished to do so, under the terms of the COPYING file.
18 # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 # KIND, either express or implied.
21 # SPDX-License-Identifier: curl
23 #***************************************************************************
25 # This perl module contains functions useful in writing test servers.
33 use base qw(Exporter);
54 # sub second timestamping needs Time::HiRes
58 import Time::HiRes qw( gettimeofday );
63 our $logfile; # server log file name, for logmsg
65 #***************************************************************************
66 # Just for convenience, test harness uses 'https' and 'httptls' literals as
67 # values for 'proto' variable in order to differentiate different servers.
68 # 'https' literal is used for stunnel based https test servers, and 'httptls'
69 # is used for non-stunnel https test servers.
71 #**********************************************************************
72 # logmsg is general message logging subroutine for our test servers.
76 # sub second timestamping needs Time::HiRes
77 if($Time::HiRes::VERSION) {
78 my ($seconds, $usec) = gettimeofday();
79 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
81 $now = sprintf("%02d:%02d:%02d.%06d ", $hour, $min, $sec, $usec);
85 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
87 $now = sprintf("%02d:%02d:%02d ", $hour, $min, $sec);
89 if(open(my $logfilefh, ">>", "$logfile")) {
90 print $logfilefh $now;
97 #***************************************************************************
98 # Return server characterization factors given a server id string.
107 /^((ftp|http|imap|pop3|smtp|http-pipe)s?)(\d*)(-ipv6|)$/) {
109 $idnum = ($3 && ($3 > 1)) ? $3 : 1;
110 $ipvnum = ($4 && ($4 =~ /6$/)) ? 6 : 4;
113 /^(tftp|sftp|socks|ssh|rtsp|gopher|httptls)(\d*)(-ipv6|)$/) {
115 $idnum = ($2 && ($2 > 1)) ? $2 : 1;
116 $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
119 die "invalid server id: '$server'"
121 return($proto, $ipvnum, $idnum);
125 #***************************************************************************
126 # Return server name string formatted for presentation purposes
129 my ($proto, $ipver, $idnum) = @_;
131 $proto = uc($proto) if($proto);
132 die "unsupported protocol: '$proto'" unless($proto &&
133 ($proto =~ /^(((FTP|HTTP|HTTP\/2|HTTP\/3|IMAP|POP3|GOPHER|SMTP|HTTP-PIPE)S?)|(TFTP|SFTP|SOCKS|SSH|RTSP|HTTPTLS|DICT|SMB|SMBS|TELNET|MQTT))$/));
135 $ipver = (not $ipver) ? 'ipv4' : lc($ipver);
136 die "unsupported IP version: '$ipver'" unless($ipver &&
137 ($ipver =~ /^(4|6|ipv4|ipv6|-ipv4|-ipv6|unix)$/));
138 $ipver = ($ipver =~ /6$/) ? '-IPv6' : (($ipver =~ /unix$/) ? '-unix' : '');
140 $idnum = 1 if(not $idnum);
141 die "unsupported ID number: '$idnum'" unless($idnum &&
142 ($idnum =~ /^(\d+)$/));
143 $idnum = '' if($idnum <= 1);
145 return "${proto}${idnum}${ipver}";
149 #***************************************************************************
150 # Return server name string formatted for identification purposes
153 my ($proto, $ipver, $idnum) = @_;
154 return lc(servername_str($proto, $ipver, $idnum));
158 #***************************************************************************
159 # Return server name string formatted for file name purposes
161 sub servername_canon {
162 my ($proto, $ipver, $idnum) = @_;
163 my $string = lc(servername_str($proto, $ipver, $idnum));
170 #***************************************************************************
171 # Return file name for server pid file.
173 sub server_pidfilename {
174 my ($piddir, $proto, $ipver, $idnum) = @_;
175 my $trailer = '_server.pid';
176 return "${piddir}/". servername_canon($proto, $ipver, $idnum) ."$trailer";
179 #***************************************************************************
180 # Return file name for server port file.
182 sub server_portfilename {
183 my ($piddir, $proto, $ipver, $idnum) = @_;
184 my $trailer = '_server.port';
185 return "${piddir}/". servername_canon($proto, $ipver, $idnum) ."$trailer";
189 #***************************************************************************
190 # Return file name for server log file.
192 sub server_logfilename {
193 my ($logdir, $proto, $ipver, $idnum) = @_;
194 my $trailer = '_server.log';
195 $trailer = '_stunnel.log' if(lc($proto) =~ /^(ftp|http|imap|pop3|smtp)s$/);
196 return "${logdir}/". servername_canon($proto, $ipver, $idnum) ."$trailer";
200 #***************************************************************************
201 # Return file name for server commands file.
203 sub server_cmdfilename {
204 my ($logdir, $proto, $ipver, $idnum) = @_;
205 my $trailer = '_server.cmd';
206 return "${logdir}/". servername_canon($proto, $ipver, $idnum) ."$trailer";
210 #***************************************************************************
211 # Return file name for server input file.
213 sub server_inputfilename {
214 my ($logdir, $proto, $ipver, $idnum) = @_;
215 my $trailer = '_server.input';
216 return "${logdir}/". servername_canon($proto, $ipver, $idnum) ."$trailer";
220 #***************************************************************************
221 # Return file name for server output file.
223 sub server_outputfilename {
224 my ($logdir, $proto, $ipver, $idnum) = @_;
225 my $trailer = '_server.output';
226 return "${logdir}/". servername_canon($proto, $ipver, $idnum) ."$trailer";
230 #***************************************************************************
231 # Return file name for main or primary sockfilter pid file.
233 sub mainsockf_pidfilename {
234 my ($piddir, $proto, $ipver, $idnum) = @_;
235 die "unsupported protocol: '$proto'" unless($proto &&
236 (lc($proto) =~ /^(ftp|imap|pop3|smtp)s?$/));
237 my $trailer = (lc($proto) =~ /^ftps?$/) ? '_sockctrl.pid':'_sockfilt.pid';
238 return "${piddir}/". servername_canon($proto, $ipver, $idnum) ."$trailer";
242 #***************************************************************************
243 # Return file name for main or primary sockfilter log file.
245 sub mainsockf_logfilename {
246 my ($logdir, $proto, $ipver, $idnum) = @_;
247 die "unsupported protocol: '$proto'" unless($proto &&
248 (lc($proto) =~ /^(ftp|imap|pop3|smtp)s?$/));
249 my $trailer = (lc($proto) =~ /^ftps?$/) ? '_sockctrl.log':'_sockfilt.log';
250 return "${logdir}/". servername_canon($proto, $ipver, $idnum) ."$trailer";
254 #***************************************************************************
255 # Return file name for data or secondary sockfilter pid file.
257 sub datasockf_pidfilename {
258 my ($piddir, $proto, $ipver, $idnum) = @_;
259 die "unsupported protocol: '$proto'" unless($proto &&
260 (lc($proto) =~ /^ftps?$/));
261 my $trailer = '_sockdata.pid';
262 return "${piddir}/". servername_canon($proto, $ipver, $idnum) ."$trailer";
266 #***************************************************************************
267 # Return file name for data or secondary sockfilter log file.
269 sub datasockf_logfilename {
270 my ($logdir, $proto, $ipver, $idnum) = @_;
271 die "unsupported protocol: '$proto'" unless($proto &&
272 (lc($proto) =~ /^ftps?$/));
273 my $trailer = '_sockdata.log';
274 return "${logdir}/". servername_canon($proto, $ipver, $idnum) ."$trailer";
278 #***************************************************************************