By user13334066 on Qer 21, 2006
Here, instead of using the nsh SAF, the set_write_filter SAF is used to get the script executed during Output stage. As blocks of data get written to the client, the script gets executed for each block. The contents of the current data block is accessible to the script as a "magic" variable, _chunk.
Anyway as far as the script's logic is concerned, it's pretty simple - keep a tab on the current download speed always, and if it ever climbs beyond a particular max limit, delay the proceedings by sleeping for a particular amount of time. Crude, yes - but it works.
# # Bandwidth control script # if $total == "" then # # Ok this is the first time we are getting called for a particular download. # Set download rate limit to 50 kbps (or whatever), and note the start time. # total = 0 if test $sn.client.ip == "192.168.\*" then # Higher limit for local network! maxkbps = 256 else # And that's for the rest... maxkbps = 50 fi tstart = millisecondsnow fi if $_chunk != "" then # # Find the length of this particular chunk being passed to the client, calculate # the total size transferred, the total time elapsed, and find the current download # rate. If it is more than the max limit which we would like to impose, then sleep # the required amount of time before proceeding. # len = length $_chunk total = expr $total + $len tnow = millisecondsnow ttaken = expr $tnow - $tstart if test $ttaken > 0 then kbps = expr $total / $ttaken if test $kbps >= $maxkbps then tnew = expr $total / $maxkbps tsleep = expr $tnew - $ttaken millisleep $tsleep fi fi else # # _chunk being null indicates that the download is over, and we are being called for # the last time for this particular request. Print some stats and get out. # tnow = millisecondsnow ttaken = expr $tnow - $tstart if test $ttaken > 0 then kbps = expr $total / $ttaken log inform "served $rq.reqpb.uri at $kbps kbytes per second" fi fi
The script assumes 192.168.\* to be the local network, and if the client IP matches that, a higher download speed is allowed.
And of course, the obj.conf should be configured to setup the Filter stage accordingly:
Init fn="load-modules" shlib="/someplace/libnsh.so" funcs="nsh,set_write_filter" < Object name="default"> .. .. Output fn="set_write_filter" script="/somewhere/bandwidth.sh" .. .. < / Object>