App-phoebe
view release on metacpan or search on metacpan
lib/App/Phoebe/Web.pm view on Meta::CPAN
return http_error($stream, "Content longer than what the header says ($actual > $length):\n" . $data->{buffer}) if $actual > $length;
if ($length == $actual) {
# got the entire body as part of the first part
process_http($stream, $data->{request}, $data->{headers}, $data->{buffer});
$stream->close_gracefully();
return;
} elsif ($length) {
# read body if it was sent in multiple parts
$data->{handler} = \&handle_http_body;
handle_http_body($stream, $data);
return;
}
# otherwise wait for more header bytes
}
if ($data->{header_size} and $data->{header_size} > $server->{wiki_page_size_limit}) {
$log->debug("This wiki does not allow more than $server->{wiki_page_size_limit} bytes of headers");
result($stream, "400", "Bad request: headers too long");
$stream->close_gracefully();
return;
}
}
# if we came here, the last line didn't match and needs more bytes
$data->{buffer} = $lines[$#lines];
$log->debug("Waiting for more HTTP headers ('$data->{buffer}')");
return;
}
sub http_error {
my $stream = shift;
my $message = shift;
$stream->write("HTTP/1.1 400 Bad Request\r\n");
$stream->write("Content-Type: text/plain\r\n");
$stream->write("\r\n");
$stream->write("$message\n");
$stream->close_gracefully();
return 0;
}
sub handle_http_body {
my $stream = shift;
my $data = shift;
$log->debug("Reading HTTP body");
my $length = $data->{headers}->{'content-length'} || 0;
my $actual = length($data->{buffer});
if ($length == $actual) {
# got the entire body
process_http($stream, $data->{request}, $data->{headers}, $data->{buffer});
$stream->close_gracefully();
return;
}
$log->debug("Received $actual/$length bytes");
}
sub process_http {
my $stream = shift;
my $request = shift;
my $headers = shift;
my $buffer = shift;
eval {
local $SIG{'ALRM'} = sub {
$log->error("Timeout processing $request");
};
alarm(10); # timeout
my $hosts = host_regex();
my $port = port($stream);
my $spaces = space_regex();
$log->info("Looking at $request");
my ($host, $space, $id, $n, $filter);
if (run_extensions($stream, $request, $headers, $buffer)) {
# config file goes first
} elsif ($request =~ m!^GET /default.css HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_css_via_http($stream, $host);
} elsif (($space) = $request =~ m!^GET (?:(?:/($spaces)/?)?|/) HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_main_menu_via_http($stream, $host, space($stream, $host, $space));
} elsif (($space, $id, $n) = $request =~ m!^GET (?:/($spaces))?/page/([^/]*)(?:/(\d+))? HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_page_via_http($stream, $host, space($stream, $host, $space), decode_utf8(uri_unescape($id)), $n);
} elsif (($space, $id, $n) = $request =~ m!^GET (?:/($spaces))?/file/([^/]*)(?:/(\d+))? HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_file_via_http($stream, $host, space($stream, $host, $space), decode_utf8(uri_unescape($id)), $n);
} elsif (($space, $id, $n) = $request =~ m!^GET (?:/($spaces))?/history/([^/]*)(?:/(\d+))? HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_history_via_http($stream, $host, space($stream, $host, $space), decode_utf8(uri_unescape($id)), $n||10);
} elsif (($space, $id, $n) = $request =~ m!^GET (?:/($spaces))?/diff/([^/]*)(?:/(\d+))? HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_diff_via_http($stream, $host, space($stream, $host, $space), decode_utf8(uri_unescape($id)), $n||10);
} elsif (($space, $id, $n) = $request =~ m!^GET (?:/($spaces))?/raw/([^/]*)(?:/(\d+))? HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_raw_via_http($stream, $host, space($stream, $host, $space), decode_utf8(uri_unescape($id)), $n);
} elsif ($request =~ m!^GET /robots.txt(?:[#?].*)? HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_raw_via_http($stream, $host, undef, 'robots');
} elsif (($space, $id, $n) = $request =~ m!^GET (?:/($spaces))?/do/changes(?:/(\d+))? HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_changes_via_http($stream, $host, space($stream, $host, $space), $n||100);
} elsif (($filter, $n) = $request =~ m!^GET /do/all(?:/(latest))?/changes(?:/(\d+))? HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_all_changes_via_http($stream, $host, $n||100, $filter||"");
} elsif (($space, $id, $n) = $request =~ m!^GET (?:/($spaces))?/do/index HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_index_via_http($stream, $host, space($stream, $host, $space));
} elsif (($space, $id, $n) = $request =~ m!^GET (?:/($spaces))?/do/files HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_files_via_http($stream, $host, space($stream, $host, $space));
} elsif (($space, $id, $n) = $request =~ m!^GET (?:/($spaces))?/do/spaces HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_spaces_via_http($stream, $host, $port);
} elsif (($space, $id, $n) = $request =~ m!^GET (?:/($spaces))?/do/rss HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_rss_via_http($stream, $host, space($stream, $host, $space));
} elsif (($space, $id, $n) = $request =~ m!^GET (?:/($spaces))?/do/atom HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_atom_via_http($stream, $host, space($stream, $host, $space));
} elsif (($space, $n) = $request =~ m!^GET /do/all/atom HTTP/1\.[01]$!
and ($host) = $headers->{host} =~ m!^($hosts)(?::$port)$!) {
serve_all_atom_via_http($stream, $host);
} else {
$log->debug("No http handler for $request");
http_error($stream, "Don't know how to handle $request");
( run in 1.935 second using v1.01-cache-2.11-cpan-39bf76dae61 )