App-phoebe
view release on metacpan or search on metacpan
lib/App/Phoebe/Oddmuse.pm view on Meta::CPAN
# The Oddmuse wiki uses WikiLinks
our %oddmuse_wiki_links = ("communitywiki.org" => 1);
# The Oddmuse wiki uses a different token as the answer to a security question
# (i.e. not the Phoebe server token). This only works if the Oddmuse wiki has
# just one security question (or accepts the same answer for all questions).
our %oddmuse_wiki_tokens = (
"emacswiki.org" => "emacs" );
our $oddmuse_namespace_regex = '[\p{Uppercase}\d][\w_ Â ]*';
*oddmuse_old_space_regex = \&App::Phoebe::space_regex;
*App::Phoebe::space_regex = \&oddmuse_new_space_regex;
sub oddmuse_new_space_regex {
my $spaces = oddmuse_old_space_regex();
return "$spaces|$oddmuse_namespace_regex" if $spaces;
return $oddmuse_namespace_regex;
}
*oddmuse_old_space = \&App::Phoebe::space;
*App::Phoebe::space = \&oddmuse_new_space;
sub oddmuse_new_space {
my $stream = shift;
my $host = shift;
my $space = shift;
if (grep { $_ eq $host } keys %oddmuse_wikis) {
# Let Oddmuse handle namespaces
return $space;
}
return oddmuse_old_space($stream, $host, $space);
}
*oddmuse_old_save_page = \&App::Phoebe::save_page;
*App::Phoebe::save_page = \&oddmuse_new_save_page;
sub oddmuse_new_save_page {
my $stream = shift;
my $host = shift;
my $space = shift;
my $id = shift;
my $type = shift;
my $data = shift;
my $length = shift;
my $port = port($stream);
if (not grep { $_ eq $host } keys %oddmuse_wikis) {
return oddmuse_old_save_page($stream, $host, $space, $id, $type, $data, $length);
}
if ($type ne "text/plain") {
$data = "#FILE $type\n" . encode_base64($data);
} elsif (not utf8::decode($data)) {
$log->debug("The text is invalid UTF-8");
result($stream, "59", "The text is invalid UTF-8");
$stream->close_gracefully();
return;
}
my @tokens = @{$server->{wiki_token}};
push(@tokens, $oddmuse_wiki_tokens{$host}) if $oddmuse_wiki_tokens{$host};
my $token = pop(@tokens); # the oddmuse wiki token, preferrably
my $name = ref($stream->handle) eq 'IO::Socket::SSL' && $stream->handle->peer_certificate('cn') || "";
my $ua = Mojo::UserAgent->new;
my $tx = $ua->post(
$oddmuse_wikis{$host}
=> {'X-Forwarded-For' => $stream->handle->peerhost}
=> form => {
title => $id,
text => $data,
ns => $space,
answer => $token,
username => $name,
gemini => 1 });
$log->debug("Got " . $tx->result->code . " response");
if ($tx->result->code == 302) {
my $url = "gemini://$host:$port";
$url .= "/$space" if $space;
result($stream, "30", "$url/page/" . uri_escape_utf8($id) . "");
} else {
$stream->write("59 Got HTTP code " . $tx->result->code . " " . $tx->result->message
. " (" . $tx->req->url->to_abs . " " . $tx->req->params . ")\r\n");
}
$stream->close_gracefully();
}
*oddmuse_old_valid_token = \&App::Phoebe::valid_token;
*App::Phoebe::valid_token = \&oddmuse_new_valid_token;
sub oddmuse_new_valid_token {
my ($stream, $host, $space, $id, $params) = @_;
my $token = $params->{token}||"";
if ($oddmuse_wiki_tokens{$host}) {
$log->debug("Comparing $token with $oddmuse_wiki_tokens{$host}");
} else {
$log->debug("There is no specific token for this Oddmuse wiki");
}
return 1 if $oddmuse_wiki_tokens{$host} and $oddmuse_wiki_tokens{$host} eq $token;
return oddmuse_old_valid_token(@_);
}
push(@extensions, \&oddmuse_process_request);
sub oddmuse_process_request {
my $stream = shift;
my $url = shift;
my $headers = shift;
my $hosts = "(" . join("|", keys %oddmuse_wikis) . ")";
my $spaces = $oddmuse_namespace_regex;
my $reserved = reserved_regex();
my $port = port($stream);
my ($host, $space, $id, $query, $n, $style, $token);
if ($url =~ m!^gemini://$hosts(?::$port)?/robots\.txt$!) {
# must come before redirection to regular pages since it contains no slash
oddmuse_serve_robots($stream);
} elsif (($host, $n, $space) = $url =~ m!^gemini://$hosts(:$port)?(?:/($spaces))?/(?:$reserved)$!) {
result($stream, "31", "gemini://$host" . ($n ? ":$port" : "") . "/" . ($space ? $space : "") . ""); # this supports "up"
} elsif (($host, $space, $id, $n) = $url =~ m!^gemini://$hosts(?::$port)?(?:/($spaces))?/page/([^/]+)(?:/(\d+))?$!
and $id ne $server->{wiki_main_page}) {
oddmuse_serve_page($stream, $host, $space, free_to_normal(decode_utf8(uri_unescape($id))), $n);
} elsif (($host, $space, $id) = $url =~ m!^gemini://$hosts(?::$port)?(?:/($spaces))?/tag/([^/]+)$!) {
oddmuse_serve_tag($stream, $host, $space, free_to_normal(decode_utf8(uri_unescape($id))));
} elsif (($host, $space, $id) = $url =~ m!^gemini://$hosts(?::$port)?(?:/($spaces))?/raw/([^/]+)$!
( run in 1.999 second using v1.01-cache-2.11-cpan-39bf76dae61 )