Paws

 view release on metacpan or  search on metacpan

lib/Paws/API/EndpointResolver.pm  view on Meta::CPAN

    lazy => 1,
    init_arg => undef, 
    default => sub {
      my $self = shift;
      my $sig_region;
   
      # For global services:   don't specify region: we sign with the region in the credentialScope
      #                        specify the region: we override the credentialScope (use the region specified)
      # For regional services: use the region specified for signing
      # If endpoint is specified: use the region specified (no _endpoint_info) 
      if (defined $self->_endpoint_info->{ credentialScope } and not defined $self->region) {
        $sig_region = $self->_endpoint_info->{ credentialScope }->{ region }
      }
      $sig_region = $self->region if (not defined $sig_region);

      Paws::Exception->throw(
        message => "Can't find a region for signing. region is required",
        code => 'NoRegionError',
        request_id => ''
      ) if (not defined $sig_region);

      return $sig_region;
    },
  );

  subtype 'Paws::EndpointURL',
       as 'URI';

  coerce 'Paws::EndpointURL',
    from 'Str',
     via { URI->new($_); };

  has endpoint => (
    is => 'ro',
    isa => 'Paws::EndpointURL',
    lazy => 1,
    coerce => 1,
    default => sub {
      shift->_endpoint_info->{ url };
    }
  );

  has endpoint_host => (
    is => 'ro',
    isa => 'Str',
    lazy => 1,
    default => sub {
      shift->endpoint->host;
    }
  ); 

  has _api_endpoint => (
    is => 'ro',
    isa => 'Str',
    lazy => 1,
    default => sub {
      shift->endpoint->as_string;
    }
  ); 

  has region_rules => (is => 'ro', isa => 'ArrayRef');

  has _default_rules => (is => 'ro', isa => 'ArrayRef', default => sub {
    [ { constraints => [ [ 'region', 'startsWith', 'cn-' ] ], 
        properties => { signatureVersion => 'v4' }, 
        uri => '{scheme}://{service}.{region}.amazonaws.com.cn'
      },
      { constraints => [ [ 'region', 'notEquals', undef ] ],
        uri => '{scheme}://{service}.{region}.amazonaws.com'
      },
    ]    
    },
  );

  has default_scheme => ( is => 'ro', isa => 'Str', default => 'https' );

  sub _construct_endpoint {
    my ($self) = @_;

    my $args = {};
    $args->{ service } = $self->service;
    $args->{ region  } = $self->region;
    $args->{ scheme  } = $self->default_scheme if (not defined $args->{scheme});

    my $service_rules = $self->region_rules;
    my $endpoint_info = $self->_match_rules($self->region_rules, $args->{ region }, $args);
    if (not defined $self->region_rules) {
      $endpoint_info = $self->_match_rules($self->region_rules, $args->{ region }, $args);
    }
    if (not defined $endpoint_info) {
      $endpoint_info = $self->_match_rules($self->_default_rules, $args->{ region }, $args);
    }

    if ( not defined $endpoint_info ) {
      my $region_for_exception = (defined $args->{ region }) ? $args->{ region } : '';
      Paws::Exception->throw(
        message => "No endpoint for service $args->{ service } in region '$region_for_exception'",
        code => 'NoRegionError',
        request_id => ''
      );
    } else {
      my $template = URI::Template->new($endpoint_info->{uri});
      my $url = $template->process($args);
      $endpoint_info->{ url } = $url;
    }

    return $endpoint_info;
  }

  sub _match_rules {
    my ( $self, $service_rules, $region, $args ) = @_;

    return undef if (not defined $service_rules);
    return undef if scalar(@$service_rules) == 0;

    for my $rule ( @$service_rules ) {
      if ( $self->_matches_rule($rule, $region, $args) ) {
        return { uri => $rule->{ uri }, (defined $rule->{ properties }) ? %{ $rule->{ properties } } : () };
      }
    }
    return undef;
  }



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