A http connection requires a HTTP POST request with a custom header object Authentication-API-Key
With CURL it's automatically converted to [HTTP_AUTHENTICATION_API_KEY] => 12345
Cannot figure out why
A simplle extract from a php class for testing is
Please help me out, how to get a $_SERVER result with [Authentication-API-Key] => 123456
<?php
$contentType = 'text/xml';
$method = 'POST';
$auth = '';
$header1 = 'Authentication-API-Key: 12345';
$charset= 'ISO-8859-1';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost/test/returnurl.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, Array('Content-type: ' .
$contentType . '; charset=' . $charset,
$header1));
curl_exec($ch);
?>
<?php
//http://localhost/test/returnurl.php
Print_r($_SERVER,true)
?>
output:
Array
(
[HTTP_HOST] => localhost
[HTTP_ACCEPT] => */*
[CONTENT_TYPE] => text/xml; charset=ISO-8859-1
[HTTP_AUTHENTICATION_API_KEY] => 12345
...
)
If I run your code, I get the message that $header2 is undefined, so I think you need to fix that.
If I remove $header2, this is the output:
GET /test/returnurl.php HTTP/1.1
Host: localhost
Accept: */*
Content-type: text/xml; charset=ISO-8859-1
Authentication-API-Key: 12345
So that seems to be okay. What is your output? Note that currently the request is send using GET, not POST.
EDIT: I created the script /test/returnurl.php that simply dumps the $_SERVER array, now I see what you mean. The fact that it ends up like that on the receiving end does not mean that you haven't set the header correctly, so the service that you're using should be receiving it as intended.
That's how _SERVER works; it does not give you the HTTP header keys verbatim.
It is not CURL doing this. Examine the actual HTTP request and you'll see that your header is fine.
Another example is $_SERVER['CONTENT_TYPE'], which gives you the value of the Content-Type HTTP header.
There is no problem here.
A script I am using passes an array like array("Content-type: image/png").
Perhaps by putting it in an array you prevent it from breaking into an array at the :
I am new to cURL so I haven't even been able to test this theory yet..
Related
I am trying to send the following cURL request in PHP:
$ curl -H 'Content-Type: application/json' -d '{"username":"a", "password":"b","msisdn":"447000000001","webhook":"http://example.com/"}' https://ms.4url.eu/lookup
Which should return:
198 bytes text/html; charset=UTF-8
{
"id": "ea26d0b2-b839-46b9-9138-50cc791bab47",
"msisdn": "447825001771",
"status": "Success",
"networkCode": "23471",
"countryName": "UK",
"countryCode": "GBR",
"network": "O2",
"networkType": "GSM",
"ported": "No"
}
I have tried to implement the code to send a request using cURL like so:
<?php
$data = array('{"username":"a", "password":"b", "msisdn":"447123121234", "webhook":"http://1f89e4a8.ngrok.io"}');
$data_string = json_encode($data);
$ch = curl_init('http://ms.4url.eu/lookup');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
?>
Using this method nothing seems to be happening I cannot see the JSON data being sent to ms.4url.eu/lookup, and when I try to echo $result I get no data echoed out?
Any help is much appreciated.
A Successful curl request is showing:
POST /testDir/getPost.php HTTP/1.1
host: 1f89e4a8.ngrok.io
accept: application/json
content-type: application/json
content-length: 198
Connection: close
X-Forwarded-For: 5.44.233.221
{"id":"ea26d0b2-b839-46b9-9138-50cc791bab47","msisdn":"447123121234","status":"Success","networkCode":"23471","countryName":"UK","countryCode":"GBR","network":"O2","networkType":"GSM","ported":"No"}
The post request from my PHP code is showing:
GET /testDir/curlPost.php HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Accept-Language: en-GB
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393
Accept-Encoding: gzip, deflate
Host: 1f89e4a8.ngrok.io
X-Forwarded-For: 92.11.143.199
Overall I would like to send the curl request from sendRequest.php and receive the Post for the webhook to getPost.php possibly using:
$entityBody = file_get_contents('php://input');
if ($entityBody != null){
echo $entityBody;
}
at the Minute I am using the getPost.php to send the HTTP 200 OK so ms.4url.eu stops sending requests 302 Found.
I think it is how you are building the json string...
You start by defining $data as an array of strings, and then json_encode it. But it is already in json format anyway (from a quick eyeball check).
The json_encode (and _decode) are meant to work with an associative array for your data.
Or just send the data string you are building, just check that it is in correct json format first.
<?php
// build an associative array
$data["username"]="a";
$data["password"]="b";
$data["msisdn"]="447123121234";
$data["webhook"]="http://1f89e4a8.ngrok.io";
// turn it into json formatted string
$json_data=json_encode($data);
print_r($data);
print($json_data);
?>
This gives you something like
Array
(
[username] => a
[password] => b
[msisdn] => 447123121234
[webhook] => http://1f89e4a8.ngrok.io
)
{"username":"a","password":"b","msisdn":"447123121234","webhook":"http:\/\/1f89e4a8.ngrok.io"}
Try to get like raw post data like below
<?php
$fp = fopen('php://input', 'r');
$rawData = stream_get_contents($fp);
echo "<pre>";
print_r($rawData);
echo "</pre>";
If you send only the json string via curl you have to use, on the destination page, php://input to retrieve the data, because there is not key => value and the variables $_POST and $_REQUEST don't intersect the request.
And, of course, check wich data are you sending in post. It seems incorrect to json_encode an array with an element "string"..
If you want to retrieve the request from the $_POST or $_REQUEST variable it's better if you put your json data into a key using the http_build_query function like following:
$data_string = json_encode($data);
$ch = curl_init('http://ms.4url.eu/lookup');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array('data' => $data_string)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
In PHP, I'm trying to retrieve the url for a specific page in DocuSign that constantly refreshes. The POST to retrieve this url is in the form:
POST http://demo.docusign.net/restapi/{apiVersion}/accounts/{accountId}/envelopes/{envelopeId}/views/recipient
This should return a json file in the form:
{
"url": "example.example.com"
}
However, I am extremely new to using PHP and POST methods and don't believe I'm doing this correctly. The API explorer for this method in particular is here. I am using cURL methods to make this request. Here is my code ($recipient,$account_id,$access_token are found accurately within another file):
$url = "http://demo.docusign.net/restapi/v2/accounts/$account_id
/envelopes/$envelope_id/views/recipient";
$body = array("returnUrl" => "http://www.docusign.com/devcenter",
"authenticationMethod" => "None",
"email" => "$recipient",
"userName" => "$recipient");
$body_string = json_encode($body);
$header = array(
'Accept: application/json',
'Content-Type: application/json',
'Content-Length: '.strlen($body_string),
);
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $body_string);
$json_response = curl_exec($curl);
$response = json_decode($json_response, true);
var_dump($response);
I am able to get the correct return on the API explorer, but not when making the request with PHP. I believe this is due to the fact that I am not incorporating the $header or $body correctly, but at this point I am just not sure.
ADDED: This is the raw output for the request when correctly running the method on the API Explorer:
Accept: application/json
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,fa;q=0.6,sv;q=0.4
Cache-Control: no-cache
Origin: https://apiexplorer.docusign.com
Referer: https://apiexplorer.docusign.com/
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Authorization: Bearer fGehcK7fkRvFguyu/7NGh01UUFs=
Content-Length:
Content-Type: application/json
This is the JSON request being formed in my code:
{
"returnUrl":"http:\/\/www.docusign.com\/devcenter",
"authenticationMethod":"Password",
"email":"example#example.com",
"userName":"example#example.com",
"clientUserId":"4c6228f4-fcfe-47f9-bee1-c9d5e6ab6a41",
"userId":"example#example.com"
}
You are not hitting a valid DocuSign URL in your cURL code. Right now you are sending requests to:
http://demo.docusign.net/apiVersion/v2/accounts/{accountId}/envelopes/{envelopeId}/views/recipient
Instead of "apiVersion" it should be "restApi" like this:
http://demo.docusign.net/restapi/v2/accounts/{accountId}/envelopes/{envelopeId}/views/recipient
We can't send post fields, because we want to send JSON, not pretend to be a form (the merits of an API which accepts POST requests with data in form-format is an interesting debate). Instead, we create the correct JSON data, set that as the body of the POST request, and also set the headers correctly so that the server that receives this request will understand what we sent:
$data = array("name" => "Hagrid", "age" => "36");
$data_string = json_encode($data);
$ch = curl_init('http://api.local/rest/users');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
All these settings are pretty well explained on the curl_setopt() page, but basically the idea is to set the request to be a POST request, set the json-encoded data to be the body, and then set the correct headers to describe that post body. The CURLOPT_RETURNTRANSFER is purely so that the response from the remote server gets placed in $result rather than echoed. If you're sending JSON data with PHP, I hope this might help!
I know this question was asked more than 3 years ago, but this may help someone who finds this question because they are having the same problem. I do not see a cURL option that will decode the response in your code. I have found that I need to use the cURL option CURLOPT_ENCODING like this: curl_setopt($ch,CURLOPT_ENCODING,""); According to the PHP manual online, it says, 'CURLOPT_ENCODING - The contents of the "Accept-Encoding: " header. This enables decoding of the response. Supported encodings are "identity", "deflate", and "gzip". If an empty string, "", is set, a header containing all supported encoding types is sent.' You can find this option at https://www.php.net/manual/en/function.curl-setopt.php. I hope this helps save someone from having a headache.
I need to send an XML string via HTTP POST to another server using the settings below...
POST /xmlreceive.asmx/CaseApplicationZipped HTTP/1.1
Host: www.dummyurl.co.uk
Content-Type: application/x-www-form-urlencoded
Content-Length: length
XMLApplication=XMLstring&byArray=base64string
I'm guessing I need to set this up via cURL or maybe fsockopen.
I've tried the following but not having any luck at getting it to work.
$url = "http://www.dummyurl.co.uk/XMLReceive.asmx/CaseApplicationZipped";
$headers = array(
"Content-Type: application/x-www-form-urlencoded"//,
);
$post = http_build_query(array('XMLApplication' => $XML, 'byArray' => $base64));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo "response: ".$response;
The remote server gives the following response...
"Object reference not set to an instance of an object."
Not enough rep yet to comment, so I'll post this as an answer.
PHP's cURL automatically send the Host (from $url) and the Content-Length headers, so you don't need to specify those manually.
A handy function exists for building the $post string: http_build_query. It'll handle properly encoding your POST body. It would look something like
$post = http_build_query(array('XMLApplication' => $XML, 'byArray' => $base64));
If you want to log out the headers you received, check the curl_getopt function.
As for the error you received, it seems like you're passing the remote site things it doesn't expect. I can't speak for what you're passing or what the site's expecting, but Input string was not in a correct format seems to imply that your $XML is not formatted correctly, or is being passed as an incorrect parameter.
My goal is to send a POST request to a server and get the proper response.
Note: Angled brackets represent placeholders.
In Terminal, using the following code will provide me the desired response.
curl -u <user>:<pass> -H 'Content-Type: application/xml' -X POST https://<rest of url>
My current PHP looks something like this:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uri); //$uri is the same that I use in terminal
curl_setopt($ch, CURLOPT_USERPWD,
sprintf('%s:%s', $user, $pass)); //same as terminal user & pass
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$headers = array(
'Content-Type: application/xml', //expect an xml response
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$curl_result = curl_exec($ch);
Using this PHP, I get a 400 Bad Request error.
The verbose information:
> POST <same url> HTTP/1.1
Authorization: Basic YWRtaW5Ac3Bhcms0NTEuY29tOnNwYXJrc29tZXRoaW5n
Host: <correct host>
Accept: */*
Content-Type: application/xml
Content-Length: -1
Expect: 100-continue
* HTTP 1.0, assume close after body
< HTTP/1.0 400 Bad request
< Cache-Control: no-cache
< Connection: close
< Content-Type: text/html
Why am I getting a 400 Bad Request error when I use PHP, but not when I use command line? How can I fix this issue so that I get my desired response using PHP?
curl_setopt($ch, CURLOPT_POSTFIELDS, array());
After adding this line, I resolved my problem. In a way, this solution makes sense; but I don't understand why CURLOPT_POSTFIELDS is required. In the PHP documentation, this part should be included under CURLOPT_POST, unless this just accidentally works.
I don't know if this can help you, but for me the Expect: 100-continue looks strange. Take a look at this comment:
http://php.net/manual/en/function.curl-setopt.php#82418
So maybe you can fix it like in the example:
<?php
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
?>
I want to send a request to a web service via an API as shown below, i have to pass
a custom http header(Hash), i'm using CURL, my code seems to work but I'm not getting
the rigth response, I'm told it has to do with the hash value, though the value has
been seen to be correct, is there anything wrong with the way I'm passing it or with
the code itself.
<?php
$ttime=time();
$hash="123"."$ttime"."dfryhmn";
$hash=hash("sha512","$hash");
$curl = curl_init();
curl_setopt($curl,CURLOPT_HTTPHEADER,array('Hash:$hash'));
curl_setopt ($curl, CURLOPT_URL, 'http://web-service-api.com/getresult.xml?clientid=456&time=$ttime');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$xml = curl_exec ($curl);
if ($xml === false) {
die('Error fetching data: ' . curl_error($curl));
}
curl_close ($xml);
echo htmlspecialchars("$xml", ENT_QUOTES);
?>
If you need to get and set custom http headers in php, the following short tutorial is really useful:
Sending The Request Header
$uri = 'http://localhost/http.php';
$ch = curl_init($uri);
curl_setopt_array($ch, array(
CURLOPT_HTTPHEADER => array('X-User: admin', 'X-Authorization: 123456'),
CURLOPT_RETURNTRANSFER =>true,
CURLOPT_VERBOSE => 1
));
$out = curl_exec($ch);
curl_close($ch);
// echo response output
echo $out;
Reading the custom header
print_r(apache_request_headers());
you should see
Array
(
[Host] => localhost
[Accept] => */*
[X-User] => admin
[X-Authorization] => 123456
[Content-Length] => 9
[Content-Type] => application/x-www-form-urlencoded
)
Custom Headers with PHP CGI
in .htaccess
RewriteEngine On
RewriteRule .? - [E=User:%{HTTP:X-User}, E=Authorization:%{HTTP:X-Authorization}]
Reading the custom headers from $_SERVER
echo $_SERVER['User'];
echo $_SERVER['Authorization'];
Resources
http://www.omaroid.com/php-get-and-set-custom-http-headers/
How can I get PHP to display the headers it received from a browser?
'Hash:$hash' should be either "Hash: $hash" (double quotes) or 'Hash: '.$hash
The same goes for your URL passed in CURLOPT_URL