I am attempting to code an API call to a online testing company. They have provided a sample call in PHP and cURL that I need to implement in ColdFusion 11 using <CFHTTP>
. So far my attempt has failed. The only response I get from their server / API is:
Statuscode = "Connection Failure. Status code unavailable. "
and
ErrorDetail = "I/O Exception: Remote host closed connection during handshake".
If it were working I would get a JSON string detailing computed scores. Note that in the code below I've changed a few values for security reasons, other than that it's the original code. Any suggestions or comments would be much appreciated, thanks.
Here is the ColdFusion/cfhttp code:
<cfoutput>
<cfset sdata = [
{
"customerid" = "ACompany",
"studentid" = "test",
"form" = "X",
"age" = "18.10",
"norms" = "grade",
"grade" = "2"
},
{
"scores" = [
{"subtest"="math","score"="34"},
{"score"="23","subtest"="lang"},
{"score"="402","subtest"="rcomp"}
]
}
]>
<!--- create JSON string for request --->
<cfset jsdata = serializeJSON(sdata)>
<!--- make the call --->
<cfhttp method="Get" url="https://www.APIwebsite.php" timeout="10" result="varx">
<cfhttpparam type="header" name="Content-Type" value = "application/json; charset=utf-8"/>
<cfhttpparam type="body" value = "#jsdata#"/>
<cfhttpparam type="header" name="Authorization" value="AuthCode"/>
<cfhttpparam type="header" name="Content-Length" value = "#len(jsdata)#"/>
</cfhttp>
<!--- show results --->
cfhttp return status code: [#varx.statusCode#]<br>
cfhttp return fileContent: [#varx.fileContent#]<br>
</cfoutput>
Here is the PHP/cURL code:
<?php
$data = array
(
"customerid" => "ACompany",
"studentid" => "test",
"scoringtype" => 2,
"form" => "X",
"age" => "18.10",
"norms" => 'grade',
"grade" => '2',
"scores" => array(
array("subtest" => "math", "score" => "34"),
array("subtest" => "lang", "score" => "23"),
array("subtest" => "rcomp", "score" => "402")
));
$url = 'https://www.APIwebsite.php';
$json_string = json_encode($data);
$headers = array (
"Content-Type: application/json; charset=utf-8",
"Content-Length: " .strlen($json_string),
"Authorization: AuthCode"
);
$channel = curl_init($url);
curl_setopt($channel, CURLOPT_RETURNTRANSFER, true);
curl_setopt($channel, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($channel, CURLOPT_HTTPHEADER, $headers);
curl_setopt($channel, CURLOPT_POSTFIELDS, $json_string);
curl_setopt($channel, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($channel, CURLOPT_CONNECTTIMEOUT, 10);
$response = curl_exec($channel); // execute the request
$statusCode = curl_getInfo($channel, CURLINFO_HTTP_CODE);
$error = curl_error($channel);
curl_close($channel);
http_response_code($statusCode);
if ( $statusCode != 200 ){
echo "Status code: {$statusCode} \n".$error;
} else {
$data = json_decode($response,true);
foreach ($data as $key => $value) {
echo nl2br($key . ': ' . $value . "\n");
}
}
?>
First make sure the url you provided is correct (I know it's for the example but .php is not a valid domain name extension), and that the SSL certificate is valid
If both are correct, you should change the request method to POST
for sending json data through the body
According to the http semantics
A client should not generate a body in a GET request. A payload received in a GET request has no defined semantics, cannot alter the meaning or target of the request, and might lead some implementations to reject the request and close the connection because of its potential as a request smuggling attack
There is a charset parameter in cfhttp so you don't need to send it in the header
Here is a code that should work
<cfset sdata = [
{
"customerid" = "ACompany",
"studentid" = "test",
"form" = "X",
"age" = "18.10",
"scoringtype" = 2,
"norms" = "grade",
"grade" = "2"
},
{
"scores" = [
{"subtest"="math","score"="34"},
{"score"="23","subtest"="lang"},
{"score"="402","subtest"="rcomp"}
]
}
]>
<!--- create JSON string for request --->
<cfset jsdata = serializeJSON(sdata)>
<!--- make the call --->
<cfhttp method="post" charset="utf-8" url="https://api.website.com/" timeout="10" result="varx">
<cfhttpparam type="header" name="Content-Type" value="application/json"/>
<cfhttpparam type="header" name="Authorization" value="AuthCode"/>
<cfhttpparam type="header" name="Content-Length" value="#len(jsdata)#"/>
<cfhttpparam type="body" value="#jsdata#"/>
</cfhttp>
<!--- show results --->
<cfoutput>
cfhttp return status code: [#varx.statusCode#]<br>
cfhttp return fileContent: [#varx.fileContent#]<br>
</cfoutput>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With