From 5b17cfaa74fff633959985366cb40d4e12f7cae9 Mon Sep 17 00:00:00 2001 From: eleksir Date: Sun, 1 Sep 2019 10:33:10 +0300 Subject: [PATCH] Make api more rich * Implement help * Add simple dns resolve commands * Add punycode <-> unicode conversions * Add time info --- lib/utils.pm | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ myapi.psgi | 56 ++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 97 insertions(+), 16 deletions(-) diff --git a/lib/utils.pm b/lib/utils.pm index 1faa3a8..7a0b419 100644 --- a/lib/utils.pm +++ b/lib/utils.pm @@ -1,6 +1,8 @@ package utils; use strict; +use Socket; # for name resolves +use Net::LibIDN ':all'; use vars qw/$VERSION/; $VERSION = "1.0"; @@ -21,4 +23,59 @@ sub ip ($) { return ('200', 'text/plain', $msg); } +sub getaddrbyname ($) { + my $name = shift; + return ('400', 'text/plain', "Supply hostname\n") unless (defined($name)); + my @addresses = gethostbyname($name); + + if (@addresses > 0) { + @addresses = map { inet_ntoa($_) } @addresses[4 .. $#addresses]; + + if (@addresses > 1) { + return ('200', 'text/plain', join("\n", @addresses) . "\n"); + } else { + return ('200', 'text/plin', "$addresses[0]\n"); + } + } else { + return ('404', 'text/plain', "Not found\n"); + } +} + +sub getnamebyaddr ($) { + my $addr = shift; + chomp($addr); + return ('400', 'text/plain', "Supply address\n") unless (defined($addr)); + my $name = gethostbyaddr(inet_aton($addr), AF_INET); + + if (defined($name)) { + return ('200', 'text/plain', "$name\n"); + } else { + return ('404', 'text/plain', "Not found\n"); + } +} + +sub punycoder ($) { + my $str = shift; + $str = Net::LibIDN::idn_to_ascii($str, 'utf-8'); + if (defined($str)) { + return ('200', 'text/plain', "$str\n"); + } else { + return ('400', 'text/plain', "Bad string\n") + } +} + +sub punydecoder ($) { + my $str = shift; + $str = Net::LibIDN::idn_to_unicode($str, 'utf-8'); + if (defined($str)) { + return ('200', 'text/plain', "$str\n"); + } else { + return ('400', 'text/plain', "Bad string\n") + } +} + +sub mytime () { + return ('200', 'text/plain', time() . "\n"); +} + 1; diff --git a/myapi.psgi b/myapi.psgi index 8a34514..332694b 100644 --- a/myapi.psgi +++ b/myapi.psgi @@ -21,7 +21,8 @@ my $main :shared = 0; #unless ($main) { threads->create('mythread'); } my $CONF = loadConf(); -if ($CONF->{api}->{prefix} eq '/') { $CONF->{prefix} = ''; } +if ($CONF->{api}->{prefix} eq '/') { $CONF->{api}->{prefix} = ''; } +my $prefix = $CONF->{api}->{prefix}; my $app = sub { my $env = shift; @@ -30,27 +31,50 @@ my $app = sub { my $status = '404'; my $content = 'text/plain'; - if ($env->{PATH_INFO} eq "$CONF->{api}->{prefix}/d") { + if ($env->{PATH_INFO} eq "$prefix/help") { + $status = '200'; + $msg = << 'EOL'; +/ping - pong +/ip - your ip +/getaddrbyname - header hostname must be set +/getnameaaddr - header adderess must be set +/punycoder - header hostname must be set +/punydecoder - header hostname must be set +/time - current time +/quote - famous or not famous quotes +/fortune - synonym for quote +EOL + } elsif ($env->{PATH_INFO} eq "$prefix/d") { $status = '200'; $msg = Dumper($env); - } elsif ($env->{PATH_INFO} eq "$CONF->{api}->{prefix}/ping") { + } elsif ($env->{PATH_INFO} eq "$prefix/ping") { ($status, $content, $msg) = ping::pong(); - } elsif ($env->{PATH_INFO} eq "$CONF->{api}->{prefix}/ip") { + } elsif ($env->{PATH_INFO} eq "$prefix/ip") { ($status, $content, $msg) = utils::ip($env); - } elsif (($env->{PATH_INFO} eq "$CONF->{api}->{prefix}/fortune") or - ($env->{PATH_INFO} eq "$CONF->{api}->{prefix}/quote")) { + } elsif (($env->{PATH_INFO} eq "$prefix/getaddrbyname")) { + ($status, $content, $msg) = utils::getaddrbyname($env->{HTTP_HOSTNAME}); + } elsif (($env->{PATH_INFO} eq "$prefix/getnamebyaddr")) { + ($status, $content, $msg) = utils::getnamebyaddr($env->{HTTP_ADDRESS}); + } elsif (($env->{PATH_INFO} eq "$prefix/punycoder")) { + ($status, $content, $msg) = utils::punycoder($env->{HTTP_HOSTNAME}); + } elsif (($env->{PATH_INFO} eq "$prefix/punydecoder")) { + ($status, $content, $msg) = utils::punydecoder($env->{HTTP_HOSTNAME}); + } elsif (($env->{PATH_INFO} eq "$prefix/time")) { + ($status, $content, $msg) = utils::mytime(); + } elsif (($env->{PATH_INFO} eq "$prefix/fortune") or + ($env->{PATH_INFO} eq "$prefix/quote")) { ($status, $content, $msg) = easter_egg::quote(); - } elsif (($env->{PATH_INFO} eq "$CONF->{api}->{prefix}/chanserv") or - ($env->{PATH_INFO} eq "$CONF->{api}->{prefix}/chanServ") or - ($env->{PATH_INFO} eq "$CONF->{api}->{prefix}/ChanServ") or - ($env->{PATH_INFO} eq "$CONF->{api}->{prefix}/CHANSERV")) { + } elsif (($env->{PATH_INFO} eq "$prefix/chanserv") or + ($env->{PATH_INFO} eq "$prefix/chanServ") or + ($env->{PATH_INFO} eq "$prefix/ChanServ") or + ($env->{PATH_INFO} eq "$prefix/CHANSERV")) { ($status, $content, $msg) = easter_egg::chanserv(); - } elsif (($env->{PATH_INFO} eq "$CONF->{api}->{prefix}/nickserv") or - ($env->{PATH_INFO} eq "$CONF->{api}->{prefix}/nickServ") or - ($env->{PATH_INFO} eq "$CONF->{api}->{prefix}/NickServ") or - ($env->{PATH_INFO} eq "$CONF->{api}->{prefix}/NICKSERV")) { + } elsif (($env->{PATH_INFO} eq "$prefix/nickserv") or + ($env->{PATH_INFO} eq "$prefix/nickServ") or + ($env->{PATH_INFO} eq "$prefix/NickServ") or + ($env->{PATH_INFO} eq "$prefix/NICKSERV")) { ($status, $content, $msg) = easter_egg::nickserv(); - } elsif (($env->{PATH_INFO} eq "$CONF->{api}->{prefix}/me")) { + } elsif ($env->{PATH_INFO} eq "$prefix/me") { ($status, $content, $msg) = easter_egg::me(); } @@ -96,7 +120,7 @@ sub mythread () { -# vim: set ft=perl noet ai : +# vim: ft=perl noet ai ts=4 sw=4 sts=4: __END__ https://toster.ru/q/75226