ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/myhttpd/access.pl
Revision: 1.19
Committed: Mon Dec 3 04:57:22 2001 UTC (22 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.18: +37 -15 lines
Log Message:
*** empty log message ***

File Contents

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