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