ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Coro/myhttpd/access.pl
(Generate patch)

Comparing cvsroot/Coro/myhttpd/access.pl (file contents):
Revision 1.6 by root, Sun Aug 19 23:57:52 2001 UTC vs.
Revision 1.28 by root, Thu Jan 3 01:20:17 2002 UTC

1package transferqueue;
1 2
3my @reserve = (
4 [ 1_200_000, 2],
5 [ 8_000_000, 1],
6 [ 75_000_000, 1],
7);
8
9sub new {
10 my $class = shift;
11 my $self = bless {
12 slots => 1,
13 maxsize => 0,
14 lastspb => 0,
15 avgspb => 0,
16 @_,
17 }, $class;
18 $self->{reschedule} = Event->timer(
19 after => 10,
20 interval => 3,
21 cb => sub { $self->wake_next },
22 );
23 $self;
24}
25
26sub start_transfer {
27 my $self = shift;
28 my $size = $_[0];
29
30 if ($self->{maxsize} && $self->{maxsize} < $size) {
31 $size = $self->{maxsize};
32 }
33
34 my $transfer = bless {
35 queue => $self,
36 time => $::NOW,
37 size => $size,
38 coro => $Coro::current,
39 started => 0,
40 }, transfer::;
41
42 push @{$self->{wait}}, $transfer;
43
44 $self->wake_next;
45
46 $transfer;
47}
48
49sub sort {
50 my @queue = grep $_, @{$_[0]{wait}};
51
52 $_->{spb} = ($::NOW-$_->{time}) / ($_->{size} || 1) for @queue;
53
54 $_[0]{wait} = [sort { $b->{spb} <=> $a->{spb} } @queue];
55
56 Scalar::Util::weaken $_ for @{$_[0]{wait}};
57}
58
59sub wake_next {
60 my $self = shift;
61
62 $self->sort;
63
64 while (@{$self->{wait}}) {
65 my $size = $self->{wait}[0]{size};
66 my $min = 0;
67 for (@reserve) {
68 last if $size <= $_->[0];
69 $min += $_->[1];
70 }
71 last unless $self->{slots} > $min;
72 my $transfer = shift @{$self->{wait}};
73 $self->{lastspb} = $transfer->{spb};
74 $self->{avgspb} = $self->{avgspb} * 0.99 + $transfer->{spb} * 0.01;
75 $self->{started}++;
76 $transfer->wake;
77 last;
78 }
79}
80
81sub waiters {
82 $_[0]->sort;
83 @{$_[0]{wait}};
84}
85
86sub DESTROY {
87 my $self = shift;
88
89 $self->{reschedule}->cancel;
90}
91
92package transfer;
93
94use Coro::Timer ();
95
96sub wake {
97 my $self = shift;
98
99 $self->{alloc} = 1;
100 $self->{queue}{slots}--;
101 $self->{wake} and $self->{wake}->ready;
102}
103
104sub try {
105 my $self = shift;
106
107 $self->{alloc} || do {
108 my $timeout = Coro::Timer::timeout $_[0];
109 local $self->{wake} = $self->{coro};
110
111 Coro::schedule;
112
113 $self->{alloc};
114 }
115}
116
117sub DESTROY {
118 my $self = shift;
119
120 if ($self->{alloc}) {
121 $self->{queue}{slots}++;
122 $self->{queue}->wake_next;
123 }
124}
125
126package conn;
127
2our @blockuri; 128our %blockuri;
3our @blockref; 129our $blockref;
4 130
5sub read_blockuri { 131sub read_blockuri {
6 local *B; 132 local *B;
7 my %group; 133 my %group;
8 @blockuri = (); 134 %blockuri = ();
9 if (open B, "<blockuri") { 135 if (open B, "<blockuri") {
10 while (<B>) { 136 while (<B>) {
11 chomp; 137 chomp;
12 if (/^group\s+(\S+)\s+(.*)/i) { 138 if (/^group\s+(\S+)\s+(.*)/i) {
13 $group{$1} = [split /\s+/, $2]; 139 $group{$1} = [split /\s+/, $2];
16 my @r; 142 my @r;
17 for (split /\s+/, $2) { 143 for (split /\s+/, $2) {
18 push @r, $group{$_} ? @{$group{$_}} : $_; 144 push @r, $group{$_} ? @{$group{$_}} : $_;
19 } 145 }
20 print "not($g) => (@r)\n"; 146 print "not($g) => (@r)\n";
147 push @{$blockuri{$_}}, $g for @r;
21 push @blockuri, [qr/$g/i, \@r]; 148 push @blockuri, [qr/$g/i, \@r];
22 } elsif (/\S/) { 149 } elsif (/\S/) {
23 print "blockuri: unparsable line: $_\n"; 150 print "blockuri: unparsable line: $_\n";
24 } 151 }
25 } 152 }
153 for (keys %blockuri) {
154 my $qr = join ")|(?:", @{$blockuri{$_}};
155 $blockuri{$_} = qr{(?:$qr)}i;
156 }
26 } else { 157 } else {
27 print "no blockuri\n"; 158 print "no blockuri\n";
28 } 159 }
29} 160}
30 161
31sub read_blockref { 162sub read_blockref {
32 local *B; 163 local *B;
33 @blockref = (); 164 my @blockref;
34 if (open B, "<blockreferer") { 165 if (open B, "<blockreferer") {
35 while (<B>) { 166 while (<B>) {
36 chomp; 167 chomp;
37 if (/^([^\t]*)\t\s*(.*)/) { 168 if (/^([^\t]*)\t\s*(.*)/) {
38 push @blockref, qr/^$1/i; 169 push @blockref, $1;
39 } elsif (/\S/) { 170 } elsif (/\S/) {
40 print "blockref: unparsable line: $_\n"; 171 print "blockref: unparsable line: $_\n";
41 } 172 }
42 } 173 }
174 $blockref = join ")|(?:", @blockref;
175 $blockref = qr{^(?:$blockref)}i;
43 } else { 176 } else {
44 print "no blockref\n"; 177 print "no blockref\n";
178 $blockref = qr{^x^};
45 } 179 }
46} 180}
47 181
48read_blockuri; 182read_blockuri;
49read_blockref; 183read_blockref;
50 184
51use Tie::Cache; 185use Tie::Cache;
52tie %whois_cache, Tie::Cache::, $MAX_CONNECTS * 1.5; 186tie %whois_cache, Tie::Cache::, 32;
53 187
54sub conn::err_block_country {
55 my $self = shift;
56 my $whois = shift;
57
58 $whois =~ s/&/&amp;/g;
59 $whois =~ s/</&lt;/g;
60 $self->err(403, "forbidden", { "Content-Type" => "text/html" }, <<EOF);
61<html>
62<head>
63<title>This material is licensed in your country!</title>
64</head>
65<body bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#000080" alink="#ff0000">
66
67<h1>This material is licensed in your country!</h1>
68
69<p>My research has shown that your IP address
70(<b>$self->{remote_addr}</b>) most probably is located in this country:
71<b>$self->{country}</b> (ISO-3166-2 code, XX == unknown). The full record is:</p>
72
73<pre>
74$whois
75</pre>
76
77<p>My database says that the material you are trying to access is licensed
78in your country. If I would distribute these files to your country I would
79actively <em>hurt</em> the industry behind it, which includes the artists
80and authors of these videos/mangas. So I hope you understand that I try to
81avoid this.</p>
82
83<p>If you <em>really</em> think that this is wrong, i.e. the
84material you tried to access is <em>not</em> licensed in your
85country or your ip address was misdetected, you can write to <a
86href="mailto:licensed\@plan9.de">licensed\@plan9.de</a>. Please explain
87what happened and why you think this is wrong in as much detail as
88possible.</p>
89
90<div align="right">Thanks a lot for understanding.</div>
91
92</body>
93</html>
94EOF
95}
96
97sub conn::err_block_referer {
98 my $self = shift;
99
100 my $uri = $self->{uri};
101 $uri =~ s/\/[^\/]+$/\//;
102 $uri = escape_uri $uri;
103 print "hiho $uri\n";#d#
104
105 $self->slog(6, "REFERER($self->{uri},$self->{h}{referer})");
106
107 $whois =~ s/&/&amp;/g;
108 $whois =~ s/</&lt;/g;
109 $self->err(203, "non-authoritative", { "Content-Type" => "text/html" }, <<EOF);
110<html>
111<head>
112<title>Unallowed Referral</title>
113</head>
114<body bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#000080" alink="#ff0000">
115
116<h1>The site which referred you has done something bad!</h1>
117
118<p>It seems that you are coming from this URL:</p>
119
120<pre>$self->{h}{referer}</pre>
121
122<p>This site has been blocked, either because it required you to pay
123money, forced you to click on banners, claimed these files were theirs
124or something very similar. Please note that you can download these files
125<em>without</em> having to pay, <em>without</em> clicking banners or jump
126through other hoops.</p>
127
128<p><b>Sites like the one you came from actively hurt the distribution of
129these files and the service quality for you since I can't move or correct
130files and you will likely not be able to see the full archive.</b></p>
131
132<p>Having that this, you can find the original content (if it is still
133there) by <b>following <a href="$uri">this link</a>.</b></p>
134
135<div align="right">Thanks a lot for understanding.</div>
136
137</body>
138</html>
139EOF
140}
141
142sub conn::access_check { 188sub access_check {
143 my $self = shift; 189 my $self = shift;
144 190
145 my $ref = $self->{h}{referer}; 191 my $ref = $self->{h}{referer};
146 my $uri = $self->{path}; 192 my $uri = $self->{path};
147 my %disallow; 193 my %disallow;
148 194
149 for (@blockref) {
150 $self->err_block_referer if $ref =~ $_; 195 $self->err_block_referer
151 } 196 if $self->{h}{referer} =~ $blockref;
152 197
153 for (@blockuri) {
154 if ($uri =~ $_->[0]) {
155 $disallow{$_}++ for @{$_->[1]};
156 }
157 }
158
159 my $whois = $whois_cache{$self->{remote_addr}} 198 my $whois = $whois_cache{$self->{remote_addr}}
160 ||= ::ip_request($self->{remote_addr}); 199 ||= netgeo::ip_request($self->{remote_addr});
161 200
162 my $country = "XX"; 201 my $country = "XX";
163 202
164 if ($whois =~ /^\*cy: (\S+)/m) { 203 if ($whois =~ /^\*cy: (\S+)/m) {
165 $country = uc $1; 204 $country = uc $1;
167 $self->slog(9, "no country($whois)"); 206 $self->slog(9, "no country($whois)");
168 } 207 }
169 208
170 $self->{country} = $country; 209 $self->{country} = $country;
171 210
172 if ($disallow{$country}) {
173 $self->err_block_country($whois); 211 $self->err_block_country($whois)
174 } 212 if $self->{path} =~ $blockuri{$country};
175} 213}
176 214
1771; 2151;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines