… | |
… | |
136 | or $self->err(500, "unable to decode peername"); |
136 | or $self->err(500, "unable to decode peername"); |
137 | |
137 | |
138 | $self->{remote_addr} = inet_ntoa $iaddr; |
138 | $self->{remote_addr} = inet_ntoa $iaddr; |
139 | $self->{time} = $::NOW; |
139 | $self->{time} = $::NOW; |
140 | |
140 | |
141 | # enter ourselves into various lists |
|
|
142 | weaken ($conn{$self->{remote_addr}}{$self*1} = $self); |
|
|
143 | |
|
|
144 | $::conns++; |
141 | $::conns++; |
145 | |
142 | |
146 | $self; |
143 | $self; |
147 | } |
144 | } |
148 | |
145 | |
… | |
… | |
150 | my $self = shift; |
147 | my $self = shift; |
151 | |
148 | |
152 | $::conns--; |
149 | $::conns--; |
153 | |
150 | |
154 | $self->eoconn; |
151 | $self->eoconn; |
155 | delete $conn{$self->{remote_addr}}{$self*1}; |
|
|
156 | } |
152 | } |
157 | |
153 | |
158 | # end of connection |
154 | # end of connection |
159 | sub eoconn { |
155 | sub eoconn { |
160 | my $self = shift; |
156 | my $self = shift; |
|
|
157 | |
|
|
158 | # clean up hints |
|
|
159 | delete $conn{$self->{remote_id}}{$self*1}; |
161 | delete $uri{$self->{remote_addr}}{$self->{uri}}{$self*1}; |
160 | delete $uri{$self->{remote_id}}{$self->{uri}}{$self*1}; |
162 | } |
161 | } |
163 | |
162 | |
164 | sub slog { |
163 | sub slog { |
165 | my $self = shift; |
164 | my $self = shift; |
166 | main::slog($_[0], ($self->{remote_id} || $self->{remote_addr}) ."> $_[1]"); |
165 | main::slog($_[0], ($self->{remote_id} || $self->{remote_addr}) ."> $_[1]"); |
… | |
… | |
228 | } |
227 | } |
229 | |
228 | |
230 | $self->{h} = {}; |
229 | $self->{h} = {}; |
231 | |
230 | |
232 | $fh->timeout($::RES_TIMEOUT); |
231 | $fh->timeout($::RES_TIMEOUT); |
233 | my $ip = $self->{remote_addr}; |
|
|
234 | |
|
|
235 | if ($blocked{$ip}) { |
|
|
236 | $self->err_blocked($blocked{$ip}) |
|
|
237 | if $blocked{$ip} > $::NOW; |
|
|
238 | |
|
|
239 | delete $blocked{$ip}; |
|
|
240 | } |
|
|
241 | |
|
|
242 | if (%{$conn{$ip}} > $::MAX_CONN_IP) { |
|
|
243 | my $delay = 120; |
|
|
244 | while (%{$conn{$ip}} > $::MAX_CONN_IP) { |
|
|
245 | if ($delay <= 0) { |
|
|
246 | $self->slog(2, "blocked ip $ip"); |
|
|
247 | $self->err_blocked; |
|
|
248 | } else { |
|
|
249 | Coro::Event::do_timer(after => 3); |
|
|
250 | $delay -= 3; |
|
|
251 | } |
|
|
252 | } |
|
|
253 | } |
|
|
254 | |
232 | |
255 | $req =~ /^(?:\015\012)? |
233 | $req =~ /^(?:\015\012)? |
256 | (GET|HEAD) \040+ |
234 | (GET|HEAD) \040+ |
257 | ([^\040]+) \040+ |
235 | ([^\040]+) \040+ |
258 | HTTP\/([0-9]+\.[0-9]+) |
236 | HTTP\/([0-9]+\.[0-9]+) |
… | |
… | |
283 | |
261 | |
284 | $self->{h}{$h} = substr $v, 1 |
262 | $self->{h}{$h} = substr $v, 1 |
285 | while ($h, $v) = each %hdr; |
263 | while ($h, $v) = each %hdr; |
286 | } |
264 | } |
287 | |
265 | |
|
|
266 | # remote id should be unique per user |
|
|
267 | my $id = $self->{remote_addr}; |
|
|
268 | |
|
|
269 | if (exists $self->{h}{"client-ip"}) { |
|
|
270 | $id .= "[".$self->{h}{"client-ip"}."]"; |
|
|
271 | } elsif (exists $self->{h}{"x-forwarded-for"}) { |
|
|
272 | $id .= "[".$self->{h}{"x-forwarded-for"}."]"; |
|
|
273 | } |
|
|
274 | |
|
|
275 | $self->{remote_id} = $id; |
|
|
276 | |
|
|
277 | if ($blocked{$id}) { |
|
|
278 | $self->err_blocked($blocked{$id}) |
|
|
279 | if $blocked{$id} > $::NOW; |
|
|
280 | |
|
|
281 | delete $blocked{$id}; |
|
|
282 | } |
|
|
283 | |
|
|
284 | if (%{$conn{$id}} >= $::MAX_CONN_IP) { |
|
|
285 | my $delay = $::PER_TIMEOUT + 15; |
|
|
286 | while (%{$conn{$id}} >= $::MAX_CONN_IP) { |
|
|
287 | if ($delay <= 0) { |
|
|
288 | $self->slog(2, "blocked ip $id"); |
|
|
289 | $self->err_blocked; |
|
|
290 | } else { |
|
|
291 | Coro::Event::do_timer(after => 4); $delay -= 4; |
|
|
292 | } |
|
|
293 | } |
|
|
294 | } |
|
|
295 | |
288 | # find out server name and port |
296 | # find out server name and port |
289 | if ($self->{uri} =~ s/^http:\/\/([^\/?#]*)//i) { |
297 | if ($self->{uri} =~ s/^http:\/\/([^\/?#]*)//i) { |
290 | $host = $1; |
298 | $host = $1; |
291 | } else { |
299 | } else { |
292 | $host = $self->{h}{host}; |
300 | $host = $self->{h}{host}; |
… | |
… | |
301 | $host = inet_ntoa $host; |
309 | $host = inet_ntoa $host; |
302 | } |
310 | } |
303 | |
311 | |
304 | $self->{server_name} = $host; |
312 | $self->{server_name} = $host; |
305 | |
313 | |
306 | # remote id should be unique per user |
314 | # enter ourselves into various lists |
307 | $self->{remote_id} = $self->{remote_addr}; |
315 | weaken ($conn{$id}{$self*1} = $self); |
308 | |
|
|
309 | if (exists $self->{h}{"client-ip"}) { |
|
|
310 | $self->{remote_id} .= "[".$self->{h}{"client-ip"}."]"; |
|
|
311 | } elsif (exists $self->{h}{"x-forwarded-for"}) { |
|
|
312 | $self->{remote_id} .= "[".$self->{h}{"x-forwarded-for"}."]"; |
|
|
313 | } |
|
|
314 | |
|
|
315 | weaken ($uri{$self->{remote_addr}}{$self->{uri}}{$self*1} = $self); |
316 | weaken ($uri{$id}{$self->{uri}}{$self*1} = $self); |
316 | |
317 | |
317 | eval { |
318 | eval { |
318 | $self->map_uri; |
319 | $self->map_uri; |
319 | $self->respond; |
320 | $self->respond; |
320 | }; |
321 | }; |
… | |
… | |
457 | $self->err(416, "not satisfiable", $hdr, ""); |
458 | $self->err(416, "not satisfiable", $hdr, ""); |
458 | |
459 | |
459 | satisfiable: |
460 | satisfiable: |
460 | # check for segmented downloads |
461 | # check for segmented downloads |
461 | if ($l && $::NO_SEGMENTED) { |
462 | if ($l && $::NO_SEGMENTED) { |
462 | my $delay = 180; |
463 | my $delay = $::PER_TIMEOUT + 15; |
463 | while (%{$uri{$self->{remote_addr}}{$self->{uri}}} > 1) { |
464 | while (%{$uri{$self->{remote_id}}{$self->{uri}}} > 1) { |
464 | if ($delay <= 0) { |
465 | if ($delay <= 0) { |
465 | $self->err_segmented_download; |
466 | $self->err_segmented_download; |
466 | } else { |
467 | } else { |
467 | Coro::Event::do_timer(after => 3); $delay -= 3; |
468 | Coro::Event::do_timer(after => 4); $delay -= 4; |
468 | } |
469 | } |
469 | } |
470 | } |
470 | } |
471 | } |
471 | |
472 | |
472 | $hdr->{"Content-Range"} = "bytes $l-$h/$length"; |
473 | $hdr->{"Content-Range"} = "bytes $l-$h/$length"; |