Skip to content

Commit

Permalink
Use XML::Hash::XS with native suppress_empty support
Browse files Browse the repository at this point in the history
  • Loading branch information
slobo committed Dec 28, 2019
1 parent 6c76619 commit 466226e
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 30 deletions.
2 changes: 1 addition & 1 deletion cpanfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ requires 'Data::Compare';
requires 'URI';
requires 'Net::Amazon::Signature::V4';
requires 'JSON::MaybeXS';
requires 'XML::Hash::XS';
requires 'XML::Hash::XS', '>= 0.54'; # 0.54 has suppress_empty support
requires 'IO::Socket::SSL';
requires 'DateTime';
requires 'DateTime::Format::ISO8601';
Expand Down
43 changes: 14 additions & 29 deletions lib/Paws/Net/XMLResponse.pm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package Paws::Net::XMLResponse;
use Moose;
use XML::Hash::XS qw//;
use XML::Hash::XS 0.54 qw//; # 0.54 introduces suppress_empty option

use Carp qw(croak);
use Paws::Exception;
Expand All @@ -9,15 +9,15 @@ package Paws::Net::XMLResponse;
default => sub {
return XML::Hash::XS->new(
force_array => qr/^(?:item|Errors)/i,
# SuppressEmpty => undef,
suppress_empty => undef,
);
}
);

sub unserialize_response {
my ($self, $response) = @_;

if (not defined $response->content or $response->content eq '') {
if (not defined $response->content or $response->content eq '') {
return Paws::Exception->new(
message => 'HTTP error with no body in HTTP response',
code => 'InvalidContent',
Expand All @@ -27,7 +27,6 @@ package Paws::Net::XMLResponse;
}

my $struct = eval { $self->_xml_parser->xml2hash($response->content) };
$struct = _emulate_xml_simple_supress_empty($struct);
if ($@){
return Paws::Exception->throw(
message => $@,
Expand All @@ -39,20 +38,6 @@ package Paws::Net::XMLResponse;
return $struct;
}

sub _emulate_xml_simple_supress_empty {
my ($struct) = @_;
return undef unless $struct;
foreach (keys %$struct) {
if (ref $struct->{$_} eq 'HASH') {
_emulate_xml_simple_supress_empty($struct->{$_})
}
elsif (defined $struct->{$_} && $struct->{$_} eq '') {
$struct->{$_} = undef;
}
}
return $struct;
}

sub process {
my ($self, $call_object, $response) = @_;

Expand All @@ -68,7 +53,7 @@ package Paws::Net::XMLResponse;

my $struct = $self->unserialize_response( $response );
return $struct if (ref($struct) eq 'Paws::Exception');

my ($code, $error, $request_id);

if (exists $struct->{Errors}){
Expand Down Expand Up @@ -121,7 +106,7 @@ package Paws::Net::XMLResponse;
}
$value_ref = ref($value);
}

if ($value_ref eq 'ARRAY') {
return $att_class->new(Map => { map { ( $_->{ $xml_keys } => $_->{ $xml_values } ) } @$value } );
} elsif ($value_ref eq 'HASH') {
Expand All @@ -147,7 +132,7 @@ package Paws::Net::XMLResponse;
}
$value_ref = ref($value);
}

my $inner_class = $att_class->meta->get_attribute('Map')->type_constraint->name;
($inner_class) = ($inner_class =~ m/\[(.*)\]$/);
Paws->load_class("$inner_class");
Expand All @@ -158,13 +143,13 @@ package Paws::Net::XMLResponse;
return $att_class->new(Map => { $value->{ $xml_keys } => $self->new_from_result_struct($inner_class, $value->{ $xml_values }) });
} elsif (not defined $value){
return $att_class->new(Map => {});
}
}
}

sub new_from_result_struct {
my ($self, $class, $result) = @_;
my %args;

if ($class->does('Paws::API::StrToObjMapParser')) {
return $self->handle_response_strtoobjmap($class, $result);
} elsif ($class->does('Paws::API::StrToNativeMapParser')) {
Expand Down Expand Up @@ -264,7 +249,7 @@ package Paws::Net::XMLResponse;
}
$value_ref = ref($value);
}

if ($type =~ m/\:\:/) {
Paws->load_class($type);

Expand All @@ -289,7 +274,7 @@ package Paws::Net::XMLResponse;
} else {
if (defined $value){
if ($value_ref eq 'ARRAY') {
$args{ $att } = $value;
$args{ $att } = $value;
} else {
$args{ $att } = [ $value ];
}
Expand All @@ -314,16 +299,16 @@ package Paws::Net::XMLResponse;

my $unserialized_struct = $self->unserialize_response( $response );
my $headers = $response->headers;
my $request_id = $headers->{'x-amz-request-id'}
my $request_id = $headers->{'x-amz-request-id'}
|| $headers->{'x-amzn-requestid'}
|| $unserialized_struct->{'requestId'}
|| $unserialized_struct->{'RequestId'}
|| $unserialized_struct->{'requestId'}
|| $unserialized_struct->{'RequestId'}
|| $unserialized_struct->{'RequestID'}
|| $unserialized_struct->{ ResponseMetadata }->{ RequestId };

# AWS has sent duplicate headers x-amx-request-id headers on some services. See issue 324 for more info
$request_id = (ref($request_id) eq 'ARRAY') ? $request_id->[0] : $request_id;

if ($returns){
if ($call_object->_result_key){
$unserialized_struct = $unserialized_struct->{ $call_object->_result_key };
Expand Down

0 comments on commit 466226e

Please sign in to comment.