AnyEvent-FTP

 view release on metacpan or  search on metacpan

lib/AnyEvent/FTP/Server/Role/TransferPrep.pm  view on Meta::CPAN

# ABSTRACT: Interface for PASV, PORT and REST commands
our $VERSION = '0.20'; # VERSION


has data => (
  is => 'rw',
);


has restart_offset => (
  is => 'rw',
);


sub clear_data
{
  my($self) = @_;
  $self->data(undef);
  $self->restart_offset(undef);
}


sub help_pasv { 'PASV (returns address/port)' }

sub cmd_pasv
{
  my($self, $con, $req) = @_;

  my $count = 0;

  tcp_server undef, undef, sub {
    my($fh, $host, $port) = @_;
    return close $fh if ++$count > 1;

    my $handle;
    $handle = AnyEvent::Handle->new(
      fh => $fh,
      on_error => sub {
        $_[0]->destroy;
        undef $handle;
      },
      on_eof => sub {
        $handle->destroy;
        undef $handle;
      },
      autocork => 1,
    );

    $self->data($handle);
    # TODO this should be with the 227 message below.
    # demoting this to a TODO (was a F-I-X-M-E)
    # since I can't remember why I thought it needed
    # doing. plicease 12-05-2014
    $self->done;

  }, sub {
    my($fh, $host, $port) = @_;
    my $ip_and_port = join(',', split(/\./, $con->ip), $port >> 8, $port & 0xff);

    my $w;
    $w = AnyEvent->timer(after => 0, cb => sub {
      $con->send_response(227 => "Entering Passive Mode ($ip_and_port)");
      undef $w;
    });

  };

  return;
}


sub help_port { 'PORT <sp> h1,h2,h3,h4,p1,p2' }

sub cmd_port
{
  my($self, $con, $req) = @_;

  if($req->args =~ /(\d+,\d+,\d+,\d+),(\d+),(\d+)/)
  {
    my $ip = join '.', split /,/, $1;
    my $port = $2*256 + $3;

    tcp_connect $ip, $port, sub {
      my($fh) = @_;
      unless($fh)
      {
        $con->send_response(500 => "Illegal PORT command");
        $self->done;
        return;
      }

      my $handle;
      $handle = AnyEvent::Handle->new(
        fh => $fh,
        on_error => sub {
          $_[0]->destroy;
          undef $handle;
        },
        on_eof => sub {
          $handle->destroy;
          undef $handle;
        },
      );

      $self->data($handle);
      $con->send_response(200 => "Port command successful");
      $self->done;

    };

  }
  else
  {
    $con->send_response(500 => "Illegal PORT command");
    $self->done;
    return;
  }
}


sub help_rest { 'REST <sp> byte-count' }



( run in 0.926 second using v1.01-cache-2.11-cpan-39bf76dae61 )