ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/myhttpd/access.pl
Revision: 1.25
Committed: Tue Dec 4 03:43:54 2001 UTC (22 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.24: +3 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.11 package transferqueue;
2    
3 root 1.24 my @reserve = (
4 root 1.25 [ 1_200_000, 1],
5     [ 3_000_000, 1],
6     [ 75_000_000, 1],
7 root 1.24 );
8    
9 root 1.11 sub new {
10     my $class = shift;
11     bless {
12 root 1.19 slots => $_[0],
13     lastspb => 0,
14 root 1.20 avgspb => 0,
15 root 1.11 }, $class;
16     }
17    
18     sub start_transfer {
19     my $self = shift;
20 root 1.19 my $size = $_[0];
21 root 1.11
22 root 1.20 my $transfer = bless {
23 root 1.22 queue => $self,
24     time => $::NOW,
25     size => $size,
26     coro => $Coro::current,
27     started => 0,
28 root 1.19 }, transfer::;
29 root 1.11
30 root 1.20 push @{$self->{wait}}, $transfer;
31 root 1.11
32 root 1.19 $self->wake_next;
33 root 1.11
34 root 1.22 $transfer;
35     }
36    
37     sub sort {
38     my @queue = grep $_, @{$_[0]{wait}};
39    
40     $_->{spb} = ($::NOW-$_->{time}) / ($_->{size} || 1) for @queue;
41    
42     $_[0]{wait} = [sort { $b->{spb} <=> $a->{spb} } @queue];
43    
44     Scalar::Util::weaken $_ for @{$_[0]{wait}};
45 root 1.11 }
46    
47     sub wake_next {
48     my $self = shift;
49    
50 root 1.19 $self->sort;
51    
52 root 1.24 while (@{$self->{wait}}) {
53     my $size = $self->{wait}[0]{size};
54     my $min = 0;
55     for (@reserve) {
56     last if $size <= $_->[0];
57     $min += $_->[1];
58     }
59     last unless $self->{slots} > $min;
60 root 1.18 my $transfer = shift @{$self->{wait}};
61 root 1.24 $self->{lastspb} = $transfer->{spb};
62     $self->{avgspb} ||= $transfer->{spb};
63     $self->{avgspb} = $self->{avgspb} * 0.95 + $transfer->{spb} * 0.05;
64     $self->{started}++;
65     $transfer->wake;
66     last;
67 root 1.13 }
68 root 1.19 }
69    
70 root 1.11 sub waiters {
71 root 1.19 $_[0]->sort;
72     @{$_[0]{wait}};
73 root 1.11 }
74    
75     package transfer;
76    
77     use Coro::Timer ();
78    
79 root 1.16 sub wake {
80     my $self = shift;
81 root 1.19
82     $self->{alloc} = 1;
83     $self->{queue}{slots}--;
84     $self->{wake} and $self->{wake}->ready;
85 root 1.16 }
86    
87 root 1.11 sub try {
88     my $self = shift;
89    
90 root 1.19 $self->{alloc} || do {
91 root 1.16 my $timeout = Coro::Timer::timeout $_[0];
92 root 1.19 local $self->{wake} = $self->{coro};
93 root 1.16
94 root 1.15 Coro::schedule;
95 root 1.19
96     $self->{alloc};
97 root 1.15 }
98 root 1.11 }
99    
100     sub DESTROY {
101     my $self = shift;
102 root 1.19
103     if ($self->{alloc}) {
104     $self->{queue}{slots}++;
105     $self->{queue}->wake_next;
106     }
107 root 1.11 }
108    
109 root 1.8 package conn;
110 root 1.1
111 root 1.8 our %blockuri;
112     our $blockref;
113 root 1.1
114 root 1.6 sub read_blockuri {
115 root 1.1 local *B;
116     my %group;
117 root 1.8 %blockuri = ();
118 root 1.6 if (open B, "<blockuri") {
119 root 1.1 while (<B>) {
120     chomp;
121     if (/^group\s+(\S+)\s+(.*)/i) {
122     $group{$1} = [split /\s+/, $2];
123     } elsif (/^!([^\t]*)\t\s*(.*)/) {
124     my $g = $1;
125     my @r;
126     for (split /\s+/, $2) {
127     push @r, $group{$_} ? @{$group{$_}} : $_;
128     }
129     print "not($g) => (@r)\n";
130 root 1.8 push @{$blockuri{$_}}, $g for @r;
131 root 1.6 push @blockuri, [qr/$g/i, \@r];
132 root 1.1 } elsif (/\S/) {
133 root 1.6 print "blockuri: unparsable line: $_\n";
134 root 1.1 }
135     }
136 root 1.8 for (keys %blockuri) {
137     my $qr = join ")|(?:", @{$blockuri{$_}};
138     $blockuri{$_} = qr{(?:$qr)}i;
139     }
140 root 1.1 } else {
141 root 1.6 print "no blockuri\n";
142 root 1.1 }
143     }
144    
145 root 1.6 sub read_blockref {
146     local *B;
147 root 1.8 my @blockref;
148 root 1.6 if (open B, "<blockreferer") {
149     while (<B>) {
150     chomp;
151     if (/^([^\t]*)\t\s*(.*)/) {
152 root 1.8 push @blockref, $1;
153 root 1.6 } elsif (/\S/) {
154     print "blockref: unparsable line: $_\n";
155     }
156     }
157 root 1.8 $blockref = join ")|(?:", @blockref;
158     $blockref = qr{^(?:$blockref)}i;
159 root 1.6 } else {
160     print "no blockref\n";
161 root 1.8 $blockref = qr{^x^};
162 root 1.6 }
163     }
164    
165     read_blockuri;
166     read_blockref;
167 root 1.1
168 root 1.5 use Tie::Cache;
169 root 1.10 tie %whois_cache, Tie::Cache::, 32;
170 root 1.1
171 root 1.8 sub access_check {
172 root 1.6 my $self = shift;
173    
174     my $ref = $self->{h}{referer};
175     my $uri = $self->{path};
176     my %disallow;
177    
178 root 1.8 $self->err_block_referer
179     if $self->{h}{referer} =~ $blockref;
180 root 1.6
181     my $whois = $whois_cache{$self->{remote_addr}}
182 root 1.9 ||= netgeo::ip_request($self->{remote_addr});
183 root 1.6
184     my $country = "XX";
185    
186     if ($whois =~ /^\*cy: (\S+)/m) {
187     $country = uc $1;
188     } else {
189     $self->slog(9, "no country($whois)");
190     }
191    
192     $self->{country} = $country;
193    
194 root 1.8 $self->err_block_country($whois)
195     if $self->{path} =~ $blockuri{$country};
196 root 1.1 }
197    
198     1;