diff --git a/bin/pt-agent b/bin/pt-agent index a52e583e..c14242bb 100755 --- a/bin/pt-agent +++ b/bin/pt-agent @@ -969,9 +969,9 @@ sub post { } sub put { - my ($self, %args) = @_; + my $self = shift; $self->_set( - %args, + @_, method => 'PUT', ); return $self->response->header('Location'); @@ -979,7 +979,6 @@ sub put { sub delete { my ($self, %args) = @_; - have_required_args(\%args, qw( link )) or die; @@ -1006,7 +1005,6 @@ sub delete { sub _set { my ($self, %args) = @_; - have_required_args(\%args, qw( method resources @@ -1016,6 +1014,8 @@ sub _set { my $res = $args{resources}; my $link = $args{link}; + my $headers = $args{headers}; + my $content = ''; if ( ref($res) eq 'ARRAY' ) { PTDEBUG && _d('List of resources'); @@ -1047,6 +1047,7 @@ sub _set { method => $method, link => $link, content => $content, + headers => $headers, ); }; if ( my $e = $EVAL_ERROR ) { @@ -1070,27 +1071,22 @@ sub _request { )) or die; my $method = $args{method}; my $link = $args{link}; - - my @optional_args = ( - 'content', - 'headers', - ); - my ($content, $headers) = @args{@optional_args}; + + my $content = $args{content}; + my $headers = $args{headers}; my $req = HTTP::Request->new($method => $link); - $req->content($content) if $content; - if ( uc($method) eq 'DELETE' ) { - $self->ua->default_header('Content-Length' => 0); + if ( $content ) { + $req->content($content); + } + if ( $headers ) { + map { $req->header($_ => $headers->{$_}) } keys %$headers; } PTDEBUG && _d('Request', $method, $link, Dumper($req)); my $response = $self->ua->request($req); PTDEBUG && _d('Response', Dumper($response)); - if ( uc($method) eq 'DELETE' ) { - $self->ua->default_header('Content-Length' => undef); - } - if ( !($response->code >= 200 && $response->code < 400) ) { die Percona::WebAPI::Exception::Request->new( method => $method, @@ -5650,7 +5646,7 @@ sub send_file { my $agent_json = as_json($agent, json => $json); chomp($agent_json); - my $boundary = '--Ym91bmRhcnk='; # "boundary" in base64 + my $boundary = 'Ym91bmRhcnk'; # "boundary" in base64, without a trailing = my $data = slurp($file); $data =~ s/^\s+//; @@ -5658,14 +5654,23 @@ sub send_file { # Put it all together: my $resource = <post( link => $link, resources => $resource, + headers => { + 'Content-Type' => "multipart/form-data; boundary=$boundary", + } ); return; diff --git a/lib/Percona/Test/Mock/UserAgent.pm b/lib/Percona/Test/Mock/UserAgent.pm index cdfefcd4..d41fcf60 100644 --- a/lib/Percona/Test/Mock/UserAgent.pm +++ b/lib/Percona/Test/Mock/UserAgent.pm @@ -35,12 +35,14 @@ sub new { post => [], put => [], }, + last_request => undef, }; return bless $self, $class; } sub request { my ($self, $req) = @_; + $self->{last_request} = $req; my $type = lc($req->method); push @{$self->{requests}}, uc($type) . ' ' . $req->uri; if ( $type eq 'post' || $type eq 'put' ) { diff --git a/lib/Percona/WebAPI/Client.pm b/lib/Percona/WebAPI/Client.pm index 2a968f53..22b54f33 100644 --- a/lib/Percona/WebAPI/Client.pm +++ b/lib/Percona/WebAPI/Client.pm @@ -168,12 +168,10 @@ sub post { return $self->response->header('Location'); } -# For a successful PUT, the server returns nothing because the caller -# already has the resources URI (if not, the caller should POST). sub put { - my ($self, %args) = @_; + my $self = shift; $self->_set( - %args, + @_, method => 'PUT', ); return $self->response->header('Location'); @@ -181,7 +179,6 @@ sub put { sub delete { my ($self, %args) = @_; - have_required_args(\%args, qw( link )) or die; @@ -209,7 +206,6 @@ sub delete { # Low-level POST and PUT handler. sub _set { my ($self, %args) = @_; - have_required_args(\%args, qw( method resources @@ -219,6 +215,9 @@ sub _set { my $res = $args{resources}; my $link = $args{link}; + # Optional args + my $headers = $args{headers}; + my $content = ''; if ( ref($res) eq 'ARRAY' ) { PTDEBUG && _d('List of resources'); @@ -250,6 +249,7 @@ sub _set { method => $method, link => $link, content => $content, + headers => $headers, ); }; if ( my $e = $EVAL_ERROR ) { @@ -276,27 +276,23 @@ sub _request { )) or die; my $method = $args{method}; my $link = $args{link}; - - my @optional_args = ( - 'content', - 'headers', - ); - my ($content, $headers) = @args{@optional_args}; + + # Optional args + my $content = $args{content}; + my $headers = $args{headers}; my $req = HTTP::Request->new($method => $link); - $req->content($content) if $content; - if ( uc($method) eq 'DELETE' ) { - $self->ua->default_header('Content-Length' => 0); + if ( $content ) { + $req->content($content); + } + if ( $headers ) { + map { $req->header($_ => $headers->{$_}) } keys %$headers; } PTDEBUG && _d('Request', $method, $link, Dumper($req)); my $response = $self->ua->request($req); PTDEBUG && _d('Response', Dumper($response)); - if ( uc($method) eq 'DELETE' ) { - $self->ua->default_header('Content-Length' => undef); - } - if ( !($response->code >= 200 && $response->code < 400) ) { die Percona::WebAPI::Exception::Request->new( method => $method, diff --git a/t/pt-agent/samples/query-history/data001.send b/t/pt-agent/samples/query-history/data001.send index 07bbdb33..023a8a44 100644 --- a/t/pt-agent/samples/query-history/data001.send +++ b/t/pt-agent/samples/query-history/data001.send @@ -1,8 +1,13 @@ +--Ym91bmRhcnk +Content-Disposition: form-data; name="agent" + { "hostname" : "prod1", "uuid" : "123" } ---Ym91bmRhcnk= +--Ym91bmRhcnk +Content-Disposition: form-data; name="data" + [ { "attributes" : { @@ -74,3 +79,4 @@ } } ] +--Ym91bmRhcnk diff --git a/t/pt-agent/send_data.t b/t/pt-agent/send_data.t index d651f2db..1b2f1292 100644 --- a/t/pt-agent/send_data.t +++ b/t/pt-agent/send_data.t @@ -138,6 +138,12 @@ ok( "Removed data file after sending successfully" ); +is( + $ua->{last_request}->header('content-type'), + 'multipart/form-data; boundary=Ym91bmRhcnk', + 'Content-Type=multipart/form-data; boundary=Ym91bmRhcnk' +) or diag(Dumper($ua)); + # ############################################################################# # Done. # #############################################################################