Search code examples
perlcurlunicodehttpslwp

Curl works fine but Perl LWP failed to post Unicode code to HTTPS server


My snippet as below, using curl I can send the Unicode string to the server and after push notify the message to my mobile phone, displayed correctly the Chinese characters on the phone.

      curl  "https://oapi.dingtalk.com/robot/send?access_token=$ACCESS_TOKEN" \
   -H 'Content-Type: application/json' \
   -d '{"msgtype": "text", "text": {
        "content": "\u6d4b\u8bd5",
     }}' 

But when I use the Perl LWP library to send the same content to the server, I only got 6d4b8bd5 displayed on the app. I've tried to use tcpdump to compare the difference between curl and LWP sent out buffer, but as it's https server it's not working.

    #!/usr/bin/perl -w
use strict;
use warnings;
use Cpanel::JSON::XS qw( encode_json );
# Create a user agent object
use LWP::UserAgent;
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;

my $ua = LWP::UserAgent->new;
$ua->agent("curl/7.47.0");


# Create a request
my $req = HTTP::Request->new(POST => 'https://oapi.dingtalk.com/robot/send?access_token=bf47148ea6a1b125395f9313873ac508');

$req->content_type('application/json;charset=utf-8');

my $var='\u6d4b\u8bd5';

my $message = encode_json({ msgtype => "text", text => { content => $var } });

$req->content($message);

# Pass request to the user agent and get a response back
my $res = $ua->request($req);

# Check the outcome of the response
if ($res->is_success) {
  print $res->content;
} else {
  print $res->status_line, "n";
}

any suggestions? Thanks!


Solution

  • Earlier, you didn't encode. Now, you double encode. encode_json is already handling the encoding to JSON, so don't do it manually too!

    If you provide the 12 characters \u6d4b\u8bd5, it will receive the 12 characters \u6d4b\u8bd5.

    If you provide the two characters U+6D4B and U+8BD5, it will receive the two characters U+6D4B and U+8BD5.

    • my $var = chr(0x6D4B) . chr(0x8BD5);
    • my $var = "\x{6D4B}\x{8BD5}";
    • my $var = "\N{U+6D4B}\N{U+8BD5}";
    • use utf8; my $var = "测试";
    • etc