# # (c) Jan Gehring <jan.gehring@gmail.com> # # vim: set ts=2 sw=2 tw=0: # vim: set expandtab: package Rex::Interface::Connection::HTTP; use strict; use warnings; our $VERSION = '1.7.0'; # VERSION use Rex::Interface::Connection::Base; BEGIN { LWP::UserAgent->use; JSON::MaybeXS->use; } use Data::Dumper; use base qw(Rex::Interface::Connection::Base); sub new { my $that = shift; my $proto = ref($that) || $that; my $self = $that->SUPER::new(@_); bless( $self, $proto ); # activate caching Rex::Config->set_use_cache(1); return $self; } sub error { } sub connect { my ( $self, %option ) = @_; my ( $user, $pass, $server, $port, $timeout ); $user = $option{user}; $pass = $option{password}; $server = $option{server}; $port = $self->_get_port( $option{port} ); $timeout = $option{timeout}; $self->{server} = $server; $self->{port} = $port; if ( $server =~ m/([^:]+):(\d+)/ ) { $server = $self->{server} = $1; $port = $self->{port} = $2; } $self->{__user} = $user; $self->{__pass} = $pass; if (!Rex::Config->has_user && Rex::Config->get_ssh_config_username( server => $server ) ) { $user = Rex::Config->get_ssh_config_username( server => $server ); } $self->ua->credentials( "$server:$port", "Rex::Endpoint::HTTP", $user => $pass, ); my $resp = $self->post("/login"); if ( $resp->{ok} ) { Rex::Logger::info("Connected to $server, trying to authenticate."); } else { Rex::Logger::info( "Can't connect to $server", "warn" ); $self->{connected} = 0; return; } Rex::Logger::info( "Connecting to $server:$port (" . $user . ")" ); } sub disconnect { } sub get_connection_object { my ($self) = @_; return $self; } sub get_fs_connection_object { my ($self) = @_; return $self; } sub is_connected { return 1; } sub is_authenticated { return 1; } sub exec { my ( $self, $cmd ) = @_; } sub ua { my ($self) = @_; return $self->{ua} if $self->{ua}; $self->{ua} = LWP::UserAgent->new; } sub upload { my ( $self, $data ) = @_; my $res = $self->ua->post( $self->_get_proto . "://" . $self->{server} . ":" . $self->{port} . "/fs/upload", Content_Type => "multipart/form-data", Content => $data ); if ( $res->is_success ) { return decode_json( $res->decoded_content ); } else { die("Error requesting /fs/upload."); } } sub post { my ( $self, $service, $data, $header ) = @_; $header ||= {}; $data ||= {}; if ( !ref($data) ) { die( "Invalid 2nd argument. must be arrayRef or hashRef!\npost(\$service, \$ref)" ); } my $res = $self->ua->post( $self->_get_proto . "://" . $self->{server} . ":" . $self->{port} . "$service", %{$header}, Content => encode_json($data) ); if ( $res->is_success ) { return decode_json( $res->decoded_content ); } else { die( "Error requesting $service.\n\nError: " . $res->{_content} ); } } sub get { my ( $self, $service ) = @_; my $res = $self->ua->get( $self->_get_proto . "://" . $self->{server} . ":" . $self->{port} . "$service" ); if ( $res->is_success ) { return decode_json( $res->decoded_content ); } else { die("Error requesting $service."); } } sub get_connection_type { return "HTTP"; } sub _get_proto { return "http"; } sub _get_port { my ( $self, $port ) = @_; return $port || 8080; } 1;