I m trying to make a GET request with headers using cURL PHP. I am getting an empty response form the server. I would like to know if I have made this request correctly using cURL PHP.
// curl GET request with headers
$url = $sendMailURL;
$requestHeaders = array(
$hConLength_.':'.$conLengthValue,
$hConType_.':'.$conTypeValue,
$hHost_.':'.$conHostValue,
$hDate_.':'.$conAmzDateValue);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
if(curl_error($ch)){
echo 'curl error: '.curl_error($ch);
}else{
print_r($output);
}
print_r($requestHeaders):
Array ( [0] => Content-Length:207
[1] => Content-Type:application/x-www-form-urlencoded
[2] => Host:email.eu-west-1.amazonaws.com
[3] => X-amz-date:20180115T224433Z )
I'm positive that you have found your answer, but in case there are others who will probably want to figure out how to check the headers or want to go down the rabbit hole trying to figure out how SignatureV4 works.
You need to set curl_option CURLINFO_HEADER_OUT
I used following to set all the options in one go, but I don't see why you can't set them one by one.
$conf = [
\CURLOPT_CUSTOMREQUEST => $method, // method
\CURLOPT_URL => $url, // url
\CURLOPT_HTTPHEADER => $requestHeaders, // headers
\CURLOPT_RETURNTRANSFER => true,
\CURLOPT_HEADER => true,
\CURLOPT_CONNECTTIMEOUT => $timeout, // set to anything that fits
\CURLOPT_PROTOCOLS => CURLPROTO_HTTPS, // whatever is your protocol
\CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, // normally 1.1
\CURLINFO_HEADER_OUT => 1, // this will cause request headers to show up
];
curl_setopt_array($this->curl, $conf);
After running your request and before closing curl you can check for your headers and response headers all together.
$result = curl_exec($this->curl);
$info = curl_getinfo($this->curl, CURLINFO_HEADER_OUT); // run after exec before close
var_dump($info);
curl_close($this->curl);
you don't have to specify CURLINFO_HEADER_OUT when calling curl_getinfo but it will show a lot more info which makes it a little harder to find what you are looking for.
Since you mentioned in comments that you are trying to make SignatureV4 for AWS and I had the same issue, a few notes:
Although http headers are not case sensitive, when calculating hash they should be in lowercase and also specified in authorization token in lower case too. to make it easier, I just included headers in both request and hash as lowercase
You don't need to hash all the headers, since you will need to mention which headers are included in hash, in the authorization token.
Someone at AWS thought it is cool to sort querystring items alphabetically before calculating hash, so if you are sending querystring, make sure tokens are sorted before hashing it e.g.
Engine=standard&LanguageCode=en-US // will work
LanguageCode=en-US&Engine=standard // will not work
The only two headers that need to be in hash are x-amz-date and host. (at least that was the case for Polly) and they need to look like this
host:service.region.amazonaws.com
x-amz-date:20210920T180242Z
authorization:AWS4-HMAC-SHA256 Credential=xxxxxxxxxxxxxxxxxxxx/20210920/region/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Related
Everything I look at online is showing how to use OAuth & Curl to make a POST request, but I want to make a get request to the Mailchimp API and I'm not getting any response it seems. I've already managed to go through the authentication and get the user's token & api URL. Now I'm just trying to pull in their lists. Here's the CURL code I've got currently:
$headers = array(
"Content-type: application/json",
"Authorization: OAuth ".$user['mct']
);
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_URL => "https://".$user['dc'].".api.mailchimp.com/3.0/lists",
CURLOPT_USERAGENT => "oauth2-draft-v10",
CURLOPT_HTTPHEADER => $headers,
CURLOPT_ENCODING => ''
));
$tresp = curl_exec($curl);
$lists = json_decode($tresp,true);
curl_close($curl);
Assuming $user['mct'] and $user['dc'] contain the proper values, any idea what I'm doing wrong here?
In case anyone ends up googling and finding this, my problem was that the user information I was getting from wordpress' get_results() function was an object and not an array. Took me forever to realize because for some reason this part of my plugin is preventing me from using print_r().
Now that it's actually going to the Mailchimp API I'm able to get and debug whatever error they're sending back.
We are having a RESTful API and RESTful clients, both in PHP. Client connecting to server via cURL http requests.
$handler = curl_init (self::API_ENDPOINT_URI . $resource);
$options =[
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_TIMEOUT => 6000,
];
curl_setopt_array ($handler, $options);
$result = curl_exec ($handler);
curl_close ($handler);
Then in model somewhere we call it:
$request = json_decode($this->_doRequest('/client/some_id'));
There is a JSON response and we parse it. Everything is ok till... Till some users start creating multiple requests and PHP hangs. For example we have a client page which is making ~5 requests to API server. When user opens a 10 tabs in browser with 10 different clients it's ~50 requests which are going one by one. That means that before first tab won't finish his work other tabs won't start their work.
Is it any way to fix this issue in simple way?
We would like to use cURL multi handler for this but not sure how to get responses immediately.
Thanks.
Currently I'm writing a PHP script that is supposed to check if a URL is current (returns a HTTP 200 code or redirects to such an URL).
Since several of the URLs that are to be tested return a file, I'd like to avoid using a normal GET request, in order not having to actually download a file.
I would normally use the HTTP HEAD method, however tests show, that many servers don't recognize it and return a different HTTP code than the corresponding GET request.
My idea was know to make a GET request and use CURLOPT_HEADERFUNCTION to define a callback function which checks the HTTP code in the first line of the header and then immediately terminate the request by having it return 0 (instead of the length of the header) if it's not a redirect code.
My question is: Is it ok, to terminate a HTTP request like that? Or will it have any negative effects on the server? Will this actually avoid the unnecessary download?
Example code (untested):
$url = "http://www.example.com/";
$ch = curl_init($url);
curl_setopt_array($ch, array(
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HEADER => true,
CURLINFO_HEADER_OUT => true,
CURLOPT_HTTPGET => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADERFUNCTION => 'requestHeaderCallback',
));
$curlResult = curl_exec($ch);
curl_close($ch);
function requestHeaderCallback($ch, $header) {
$matches = array();
if (preg_match("/^HTTP/\d.\d (\d{3}) /")) {
if ($matches[1] < 300 || $matches[1] >= 400) {
return 0;
}
}
return strlen($header);
}
Yes it is fine and yes it will stop the transfer right there.
It will also cause the connection to get disconnected, which only is a concern if you intend to do many requests to the same host as then keeping the connection alive could be a performance benefit.
I am going to send a Log in request to the server by using CURL in my PHP code. This request is POST and I wrote following code,
if (strpos($header, 'POST') !== false){
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HEADER => 1,
CURLOPT_URL => $url,
CURLOPT_USERAGENT => 'proxy',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $postParameters,
CURLOPT_COOKIE => $postCoockies
));
$respond = curl_exec($curl);
curl_close($curl); }
and if I want to say what my variables are here:
$url is the exact String after POST and before HTTP/1.1.
when I want to send the GET request also, I am using this part as my urs which would be contained all parameters in my query String.
$postParameters is the exact String that exist in POST body.
(That's a String, not an associative array)
$postCoockies in the exact String after Cookie: in my request header.
(again, that's not an associative array)
My problem is:
When I send this request, server sends me back a response to only the URL I am passing. Which is to load the login page again! it seems that the server is not receiving my parameters!
Also, when I used GET request for login (I have access to the source code of website), and sent the whole URL and parameters inside the $url, the same thing happened.
Am I wrong somewhere in sending my request?
Should I consider something else here?
So I've been finding a lot of posts here and other places on the interwebs regarding PHP, cURL and SSL. I've got a problem that I'm not seeing around.
Obviously, if I set SSL_VERIFYPEER/HOST to blindly accept I can get this to work, but I would like to use my cert to verify the connection.
So here is some code:
$options = array(
CURLOPT_URL => $oAuthResult['signed_url'],
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HEADER => 0,
CURLOPT_SSL_VERIFYPEER => TRUE,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_CAINFO => getcwd() . '\application\third_party\certs\rootCerr.crt'
);
curl_setopt_array($ch, $options);
try {
$result = curl_exec($ch);
$errCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) != 200) {
throw new Exception('<strong>Error trying to ExecuteWebRequest, returned: '.$errCode .'<br>URL:'.$url . '<br>POST data (if any):</strong><br>');
}
curl_close($ch);
} catch (Exception $e) {
//print the error stuff
}
The error code that is returned is 0...which means that everything is A-OK...but since nothing comes back to the screen...I'm pretty sure it's not working.
Anyone?
The $errCode you extract is the HTTP code which is 200-299 when OK. Getting 0 means it was never set due to a problem or similar.
You should rather use curl_errno() after curl_exec() to figure out if things went fine or not. (You can't check the curl_exec() return code for errors as easily, as you have CURLOPT_RETURNTRANSFER enabled which makes that function instead return the contents of the transfer it is set to get. Of course, getting no contents at all returned should also be a good indicator that something failed.)
I've implemented LibCurl Certs by using the CURLOPT_CAINFO as you have indicated...
However, by providing the file name itself wasn't good enough... It had crashed on me too.
For me, the file was referenced by relative path... Additionally, I had to make sure the cert was in Base64 format too. Then everything went through without a hitch..