HTTP request doesn't get Json expression with values contain a dot "." - json

I have a Json expression that contains values with "." and # like this
{"queued":"C1F","messageid":"dfs.jfdsf#sdf.abc.fr"}
that doesn't get processed by HTTP POST request , and it's give me this result :
"code":400,"message":"Unable to process JSON
PS: my web server is created with dropWizard in Intellij IDEA
how can I resolve this problem
EDIT: this is the code used in perl
my $queued=$1; my $messageid=$2 ;
my $json= "{\"queued\":\"$queued\",\"messageid\":\"$messageid\"}";
$req1->content($json);
my $response=$ua->request($req1);
if ($response->is_success) {
my $message =$response->decoded_content ;
print "resultat : $message \n";
}
else {
print "erreur", $response->code, " ", $response->message, "\n" ;
}

It would be less error-prone to use the JSON library to build your JSON string
use JSON 'to_json';
my $json = to_json({ queued => $queued, messageid => $messageid });

Related

How to send a .json file from Flow to Azure Function and return results?

I want to send a serialized .json file to a PowerShell Azure Function, prettify it, then return the file to Flow for further processing. I cannot figure out how to do this.
In Flow:
Trigger: Button push
Action1: Get file content from OneDrive
Output:
{
"$content-type": "application/octet-stream",
"$content": "eyJUb3BQYXJlbnQiOns...<truncated for this post>"
}
Action2: Send HTTP Request
URI: https://test.azurewebsites.net/api/prettifyJson?code=<api key>
Method: POST
Body: body('Get_file_content') (output from Action1)
In Azure Function:
Default PowerShell run.ps1:
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."
# Interact with body of the request.
$content = $Request.Query.baz
if (-not $name) {
$name = $Request.Body.baz
}
if ($name) {
$status = [HttpStatusCode]::OK
$body = "Hello $name"
}
else {
$status = [HttpStatusCode]::BadRequest
$body = "Please pass a name on the query string or in the request body."
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]#{
StatusCode = $status
Body = $content
})
Issues:
A call to the function fails with Please pass a name on the query string or in the request body. I can see why, but do not know what syntax to replace in run.ps1
I have no idea what syntax to use to:
a. Receive the .json file
b. Convert it to pretty json
c. Repackage the .json file
d. Send it back to Flow
Looking for guidance.
About number one, seems you're missing the name in the url.
try to replace from this:
https://test.azurewebsites.net/api/prettifyJson?code=
to this:
https://test.azurewebsites.net/api/prettifyJson?name=test&code=
about your second question, the you'll need to parse the body content as Hashtable. try to combine:
$hash = $Request.Body | ConvertFrom-Json -AsHashtable
then all the variables will be available using $hash[]
e.g: $hash["$content"]

Parsing JSON In Perl

I'm trying to parse JSON data in Perl. it is request to Cisco Prime Service. My script works, but parsing doesn't work. And I have a warning,
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "HTTP::Response=HASH(...") at InternetBSP.pl line 39.
It is here:
my $json_text = $json->allow_nonref->utf8->relaxed->escape_slash->loose->allow_singlequote->allow_barekey->decode($res);
have no Idee how should I fix it...
use strict;
use warnings;
use JSON -support_by_pp;
use LWP 5.64;
use LWP::UserAgent;
use MIME::Base64;
use REST::Client;
use IO::Socket::SSL;
#So dass es auch ohne SSL Sertifizierung funktioniert
BEGIN { $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0 }
#Create a user agent object
my $ua = LWP::UserAgent->new(
ssl_opts => {
SSL_verify_mode => SSL_VERIFY_NONE(),
verify_hostname => 0,
}
);
#Create a request
my $req = HTTP::Request->new( GET => 'https://10.10.10.10/webacs/api/v1/data/AccessPoints.json?.full=true' );
$req->content_type('application/json');
$req->authorization_basic( "Username", "Password" );
#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";
}
my $json = new JSON;
my $json_text = $json->allow_nonref->utf8->relaxed->escape_slash->loose->allow_singlequote->allow_barekey->decode($res);
#my try to pasre the data
foreach my $ap ( #{ $json_text->{queryResponse}->{'entity'} } ) {
print "------------------------\nAccess Point " . $ap->{'accessPointsDTO'}->{'#id'} . "\n";
print "Model:" . $ap->{'accessPointsDTO'}->{'model'} . "\n";
print "MAC Address:" . $ap->{'accessPointsDTO'}->{'macAddress'} . "\n";
print "Serial Number:" . $ap->{'accessPointsDTO'}->{'serialNumber'} . "\n";
print "Software Version:" . $ap->{'accessPointsDTO'}->{'softwareVersion'} . "\n";
print "Status:" . $ap->{'accessPointsDTO'}->{'status'} . "\n";
print "Location:" . $ap->{'accessPointsDTO'}->{'location'} . "\n";
}
I have this like outcome:
{"queryResponse":{"#last":"7","#first":"0","#count":"8","#type":"AccessPoints","#responseType":"listEntityInstances","#requestUrl":"https:\/\/10.66.1.23\/webacs\/api\/v1\/ data\/AccessPoints?.full=true","#rootUrl":"https:\/\/10.66.1.23\/webacs\/api\/v1\/data","entity":[{"#dtoType":"accessPointsDTO","#type":"AccessPoints","#url":"https:\/\/10 .66.1.23\/webacs\/api\/v1\/data\/AccessPoints\/205320"
But it shoud be smth like:
{"queryResponse":
{"#type":"AccessPoints",
"#rootUrl":"https://172.18.138.90/webacs/api/v1/data",
"#requestUrl":"https://172.18.138.90/webacs/api/v1/data/AccessPoints?.full=true",
"#responseType":"listEntityInstances",
"entity":[
{"#url":"https://172.18.138.90/webacs/api/v1/data/AccessPoints/13544533",
"#type":"AccessPoints",
"#dtoType":"accessPointsDTO",
"accessPointsDTO":
{"#id":"13544533",
"#displayName":"13544533",
"adminStatus":"ENABLE",
"bootVersion":"12.4.23.0",
"clientCount":0,
After update :)
------------------------
Access Point 205320
Model:AIR-LAP1142N-E-K9
MAC Address:6c:9c:ed:b5:45:60
Serial Number:FCZ1544W51B
Software Version:7.6.130.0
Status:CLEARED
Location:de.bw.stu.
------------------------
Access Point 205322
Model:AIR-CAP3502I-E-K9
MAC Address:0c:f5:a4:ee:70:10
Serial Number:FCZ184680VB
Software Version:7.6.130.0
Status:CLEARED
Location:de.bw.stu.
------------------------
Access Point 205324
Model:AIR-LAP1142N-E-K9
MAC Address:6c:9c:ed:86:9d:20
Serial Number:FCZ1544W50Y
Software Version:7.6.130.0
Status:CLEARED
Location:de.bw.stu.
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "HTTP::Response=HASH(...")
This error message means that the data you are giving to decode is not JSON.
You are passing $res to decode, which is an HTTP::Response object (see above, emphasis mine). You need to use $res->content, which you use for debugging output a few lines above.
if ($res->is_success) {
print $res->content;
} else {print $res->status_line, "n";
}
I would rewrite that whole block of code to this.
die $res->status_line unless $res->is_success;
my $json = JSON->new->allow_nonref
->utf8->relaxed
->escape_slash->loose
->allow_singlequote->allow_barekey;
my $json_text = $json->decode( $res->content );
Instead of printing some debug output and then going on anyway if things went wrong you can just die if the request was not successful.
After that, create your JSON object and configure it. This is way more readable than this long line of code, and we're using a method call to new instead of indirect object notation.
Finally, we are decodeing $res->content.

Perl issues while sending emojis over socket

My Perl script sends push notifications to an Apple APNS server. It works except when I try to send emojis (special characters).
My code
use DBI;
use JSON;
use Net::APNS::Persistent;
use Data::Dumper;
use Encode;
my $cfg;
my $apns;
...;
sub connect {
my ($sandbox, $cert, $key, $pass) = $cfg->getAPNSServer();
$apns = Net::APNS::Persistent->new({
sandbox => $sandbox,
cert => $cert,
key => $key,
}) or die("[-] Unable to connect to APNS server");
}
sub push {
my $msg = $_[1];
Logger::log(5, "[APNS Client] Got message ".Dumper($msg));
#Encode::_utf8_off($msg);
utf8::encode($msg);
my $pack = decode_json($msg);
my ($token, $payload) = #{$pack};
Logger::log(5, "Sending push with token: $token and Data: \n".Dumper($payload));
$apns->queue_notification(
$token,
$payload
);
$apns->send_queue;
}
So in the push subroutine I pass JSON data with the format given below. My problem is with the emoji character \x{2460}. You can see I added this line
utf8::encode($msg);
Before decoding the data. If I remove this line I get an error while decoding the JSON data
Wide character in subroutine entry at .....
With the above line added I can decode my JSON data. However when I try to write to the socket in the next line ($apns->send_queue) gives
Cannot decode string with wide characters at /usr/lib/perl/5.10/Encode.pm line 176
How do I solve this?
Message format (JSON)
["token",
{
"aps":{
"alert":"Alert: \x{2460}",
"content-available":1,
"badge":2,
"sound":"default.aiff"
},
"d":"Meta"
}
]
Dumper Output
[-] [ 2015-08-25T20:03:15 ] [APNS Client] Got message $VAR1 = "[\"19c360f37681035730a26cckjgkjgkj58b2d20326986f4265ee802c103f51\",{\"aps\":{\"alert\":\"Alert: \x{24bc}\",\"content-available\":1,\"badge\":2,\"sound\":\"default.aiff\"},\"d\":\"Meta\"}]";
[-] [ 2015-08-25T20:03:15 ] Sending push with token: 119c360f37681035730a26cckjgkjgkj58b2d20326986f4265ee802c103f51 and Data:
$VAR1 = {
'aps' => {
'alert' => "Alert: \x{24bc}",
'content-available' => 1,
'badge' => 2,
'sound' => 'default.aiff'
},
'd' => 'Meta'
};
[x] [ 2015-08-25T20:03:15 ] [APNS Client] Error writing to socket. Reconnecting : Cannot decode string with wide characters at /usr/lib/perl/5.10/Encode.pm line 176.
First of all, decode_json expects JSON encoded using UTF-8, so if you're starting with "decoded" JSON, it is proper to encode it as you did.
utf8::encode( my $json_utf8 = $json_uni );
my $data = decode_json($json_utf8);
However, it would have been simpler to use from_json.
my $data = from_json($json_uni);
Now on to your question. Whoever wrote Net::APNS::Persistent messed up big time. I looked at the source code, and they expect the alert message to be encoded using UTF-8. Adding the following will make your structure conform with the module's wonky expectation:
utf8::encode(
ref($payload->{aps}{alert}) eq 'HASH'
? $payload->{aps}{alert}{body}
: $payload->{aps}{alert}
);
It wouldn't surprise me if you ran into other issues. Notably, the modules uses the bytes module, a sure sign that something is being done incorrectly.
You probably have to UTF-8 encode the alert in $payload before sending it. You can also use from_json instead of decode_json to avoid the first encoding step:
sub push {
my $msg = $_[1];
Logger::log(5, "[APNS Client] Got message ".Dumper($msg));
my $pack = from_json($msg);
my ($token, $payload) = #{$pack};
Logger::log(5, "Sending push with token: $token and Data: \n".Dumper($payload));
# UTF-8 encode before sending.
utf8::encode($payload->{aps}{alert});
$apns->queue_notification(
$token,
$payload
);
$apns->send_queue;
}

How to check whether hash key contain JSON in perl?

I am sending a request to the endpoint url ,from there i am getting the response in case of success in form of JSON,but if it fails it return certain text .
Sending request:
$data->{response} = $self->{_http}->send($myData);
So before doing this:
$resp = from_json($data->{response});
i want to check whether the reponse is in json format or not .How we can handle this in Perl kindly help in this
You can catch exception thrown by from_json(),
my $resp;
my $ok = eval { $resp = from_json("{}"); 1 };
$ok or die "Not valid json";
or simpler,
my $resp = eval { from_json("rrr") };
$resp // die "Not valid json";
Use JSON or JSON::XS to decode the JSON into a Perl structure.
Simple example:
use strict;
use warnings;
use JSON::XS;
my $json = '[{"Year":"2012","Quarter":"Q3","DataType":"Other 3","Environment":"STEVE","Amount":125},{"Year":"2012","Quarter":"Q4","DataType":"Other 2","Environment":"MIKE","Amount":500}]';
my $arrayref = decode_json $json;
foreach my $item( #$arrayref ) {
# fields are in $item->{Year}, $item->{Quarter}, etc.
}
You could use a try/catch block using Try::Tiny
use Try::Tiny;
try {
$resp = from_json($data->{response});
} catch {
# Do something if it does not parse
warn 'Could not parse json'
};

how to decode json in perl if value has \n or more than one line

how to decode the json file if a value has more than one line
a.json file:
{
"sv1" : {
"output" : "Hostname: abcd
asdkfasfjsl",
"exp_result" : "xyz"
}
}
when I try to read the above json file, I am hitting with an error "invalid character encountered while parsing JSON string, at character offset 50 (before "\n ...")"
code to read the above json file:
#!/volume/perl/bin/perl -w
use strict;
use warnings;
use JSON;
local $/;
open(AA,"<a.json") or die "can't open json file : $!\n";
my $json = <AA>;
my $data = decode_json($json);
print "reading output $data->{'sv1'}->{'output'}\n";
print "reading output $data->{'sv1'}->{'exp_result'}\n";
close AA;
Besides from whether the JSON is valid or not (see comments on question), you're reading only the first line from the file.
my $json = <AA>;
This is a scalar variable and receives only one line.
Use an array to get all lines:
my #json = <AA>;
my $json = join "\n", #json;
or even better: use File::Slurp::read_file to get the whole content of the file with one simple command.
use File::Slurp qw/read_file/;
my $json = read_file( "a.json" );