6 delayer - Squid external acl helper adding artificial delay to requests
10 delayer [--help] [--debug] [--log file] [--wait msec]
16 =item B<--help> or B<-h>
18 Print help message to stdout
20 =item B<--debug> or B<-d>
22 Emit debugging output to STDERR and ultimately cache.log
24 =item B<--log /path/to/file> or B<-l /path/to/file>
26 Emit debugging output to specified file instead of STDERR. Also turns on debugging
28 =item B<--wait msec> or B<-w msec>
30 Delay each request by the specified amount of msec.
31 Unless this option is specified, by default each submitted request
32 will be delayed by half a second (500 msec).
38 Squid external acl helper; causes squid to delay responding to HTTP requests.
40 By carefully crafting the ACLs of a Squid setup it is possible to
41 selectively delay requests received by a proxy. After the configured amount
42 of time, it will always return "true".
46 To engage it, this snippet of configuration template can be used in squid.conf:
48 external_acl_type delayer concurrency=100000 children-max=2 children-startup=1 children-idle=1 cache=10 %URI /path/to/delayer -w 200
49 acl delay external delayer
50 http_access allow acl1 acl2 acl3 delay !all
52 It is important that the acl referencing the delayer be the penultimate clause in the
53 http_access line. It will cause delay to all requests that match all the
54 preceding acls in the line. The !all clause at the end of the line will make it
55 so that no traffic is authorized by this ACL, only the delay to evaluate
56 the delay clause will be inserted before evaluating following http_access lines.
57 It is also important to place the http_access line carefully in the sequence
58 of all http_access_lines; it should be near the beginning, but be careful
59 not to insert unwanted slow acls (especially proxy_auth).
61 It is possible to customize how delay is calculated for each request by
62 modifying the "calc_delay" PERL function in the script, documentation on this
63 is embedded in the source code comments.
67 This software is written by Francesco Chemolli <kinkie@squid-cache.org>
71 (C) 2014 Francesco Chemolli <kinkie@squid-cache.org>
73 This program is free software. You may redistribute copies of it under the
74 terms of the GNU General Public License version 2, or (at your opinion) any
79 Questions on this code are best addressed on the Squid-users mailing list
80 <squid-users@squid-cache.org>
84 Bug reports need to be made in English.
85 See http://wiki.squid-cache.org/SquidFaq/BugReporting for details of what you
86 need to include with your bug report.
87 Report bugs or bug fixes using http://bugs.squid-cache.org/
91 B<squid>(8), B<GPL>(7), B<Squid Wiki> http://wiki.squid-cache.org/ ,
92 B<Squid Configuration Manual> http://www.squid-cache.org/Doc/config/
98 use Getopt
::Long
qw(:config auto_version auto_help);
100 use Time
::HiRes
qw(gettimeofday tv_interval);
103 my %opts = (); #for getopt
104 my $debug = 0; #debug
105 my $logfile = *STDERR
; #filehandle to logfile
107 my $delay = 500; #in milliseconds. Configurable with the -w option.
108 #for custom delay algorithms, you can customize the dispatch_request function
110 #calculate the delay for the request.
111 # Gets as input the verbatim full line received from squid
112 # (channel number and all, as configured in squid.conf) and returns
113 # a floating point number >= 0 which is the delay to be applied to the request
115 # Notice that in order to have efficient data structures, the delay is
116 # assumed to be monotonously growing. In other words, a long-delay
117 # item will stall the queue until completed. Supporting generic delays
118 # requires transforming @queue from a FIFO to a priority queue.
123 GetOptions
("debug|d" => \
$debug,
124 "wait|w=i" => \
$delay,
125 "log|l=s" => \
$logfilename)
126 or die("Error in parsing command line arguments");
127 if (defined $opts{h
}) {
131 $delay /= 1000.0; # transform msec into sec
133 open ($logfile,">>", "$opts{l}");
137 my @p=split(/[\\\/]/,$0);
138 my $prg_basename=pop @p;
139 $prg_basename .= "[$$]";
141 my $reqid=0; #sequence number for requests
143 # variables initialization for select
145 vec($rvec,0,1) = 1; #stdin
146 my ($nfound, $rd, $nread, $req);
149 my @queue = (); # array of references to hashes, with keys chan, when, req, reqid
152 $SIG{HUP
} = \
&dump_state
;
154 #disable IO buffering
156 my $fh=select($logfile); $|=1; select($fh); undef($fh);
158 # takes a result from a gettimeofday call and turns it into a
159 # floating-point number suitable for approximate time calculations and select
161 return $_[0]+$_[1]/1000000;
164 sub dispatch_request
{
167 &debug
("got request: '$r'");
170 @fields = split (/\s+/, $r);
171 $evt{when} = &calc_delay
($r)+fract_time
(gettimeofday
());
172 $evt{reqid
}=$reqid++;
174 $evt{chan
} = $fields[0];
175 &debug
("Dispatching: reqid $evt{reqid}, chan $evt{chan}, when $evt{when}, raw {$evt{req}}");
180 my $now = fract_time
(gettimeofday
());
182 my $when = $queue[0]->{when} - $now;
183 &debug
("Next event is in $when seconds");
186 &debug
("No events in queue");
191 my $now = fract_time
(gettimeofday
());
193 &debug
("Queue length is $#queue");
194 last if ($queue[0]->{when} > $now);
195 my %evt = %{shift @queue};
196 &debug
("Event: reqid $evt{reqid}, chan $evt{chan}, when $evt{when}, raw {$evt{req}}");
197 print $evt{chan
} , " OK\n";
204 $nfound = select($rd = $rvec,undef,undef,&next_event
());
205 &debug
("found $nfound bits set");
206 if ($nfound == -1 ) {
207 next if ($!{ERESTART
} || $!{EAGAIN
} || $!{EINTR
});
208 &debug
("error in select: $!");
211 if (vec($rd,0,1)==1) { #got stuff from stdin
213 $nread = sysread(STDIN
,$d,40960); # read 40kb
214 # clear the signal-bit, stdin is special
217 &debug
("nothing read from stdin, exiting");
221 while ($i = index($d,"\n")) { #BUG: assumption of no spill-over
223 &dispatch_request
(substr($d,0,$i));
231 delay
-adding external acl helper
232 authorizes all requests
, adding a delay before doing so
.
233 supports multiplexed helper protocol
.
235 -h
, --help
: this help message
236 -d
, --debug
: enable debug output
237 -l
<file
>, --log <file
>: log output to named file instead of stderr
(implies debug
)
238 -w
<num
>, --wait <num
> delay
each request by this number milliseconds
240 AUTHOR
: Francesco Chemolli
<kinkie\
@squid-cache
.org
>
241 Licensed under the terms of the GNU GPL v2
or later
(see source
for details
)
243 our $VERSION = "1.0";
250 $SIG{HUP
} = \
&dump_state
;
251 print STDERR
"Queue:\n",Dumper
(\
@queue),"\n";
255 return unless ($debug);
256 print $logfile $prg_basename , ": ", @_, "\n";