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

Comparing cvsroot/Coro/myhttpd/httpd.pl (file contents):
Revision 1.13 by root, Sun Aug 12 01:16:48 2001 UTC vs.
Revision 1.16 by root, Tue Aug 14 19:38:25 2001 UTC

70package conn; 70package conn;
71 71
72use Socket; 72use Socket;
73use HTTP::Date; 73use HTTP::Date;
74use Convert::Scalar 'weaken'; 74use Convert::Scalar 'weaken';
75use Linux::AIO;
76
77Linux::AIO::min_parallel $::AIO_PARALLEL;
78
79Event->io(fd => Linux::AIO::poll_fileno,
80 poll => 'r',
81 async => 1,
82 cb => \&Linux::AIO::poll_cb );
83
84Event->add_hooks(prepare => sub {
85 &Coro::cede while &Coro::nready;
86 1e6;
87});
75 88
76our %conn; # $conn{ip}{fh} => connobj 89our %conn; # $conn{ip}{fh} => connobj
77our %blocked; 90our %blocked;
78our %mimetype; 91our %mimetype;
79 92
163sub err_blocked { 176sub err_blocked {
164 my $self = shift; 177 my $self = shift;
165 my $ip = $self->{remote_addr}; 178 my $ip = $self->{remote_addr};
166 my $time = time2str $blocked{$ip} = $::NOW + $::BLOCKTIME; 179 my $time = time2str $blocked{$ip} = $::NOW + $::BLOCKTIME;
167 180
181 Coro::Event::do_timer(after => 15);
182
168 $self->err(403, "too many connections", 183 $self->err(401, "too many connections",
169 { 184 {
170 "Content-Type" => "text/html", 185 "Content-Type" => "text/html",
171 "Retry-After" => $::BLOCKTIME 186 "Retry-After" => $::BLOCKTIME
172 }, 187 },
173 <<EOF); 188 <<EOF);
215 $req =~ /^(?:\015\012)? 230 $req =~ /^(?:\015\012)?
216 (GET|HEAD) \040+ 231 (GET|HEAD) \040+
217 ([^\040]+) \040+ 232 ([^\040]+) \040+
218 HTTP\/([0-9]+\.[0-9]+) 233 HTTP\/([0-9]+\.[0-9]+)
219 \015\012/gx 234 \015\012/gx
220 or $self->err(403, "method not allowed", { Allow => "GET,HEAD" }); 235 or $self->err(405, "method not allowed", { Allow => "GET,HEAD" });
221 236
222 $2 ne "1.0" 237 $2 ne "1.0"
223 or $self->err(506, "http protocol version not supported"); 238 or $self->err(506, "http protocol version not supported");
224 239
225 $self->{method} = $1; 240 $self->{method} = $1;
403 418
404satisfiable: 419satisfiable:
405 # check for segmented downloads 420 # check for segmented downloads
406 if ($l && $::NO_SEGMENTED) { 421 if ($l && $::NO_SEGMENTED) {
407 if (%{$uri{$self->{remote_addr}}{$self->{uri}}} > 1) { 422 if (%{$uri{$self->{remote_addr}}{$self->{uri}}} > 1) {
423 Coro::Event::do_timer(after => 15);
424
408 $self->err(400, "segmented downloads are not allowed"); 425 $self->err(400, "segmented downloads are not allowed");
409 } 426 }
410 } 427 }
411 428
412 $hdr->{"Content-Range"} = "bytes $l-$h/$length"; 429 $hdr->{"Content-Range"} = "bytes $l-$h/$length";
423 $hdr->{"Content-Length"} = $length; 440 $hdr->{"Content-Length"} = $length;
424 441
425 $self->response(@code, $hdr, ""); 442 $self->response(@code, $hdr, "");
426 443
427 if ($self->{method} eq "GET") { 444 if ($self->{method} eq "GET") {
428 my ($fh, $buf); 445 my ($fh, $buf, $r);
446 my $current = $Coro::current;
429 open $fh, "<", $self->{path} 447 open $fh, "<", $self->{path}
430 or die "$self->{path}: late open failure ($!)"; 448 or die "$self->{path}: late open failure ($!)";
431 449
432 if ($l) {
433 sysseek $fh, $l, 0
434 or die "$self->{path}: cannot seek to $l ($!)";
435 }
436
437 $h -= $l - 1; 450 $h -= $l - 1;
438 451
439 while ($h > 0) { 452 while ($h > 0) {
440 $h -= sysread $fh, $buf, $h > $::BUFSIZE ? $::BUFSIZE : $h; 453 aio_read($fh, $l, ($h > $::BUFSIZE ? $::BUFSIZE : $h),
454 $buf, 0, sub {
455 $r = $_[0];
456 $current->ready;
457 });
458 &Coro::schedule;
459 last unless $r;
441 my $w = $self->{fh}->syswrite($buf) 460 my $w = $self->{fh}->syswrite($buf)
442 or last; 461 or last;
443 $::written += $w; 462 $::written += $w;
444 $self->{written} += $w; 463 $self->{written} += $w;
464 $l += $r;
445 } 465 }
446 } 466 }
447 467
448 close $fh; 468 close $fh;
449} 469}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines