App-Phoebe

 view release on metacpan or  search on metacpan

META.json  view on Meta::CPAN

      "runtime" : {
         "requires" : {
            "Algorithm::Diff" : "0",
            "Encode::Locale" : "0",
            "File::MimeInfo" : "0",
            "File::MimeInfo::Magic" : "0",
            "File::ReadBackwards" : "0",
            "File::Slurper" : "0",
            "HTTP::Date" : "0",
            "IO::Scalar" : "0",
            "IO::Socket::SSL" : "2.069",
            "IRI" : "0",
            "Modern::Perl" : "1.20180701",
            "Mojolicious" : "9",
            "Net::IDN::Encode" : "0",
            "Net::SSLeay" : "1.9",
            "Text::Wrapper" : "0",
            "URI::Escape" : "0",
            "XML::LibXML" : "0",
            "perl" : "5.026000"
         }

META.yml  view on Meta::CPAN

    - inc
requires:
  Algorithm::Diff: '0'
  Encode::Locale: '0'
  File::MimeInfo: '0'
  File::MimeInfo::Magic: '0'
  File::ReadBackwards: '0'
  File::Slurper: '0'
  HTTP::Date: '0'
  IO::Scalar: '0'
  IO::Socket::SSL: '2.069'
  IRI: '0'
  Modern::Perl: '1.20180701'
  Mojolicious: '9'
  Net::IDN::Encode: '0'
  Net::SSLeay: '1.9'
  Text::Wrapper: '0'
  URI::Escape: '0'
  XML::LibXML: '0'
  perl: '5.026000'
resources:

Makefile.PL  view on Meta::CPAN

  ],
  PREREQ_PM => {
    # t/prerequisites.t is serious about all these!
    'Modern::Perl' => 1.20180701, # for '2018'
    'URI::Escape' => 0,
    'Encode::Locale' => 0,
    'Algorithm::Diff' => 0,
    'File::ReadBackwards' => 0,
    'File::Slurper' => 0,
    'Mojolicious' => 9.00,        # removed tls_verify from Mojo::IOLoop::TLS 9.0
    'IO::Socket::SSL' => 2.069,   # optional for Mojo::IOLoop
    'Net::SSLeay' => 1.90,
    'Net::IDN::Encode' => 0,
    'IRI' => 0,                   # for script/gemini
    'Text::Wrapper' => 0,         # Gopher.pm
    'File::MimeInfo' => 0,        # Iapetus.pm, Capsules.pm
    'File::MimeInfo::Magic' => 0, # WebDAV.pm
    'IO::Scalar' => 0,            # WebDAV.pm
    'HTTP::Date' => 0,            # WebDAV.pm
    'XML::LibXML' => 0,           # WebDAV.pm
  },

Makefile.PL  view on Meta::CPAN

	openssl x509 -in cert.pem -text

# Generate client certificates for testing. These use eliptic
# curves and are valid for five years.
client-cert:
	openssl req -new -x509 -newkey ec \
	-pkeyopt ec_paramgen_curve:prime256v1 \
	-days 1825 -nodes -out client-cert.pem -keyout client-key.pem

# Generates the fingerprint of the client certificate in a form
# suitable for comparison with fingerprints by IO::Socket::SSL.
client-fingerprint:
	openssl x509 -in client-cert.pem -noout -sha256 -fingerprint \
	| sed -e 's/://g' -e 's/SHA256 Fingerprint=/sha256$$/' | tr [:upper:] [:lower:]

PHOEBE_TARGETS
}

README.md  view on Meta::CPAN


## Dependencies

If you are not using `cpan` or `cpanm` to install Phoebe, you'll need to install
the following dependencies:

- [Algorithm::Diff](https://metacpan.org/pod/Algorithm%3A%3ADiff), or `libalgorithm-diff-xs-perl`
- [File::ReadBackwards](https://metacpan.org/pod/File%3A%3AReadBackwards), or `libfile-readbackwards-perl`
- [File::Slurper](https://metacpan.org/pod/File%3A%3ASlurper), or `libfile-slurper-perl`
- [Mojolicious](https://metacpan.org/pod/Mojolicious), or `libmojolicious-perl`
- [IO::Socket::SSL](https://metacpan.org/pod/IO%3A%3ASocket%3A%3ASSL), or `libio-socket-ssl-perl`
- [Modern::Perl](https://metacpan.org/pod/Modern%3A%3APerl), or `libmodern-perl-perl`
- [URI::Escape](https://metacpan.org/pod/URI%3A%3AEscape), or `liburi-escape-xs-perl`
- [Net::IDN::Encode](https://metacpan.org/pod/Net%3A%3AIDN%3A%3AEncode), or `libnet-idn-encode-perl`
- [Encode::Locale](https://metacpan.org/pod/Encode%3A%3ALocale), or `libencode-locale-perl`

I'm going to be using `curl` and `openssl` in the Quickstart section of
`phoebe`, so you'll need those tools as well. And finally, when people download
their data, the code calls `tar` (available from packages with the same name on
Debian derived systems).

lib/App/Phoebe/Oddmuse.pm  view on Meta::CPAN

    $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,

lib/App/Phoebe/Oracle.pm  view on Meta::CPAN


    our $oracle_space = 'truth';

If you want to change the maximu number of answers that a question may have:

    our $max_answers = 5;

If you want to notify Antenna whenever a new question has been asked:

    use App::Phoebe qw($log);
    use IO::Socket::SSL;
    # a very simple Gemini client
    sub query {
      my $url = shift;
      my($scheme, $authority, $path, $query, $fragment) =
	$url =~ m|(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(\S*))?|;
      my ($host, $port) = split(/:/, $authority);
      my $socket = IO::Socket::SSL->new(
	PeerHost => $host, PeerPort => $port||1965,
	# don't verify the server certificate
	SSL_verify_mode => SSL_VERIFY_NONE, );
      $socket->print($url);
      local $/ = undef; # slurp
      return <$socket>;
    }
    # wrap the save_data sub in our own code
    *old_save_oracle_data = \&App::Phoebe::Oracle::save_data;
    *App::Phoebe::Oracle::save_data = \&new_save_oracle_data;

script/phoebe  view on Meta::CPAN


=cut

use FindBin;
use lib "$FindBin::Bin/../lib";
use App::Phoebe qw($log $server host_regex handle_request get_ip_numbers);
use Modern::Perl '2018';
use File::Slurper qw(read_dir);
use Encode qw(decode);
use Encode::Locale;
use IO::Socket::SSL;
use Mojo::IOLoop;
use Getopt::Long;
use Pod::Text;
use utf8;
use B;

# Some of these need to be decoded (hostnames, pagenames).
GetOptions(
  $server,
  'help' => \&help,

script/titan  view on Meta::CPAN

    echo "This is my test." \
      | titan --url=titan://transjovian.org/test/raw/testing --token=hello

=cut

use Modern::Perl '2018';
use Pod::Text;
use URI::Escape;
use File::Basename;
use File::Temp qw(tempfile);
use IO::Socket::SSL;
use Getopt::Long;

my $cert;
my $key;
my $token;
my $help;
my $mime;

GetOptions ("cert_file=s" => \$cert,
	    "key_file=s" => \$key,

script/titan  view on Meta::CPAN

  $type =~ s/\s+$//; # remove trailing whitespace

  # If the URL ends in a slash, append the URI-escaped filename without suffix
  my $furl = $url;
  if ($path =~ /\/$/) {
    my ($name) = fileparse($file, '.gmi');
    $furl .= uri_escape($name);
  }

  # create client
  my $socket = IO::Socket::SSL->new(%args)
      or die "Cannot construct client socket: $@";

  # send data in one go
  print $socket "$furl;size=$size;mime=$type;token=$token\r\n$data";

  # print response
  my $response = <$socket>;
  if ($response) {
    $response =~ s/\r//g;
    print $response;

t/00_tls_check.t  view on Meta::CPAN

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

use Modern::Perl;
use Mojo::IOLoop;
use IO::Socket::SSL;

# We're using the same cert for server and client, just so we can test client
# cert fingerprinting on the server side.

require './t/cert.pl';

my $address = '127.0.0.1';
my $port = Mojo::IOLoop::Server->generate_port;
my $pid = fork();

t/00_tls_check.t  view on Meta::CPAN

    });
    # Write request
    $stream->write("$query")
  });
  # Start event loop if necessary
  Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
}

sub query2 {
  my $query = shift;
  my $socket = IO::Socket::SSL->new(
    PeerHost => $address, PeerPort => $port,
    # don't verify the server certificate
    SSL_verify_mode => SSL_VERIFY_NONE,
    SSL_cert_file => 't/cert.pem',
    SSL_key_file => 't/key.pem', );
  $socket->print("$query");
  undef $/; # slurp
  my $fingerprint = 'sha256$0ba6ba61da1385890f611439590f2f0758760708d1375859b2184dcd8f855a00';
  is(<$socket>, "Got 'Hello2' from client $fingerprint\n", "IO::Socket::SSL");
}

t/Gopher.t  view on Meta::CPAN

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

use Modern::Perl;
use Test::More;
use File::Slurper qw(write_text read_binary);
use IO::Socket::IP;
use IO::Socket::SSL;
use Mojo::IOLoop::Server;
use utf8; # tests contain UTF-8 characters and it matters

plan skip_all => 'This is an author test. Set $ENV{TEST_AUTHOR} to a true value to run.' unless $ENV{TEST_AUTHOR};

our $host;
our @hosts = qw(localhost 127.0.0.1); # localhost must come first
our @spaces = qw(localhost/alex);
our $dir;
our $base;

t/Gopher.t  view on Meta::CPAN

EOF

require './t/test.pl';

sub query_gopher {
  my $query = shift;
  my $tls = shift;
  # create client
  my $socket;
  if ($tls) {
    $socket = IO::Socket::SSL->new(
      PeerHost => $host, PeerPort => $gophers_port,
      SSL_verify_mode => SSL_VERIFY_NONE)
	or die "Cannot construct client socket: $@";
  } else {
    $socket = IO::Socket::IP->new("$host:$gopher_port")
	or die "Cannot construct client socket: $@";
  }
  $socket->print("$query\r\n");
  undef $/; # slurp
  return <$socket>;

t/Iapetus.t  view on Meta::CPAN

# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

use App::Phoebe;
use Modern::Perl;
use Test::More;
use IO::Socket::SSL;
use utf8; # tests contain UTF-8 characters and it matters

our @use = qw(Iapetus);

our @config = (<<'EOT');
package App::Phoebe;
our @known_fingerprints = qw(
    sha256$0ba6ba61da1385890f611439590f2f0758760708d1375859b2184dcd8f855a00);
EOT

t/Iapetus.t  view on Meta::CPAN

our $port;

# test page
my $page = query_gemini("$base/Haiku");
like($page, qr/^51 Path not found/m, "Test page does not exist");

# upload text
sub iapetus {
  my $request = shift;
  my $data = shift;
  my $socket = IO::Socket::SSL->new(
    PeerHost => $host, PeerPort => $port,
    # don't verify the server certificate
    SSL_verify_mode => SSL_VERIFY_NONE,
    SSL_cert_file => 't/cert.pem',
    SSL_key_file => 't/key.pem', );
  $socket->print($request);
  is(<$socket>, "10 Continue\r\n");
  $socket->print($data);
  undef $/; # slurp
  return <$socket>;



( run in 0.640 second using v1.01-cache-2.11-cpan-4d50c553e7e )