| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 | #!/usr/bin/perluse Modern::Perl;# Клиент для Дарсана, версия 2# Ю. Жиловец, 17.02.2015package darsan_client;use Mojo::UserAgent;use URI::Query;use Mojo::JSON qw/j/;use Data::Dumper;use utf8;sub new{  my $class = shift;  my $auth = shift;  my $tpl = shift;  return bless {auth=>$auth,tpl=>$tpl,error=>undef, ua => new Mojo::UserAgent}, $class;}sub source_ip{  my $self = shift;  my $ip = shift;  $self->{ua}->local_address($ip);}sub error{  return $_[0]->{error};}sub _query{  my $self = shift;  my $method = shift;  my $url = shift;  my $sub = pop;  my @rest = @_;  undef $self->{error};  my $is_raw = 0;  if ($method eq "GET_RAW")  {    $method = "GET";    $is_raw = 1;  }  my $headers = {};  $headers = shift(@rest) if @rest && ref($rest[0]) eq "HASH";   my $make_query = sub   {      my $token = shift;        $headers->{Authorization} = "Darsan2 $token";      return $self->{ua}->build_tx($method,$url,$headers,@rest);   };  if ($sub && $sub eq "promise")  {    return $self->_promise_query($make_query, $is_raw);  }  elsif ($sub)  {    return $self->_async_query($sub, $make_query, $is_raw);  }  else  {    return $self->_sync_query($make_query, $is_raw);  }}sub _sync_query{  my $self = shift;  my $make_query = shift;  my $is_raw = shift;    my $token = $self->{auth}->token;  if ($self->{auth}->error)  {    $self->{error} = "darsan_auth: ".$self->{auth}->error;    return undef;  }  my $tx = $self->{ua}->start($make_query->($token));  my $resp = $tx->result; if ($resp->is_error) {    my $e = $tx->error;     $e->{code} ||= 500;    $self->{error} = "$e->{code} $e->{message}/".substr($tx->res->body,0,500);    return undef;  }  return $resp if $is_raw;  return $resp->headers->content_type =~ m|application/json| ? j($resp->body) : $resp->body;}sub _async_query{  my $self = shift;  my $sub = shift;  my $make_query = shift;  my $is_raw = shift;    $self->{auth}->token(sub   {      my ($err,$token) = @_;      return $sub->({code=>500, message=>"darsan_auth: cannot get token: $err->{message}"}) if $err;      my $tx = $self->{ua}->start($make_query->($token) => sub      {         my ($ua, $tx) = @_;        my $resp = $tx->result;              if ($resp->is_error)        {          my $e = $tx->error;          $e->{code} ||= 500;          my $error = { code=>$e->{code}, message=>$e->{message}, response=>$tx->res };          return $sub->($error);        }                $sub->(undef,$is_raw ? $resp : j($resp->body));      });  });}sub _promise_query{  my $self = shift;  my $make_query = shift;  my $is_raw = shift;    return $self->{auth}->token("promise")->then(sub  {      my $token = shift;      my $tx = $self->{ua}->start_p($make_query->($token))->then(sub      {         my $tx = shift;        my $resp = $tx->result;                if ($resp->is_success)        {           $is_raw ? $resp : j($resp->body);        }        else        {          my $body = $resp->body;          utf8::decode($body);          die {code=>$resp->{code}, message=>$resp->{message}, body=>$body, content_type=>$resp->headers->header("Content-Type")};        }      });  }, sub   {    my $err = shift;    die {code=>500, message=>"darsan_auth: cannot get token from $err->{url}: $err->{code} $err->{message}"};  });}sub get{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};  my $sub = shift;    my $q = URI::Query->new($params);  $q = "?$q" if $q;  my $url = $self->_make_server($topic).$path.$q;  return $self->_query(GET => $url => $sub);}sub get_p{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};  return $self->get($topic, $path, $params, "promise");}sub get_raw{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};  my $sub = shift;              my $q = URI::Query->new($params);  $q = "?$q" if $q;  my $url = $self->_make_server($topic).$path.$q;  return $self->_query(GET_RAW => $url => $sub);}sub get_raw_p{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};              return $self->get_raw($topic, $path, $params, "promise");            }sub post{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};  my $sub = shift;    my $url = $self->_make_server($topic).$path;  return $self->_query(POST => $url => form => $params => $sub);}sub post_p{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};  return $self->post($topic, $path, $params, "promise");  }sub post_json{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};  my $sub = shift;    my $url = $self->_make_server($topic).$path;  return $self->_query(POST => $url => { "Content-Type"=>"application/json" } => j($params) => $sub);}sub post_json_p{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};    my $url = $self->_make_server($topic).$path;  return $self->_query(POST => $url => { "Content-Type"=>"application/json" } => j($params) => "promise");}sub delete{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};  my $sub = shift;  my $url = $self->_make_server($topic).$path;  return $self->_query(DELETE => $url => form => $params => $sub);}sub delete_p{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};  $self->delete($topic, $path, $params, "promise");  }sub put{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};  my $sub = shift;    my $url = $self->_make_server($topic).$path;  return $self->_query(PUT => $url => form => $params => $sub);}sub put_p{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};  $self->put_p($topic, $path, $params, "promise");  }sub patch{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};  my $sub = shift;  my $url = $self->_make_server($topic).$path;  return $self->_query(PATCH => $url => form => $params => $sub);}sub patch_json{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};  my $sub = shift;  my $url = $self->_make_server($topic).$path;  return $self->_query(PATCH => $url => { "Content-Type"=>"application/json" } => j($params) => $sub);}sub patch_p{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};  $self->patch($topic, $path, $params, "promise");  }sub patch_json_p{  my $self = shift;  my $topic = shift;  my $path = shift;  my $params = shift || {};  $self->patch_json($topic, $path, $params, "promise");  }sub map{  my $self = shift;  my $map = shift;  $self->{map} = $map;}sub _make_server{  my $self = shift;  my $topic = shift;  return $self->{map}->{$topic} if $self->{map} && exists $self->{map}->{$topic};  my $server = $self->{tpl};  $server =~ s/\{entity\}/$topic/;  $server =~ s/darsan-darsan/darsan/;  return $server;}1;
 |