1

Just curious to know the difference between below three executions, If I use a variable to hold the json data and pass the same to curl command, json msg become corrupt and server returns incorrect result, What is the best way to pass json from a variable while invoking curl command ? Trying to make the last line in the snippet work.

my $tsFormatted = '2021-06-10';
my $metaLoad = '{"validDate": "'.$tsFormatted.'"}';

my $curl_out_1 = `curl -s -X POST -H 'Content-Type: application/json' $mw_meta_load_api --key $mw_access_key --cert $mw_access_cert --data '{"validDate": "2021-06-10"}'`;

my $curl_out_2 = `curl -s -X POST -H 'Content-Type: application/json' $mw_meta_load_api --key $mw_access_key --cert $mw_access_cert --data '{"validDate": "'.$tsFormatted.'"}'`;

my $curl_out_3 = `curl -s -X POST -H 'Content-Type: application/json' $mw_meta_load_api --key $mw_access_key --cert $mw_access_cert --data $metaLoad`;

1 Answer 1

4

Backticks interpolate as double-quoted strings, so we can easily view the difference by using double-quoted string literals instead of backticks.

my $tsFormatted = '2021-06-10';
my $metaLoad = '{"validDate": "'.$tsFormatted.'"}';

# qq`...`, qq"..." and "..." are all the same thing.
say qq`... --data '{"validDate": "2021-06-10"}'`;
say qq`... --data '{"validDate": "'.$tsFormatted.'"}'`;
say qq`... --data $metaLoad`;

Output:

... --data '{"validDate": "2021-06-10"}'
... --data '{"validDate": "'.2021-06-10.'"}'
... --data {"validDate": "2021-06-10"}

The contents of string literals (including backticks) aren't treated as Perl code.


Of those three, only the first is correct.

The first passes the following two arguments to curl:

  • --data
  • {"validDate": "2021-06-10"}

The second passes the following two arguments to curl:

  • --data
  • {"validDate": ".2021-06-10."}

The third passes the following three arguments to curl:

  • --data
  • {validDate:
  • 2021-06-10}

What you want:

use Cpanel::JSON::XS   qw( encode_json );
use String::ShellQuote qw( shell_quote );

my $ts_formatted = '2021-06-10';
my $data = { validDate => $ts_formatted };
my $data_formatted = encode_json($data);

my $cmd = shell_quote(
   curl => (
      $mw_meta_load_api,
      '-s',
      -X       => 'POST',
      -H       => 'Content-Type: application/json',
      '--key'  => $mw_access_key,
      '--cert' => $mw_access_cert,
      '--data' => $data_formatted,
   )
);

my $out = `$cmd`;
die("Can't execute shell: $!\n")                 if $? == -1;
die("curl killed by signal ".( $? & 0x7F )."\n") if $? & 0x7F;
die("curl exited with error ".( $? >> 8 )."\n")  if $? >> 8;

Also, have you considered using Net::Curl::Easy instead of shelling out?

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.