1 | #!/usr/bin/perl |
1 | #!/usr/bin/perl |
2 | |
2 | |
3 | # this is a relatively small web-server, using coroutines |
3 | # this is a relatively small web-server, using coroutines for connections. |
4 | # for connections. play around with it but do not use |
4 | # play around with it but do not use it in production without checking it |
5 | # it in production. ask myhttpd@plan9.de for a better |
5 | # works for you. ask myhttpd@plan9.de in case of problems, or if you are |
6 | # version that's more usable and bugfixed. |
6 | # interested in a newer version (more useless features). |
7 | |
7 | |
8 | use Coro; |
8 | use Coro; |
9 | use Coro::Semaphore; |
9 | use Coro::Semaphore; |
10 | use Coro::Event; |
10 | use Coro::Event; |
11 | use Coro::Socket; |
11 | use Coro::Socket; |
… | |
… | |
77 | } |
77 | } |
78 | |
78 | |
79 | } |
79 | } |
80 | }; |
80 | }; |
81 | |
81 | |
|
|
82 | cede; |
82 | loop; |
83 | loop; |
83 | print "ende\n";#d# |
84 | print "ende\n";#d# |
84 | |
85 | |
85 | package conn; |
86 | package conn; |
86 | |
87 | |
… | |
… | |
88 | use HTTP::Date; |
89 | use HTTP::Date; |
89 | |
90 | |
90 | sub new { |
91 | sub new { |
91 | my $class = shift; |
92 | my $class = shift; |
92 | my $fh = shift; |
93 | my $fh = shift; |
93 | my (undef, $iaddr) = unpack_sockaddr_in $fh->getpeername |
94 | my (undef, $iaddr) = unpack_sockaddr_in $fh->peername |
94 | or $self->err(500, "unable to get peername"); |
95 | or $self->err(500, "unable to get peername"); |
95 | $self->{remote_address} = inet_ntoa $iaddr; |
96 | $self->{remote_address} = inet_ntoa $iaddr; |
96 | bless { fh => $fh }, $class; |
97 | bless { fh => $fh }, $class; |
97 | } |
98 | } |
98 | |
99 | |
… | |
… | |
151 | ([^\040]+) \040+ |
152 | ([^\040]+) \040+ |
152 | HTTP\/([0-9]+\.[0-9]+) |
153 | HTTP\/([0-9]+\.[0-9]+) |
153 | \015\012/gx |
154 | \015\012/gx |
154 | or $self->err(403, "method not allowed", { Allow => "GET,HEAD" }); |
155 | or $self->err(403, "method not allowed", { Allow => "GET,HEAD" }); |
155 | |
156 | |
156 | $2 ne "1.0" |
157 | $2 < 2 |
157 | or $self->err(506, "http protocol version not supported"); |
158 | or $self->err(506, "http protocol version not supported"); |
158 | |
159 | |
159 | $self->{method} = $1; |
160 | $self->{method} = $1; |
160 | $self->{uri} = $2; |
161 | $self->{uri} = $2; |
161 | |
162 | |
… | |
… | |
164 | my (%hdr, $h, $v); |
165 | my (%hdr, $h, $v); |
165 | |
166 | |
166 | $hdr{lc $1} .= ",$2" |
167 | $hdr{lc $1} .= ",$2" |
167 | while $req =~ /\G |
168 | while $req =~ /\G |
168 | ([^:\000-\040]+): |
169 | ([^:\000-\040]+): |
169 | [\008\040]* |
170 | [\011\040]* |
170 | ((?: [^\015\012]+ | \015\012[\008\040] )*) |
171 | ((?: [^\015\012]+ | \015\012[\011\040] )*) |
171 | \015\012 |
172 | \015\012 |
172 | /gxc; |
173 | /gxc; |
173 | |
174 | |
174 | $req =~ /\G\015\012$/ |
175 | $req =~ /\G\015\012$/ |
175 | or $self->err(400, "bad request"); |
176 | or $self->err(400, "bad request"); |
… | |
… | |
206 | $self->{path} = "$::DOCROOT/$host$uri"; |
207 | $self->{path} = "$::DOCROOT/$host$uri"; |
207 | } |
208 | } |
208 | |
209 | |
209 | sub server_address { |
210 | sub server_address { |
210 | my $self = shift; |
211 | my $self = shift; |
211 | my ($port, $iaddr) = unpack_sockaddr_in $self->{fh}->getsockname |
212 | my ($port, $iaddr) = unpack_sockaddr_in $self->{fh}->sockname |
212 | or $self->err(500, "unable to get socket name"); |
213 | or $self->err(500, "unable to get socket name"); |
213 | ((inet_ntoa $iaddr), $port); |
214 | ((inet_ntoa $iaddr), $port); |
214 | } |
215 | } |
215 | |
216 | |
216 | sub server_host { |
217 | sub server_host { |
… | |
… | |
317 | ($l, $h) = ($1, ($2 ne "" || $2 >= $length) ? $2 : $length - 1); |
318 | ($l, $h) = ($1, ($2 ne "" || $2 >= $length) ? $2 : $length - 1); |
318 | } else { |
319 | } else { |
319 | ($l, $h) = (0, $length - 1); |
320 | ($l, $h) = (0, $length - 1); |
320 | goto ignore; |
321 | goto ignore; |
321 | } |
322 | } |
322 | goto satisfiable if $l >= 0 && $l < $length && $h >= 0 && $h > $l; |
323 | goto satisfiable if $l >= 0 && $l < $length && $h >= 0 && $h >= $l; |
323 | } |
324 | } |
324 | $hdr->{"Content-Range"} = "bytes */$length"; |
325 | $hdr->{"Content-Range"} = "bytes */$length"; |
325 | $self->err(416, "not satisfiable", $hdr); |
326 | $self->err(416, "not satisfiable", $hdr); |
326 | |
327 | |
327 | satisfiable: |
328 | satisfiable: |
… | |
… | |
363 | } |
364 | } |
364 | } |
365 | } |
365 | |
366 | |
366 | close $fh; |
367 | close $fh; |
367 | } |
368 | } |
|
|
369 | |