I'm trying to retrieve the location URL of an image after a redirect, but I can't seem to get it to work. I've never used cURL before, but from the research I've done it looks like I need it to get an image from Facebook. Here's my code so far:
function getImage($url) {
$ch = curl_init();
// Only calling the head
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true); // header will be at output
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'
$content = curl_exec($ch);
curl_close($ch);
return $content;
}
$image = explode("Location: ", getImage("http://graph.facebook.com/553451657/picture?type=large"));
print_r($image);
But my response is:
HTTP/1.1 302 Found Access-Control-Allow-Origin: * Cache-Control: private, no-cache, no-store, must-revalidate Content-Type: image/jpeg Expires: Sat, 01 Jan 2000 00:00:00 GMT Location: http://profile.ak.fbcdn.net/hprofile-ak-snc4/161877_553451657_798840908_n.jpg Pragma: no-cache X-FB-Rev: 590433 X-FB-Debug: WH1uJvIjUqiLT8ezVPdude8VKYnXjAHRlFaP8gqF9fI= Date: Fri, 13 Jul 2012 17:56:09 GMT Connection: keep-alive Content-Length: 0 Array ( [0] => 1 )
How do I JUST get the Location part ("http://profile.ak.fbcdn.net/hprofile-ak-snc4/161877_553451657_798840908_n.jpg")?
You can do a function on the headers:
$headers = [];
curl_setopt($curl, CURLOPT_HEADERFUNCTION, function ($ch, $header) use (&$headers) {
$matches = array();
if ( preg_match('/^([^:]+)\s*:\s*([^\x0D\x0A]*)\x0D?\x0A?$/', $header, $matches) )
{
$headers[$matches[1]][] = $matches[2];
}
return strlen($header);
});
(seen here)
Then you get it stored in $headers["Location"][0].
I am also, like you, trying to get the fb page image this way, it seems no PHP SDK, App priviledges or access_token is needed for that, but there might be some limitations (anybody knows?)
How do I JUST get the Location part
Getting that Location header is not you’re primary goal, right? You want to get the image from the address that’s being redirected to, correct?
So just set the option CURLOPT_FOLLOWLOCATION, and cURL will follow that redirect automatically and fetch the real image for you.
Related
I am trying to get the response/status code including the header for multiple URL's. My first try I was successful in getting the status code i.e. 200 or 301 or 302. But I want the output to be like HTTP/1.1 200 OK or HTTP/1.1 302 Found etc.
Below is my code in which I get just the response code i.e. 200 or 301.
<?php
$line = "https://www.pnc.com";
$ch = curl_init($line);
curl_setopt($ch, CURLOPT_URL, $line);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER,true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_TIMEOUT,10);
$out = curl_exec($ch);
$ret = true;
if ($out !== false) {
$statuscode = curl_getinfo($ch,CURLINFO_HTTP_CODE);
echo "Response Code:" .$statuscode. "\r";
}
curl_close($ch);
?>
Actual Ouput
Response Code:HTTP/1.1 200 OK
ETag: "846caf551746b12e876c0bad5a50830d:1475788950"
Last-Modified: Thu, 06 Oct 2016 21:22:30 GMT
Accept-Ranges: bytes
Content-Length: 17609
Content-Type: text/html
Expires: Fri, 21 Sep 2018 15:35:01 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Fri, 21 Sep 2018 15:35:01 GMT
Connection: keep-alive
Expected Output
HTTP/1.1 200 OK.
Can someone help me with this?
This can be done using strtok
Example:
$statuscode = strtok( $statuscode, "\n" );
-or-
Using explode is pretty standard:
$statuscode = explode( "\n", $statuscode )[0];
There are definitely other methods as well
However probably the cleanest way might be to use cURL itself:
$response = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
I am trying to get the access token using curl.
$tokenurl = "https://graph.facebook.com/oauth/access_token?client_id=11111111111111&redirect_uri="http://www.example.com/?callback"&client_secret=11111111111111111111111111111&code=" . $_GET['code'];
$_h = curl_init();
curl_setopt($_h, CURLOPT_HEADER, 1);
curl_setopt($_h, CURLOPT_RETURNTRANSFER, true);
curl_setopt($_h, CURLOPT_HTTPGET, 1);
curl_setopt($_h, CURLOPT_URL, $tokenurl );
curl_setopt($_h, CURLOPT_DNS_USE_GLOBAL_CACHE, false );
curl_setopt($_h, CURLOPT_DNS_CACHE_TIMEOUT, 2 );
//var_dump(curl_exec($_h));
$result = curl_exec($_h);
$json = json_decode($result, true);
echo $json['access_token'];
curl_close($_h);
return $result;
var_dump is showing valid data, but I can't fetch it using json_decode(). echo $json['access_token']; shows nothing. Am I doing something wrong? Any suggestion would be helpful.
var_dump is showing this data:
string(733) "HTTP/1.1 200 OK Access-Control-Allow-Origin: * Pragma: no-cache Cache-Control: private, no-cache, no-store, must-revalidate x-fb-rev: 3044559 Content-Type: application/json; charset=UTF-8 x-fb-trace-id: E9niQhqkk34 facebook-api-version: v2.3 Expires: Sat, 01 Jan 2000 00:00:00 GMT Vary: Accept-Encoding X-FB-Debug: 8y64Y0AJvl8YiFFk+kQj8pVvJHBQJLBPC854l5J7e41ypLTYesLTYvfMjsc+FjH9mpZw4Fi7ZITONGM8sazlCw== Date: Thu, 25 May 2017 10:01:35 GMT Transfer-Encoding: chunked Connection: keep-alive {"access_token":"EAAN12SVnRf8BAGGcZBFhAn8Pz7JHqsLVSC00pkZA81ap4rZAJOwSl3ZABaQPT7L03vPSNnsGS2lTduSN1FQMy1q8vRqiefD0sCd3sN4wu1n9tuMgMqXCeVi5zAKod1oPrjgJA246VHN5qkOxQGZBj52ZCgWblJ877cZD","token_type":"bearer","expires_in":5118394}" 0
var_dump is showing valid data, but I can't fetch it using json_decode(). echo $json['access_token']; shows nothing. Am I doing something wrong?
Yes - you are trying to decode the whole response, headers and body, as JSON.
Only the body contains the JSON data you are interested in - so don't set CURLOPT_HEADER.
I'm really confused by this. My company recently switched this URL to https, and I can no longer make cURL requests against it. No one else in the company does PHP, so there's no one to help me debug.
I don't have much experience with https, so I read through a bunch of posts on here and found a few that addressed this same issue, namely, this one:
Can't connect to HTTPS site using cURL. Returns 0 length content instead. What can I do?
At first, I was getting all sorts of errors related to security certificates, but after adding curl.cainfo="c:\xampp\htdocs\login\cacert.pem" to my php.ini file, I believe I have resolved those as I am not getting errors anymore, but I am still not getting back a successful login response.
As part of the process, I need to pass a cookie to the server, which is present. echo $strCookie gives back the correct cookie data, so I don't think it's that.
$searchURL = "https://url.com/valid?";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $searchURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$strCookie = 'testcookie=' . $_COOKIE['testcookie'] . '; path=/';
curl_setopt( $ch, CURLOPT_COOKIE, $strCookie );
curl_setopt($ch, CURLOPT_CAPATH, "\cacert.pem");
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
if($answer = curl_exec($ch))
{
echo "<pre>";
print_r($answer);
echo "</pre>";
}
else
{
echo "<pre>";
echo 'Curl error: ' . curl_error($ch);
echo "</pre>";
}
If I put the url into my browser (url.com/valid?), I get back boolean = true, so I know I am logged in. However, this script is returning boolean = false and I cannot figure out why.
Here are the headers:
TTP/1.1 200 OK
Date: Mon, 09 Nov 2015 21:33:16 GMT
Cache-Control: no-store, no-cache, must-revalidate, max-age=0
Pragma: no-cache
Content-Length: 14
Content-Type: text/plain; charset=UTF-8
X-Powered-By: Servlet/2.5 JSP/2.1
Set-Cookie: amlbcookie=01; domain=.****.com; path=/
Vary: User-Agent,Accept-Encoding
I'm confused by the Set-Cookie: amlbcookie=01 line, as I'm not sure what that cookie is. It does not match the output I get from echo $strCookie.
Ok, to understand the problem, first please visit
http://unblockproxy.nu/
Try to surf any website, let's say (http://www.example.com/samplepage.html) put it in the field then click "unblock" button
After sending the $_POST request, the site should redirect you to something like:
http://unblockproxy.nu/index.php?x=Mfv0KjYRb3J3JO50MgBNbplFn2sTMoqPUIu1Unqn0bqdUoq5VbA9OnO8%3D
Response Headers of the browser is like:
HTTP/1.1 302 Found
Date: Fri, 06 Mar 2015 12:49:30 GMT
Server: Apache/2.2.15
x-powered-by: PHP/5.3.3
Location: http://unblockproxy.nu/index.php?x=Mfv0KjYRb3J3JO50MgBNbplFn2sTMoqPUIu1Unqn0bqdUoq5VbA9OnO8%3D
Cache-Control: max-age=600, private, must-revalidate
Expires: Fri, 06 Mar 2015 12:59:30 GMT
Vary: Accept-Encoding
Connection: close
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
HTTP/1.1 200 OK
Date: Fri, 06 Mar 2015 12:49:34 GMT
Server: Apache/2.2.15
X-Powered-By: PHP/5.3.3
Content-Disposition: inline; filename="samplepage.html"
Cache-Control: max-age=600, private, must-revalidate
Expires: Fri, 06 Mar 2015 12:59:34 GMT
Vary: Accept-Encoding
Connection: close
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
That's easy, now you got the contents of the surfed page by using this web proxy.
Now, i want to do the same job by using curl
My problem is, i don't know how to let curl deal with Content-Disposition of the response header
Here is some codes to simulate my problem::
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://unblockproxy.nu/index.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('x' => 'http://www.example.com/samplepage.html'));
curl_setopt($ch, CURLOPT_COOKIESESSION, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
$string = curl_exec($ch);
curl_close($ch);
echo $string;
This will return the contents of http://unblockproxy.nu/ and that is not what i want (http://www.example.com/samplepage.html which surfed by http://unblockproxy.nu/)
If you want to take a look into the script of this site (2 PHP files only), you can go here
Thank you.
Try this. This works for me just fine if I'm understanding your question correctly. I removed a lot of code that did nothing. Turns out, the problems was that you weren't setting the referer in the request headers.
Let me start from the beginning. Upon submitting the form via POST to view a given website with a proxy, a request is sent to http://unblockproxy.nu/index.php. As you mentioned in your question, index.php handles the form submission and generates an HTTP status code of 302 which essentially just redirects you to another page. Assuming that you send a properly formatted request to index.php, you can parse the response headers and get the value of the redirect URL. Follow the code below to get the redirect URL.
/**
* Submit the form via POST
* #param [site_url] The link to the page that you want to view
* eg: http://sitetoget.com/page.html
* #return A string containing the response headers
*/
function GetRedirect($site_url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://unblockproxy.nu/index.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('x' => $site_url));
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
/**
* Turn a header string into an associative array
* #param [response] The response headers from the form submission
* #return An array containing all of the headers
*/
function GetHeaders($response) {
$headers = [];
$text = substr($response, strpos($response, "\r\n\r\n"));
foreach(explode("\r\n", $text) as $i => $line) {
if($i === 0 || $i == 1) {
$headers['http_code'] = $line;
} else {
list($key, $value) = explode(': ', $line);
if($key != '' && $value != '') {
$headers[$key] = $value;
}
}
}
return $headers;
}
// Get the redirect URL
$redirect = GetRedirect('http://lancenewman.me/');
// Parse the response headers
$headers = GetHeaders($redirect);
// Save the redirect URL
$new_url = $headers['Location'];
Now that you have the URL that index.php redirects to, send a cURL request to it as follows. Strangely enough, almost all of the other request headers that I've tinkered with play no role in determining whether or not this solution works. The reason your code is getting the contents of http://unblockproxy.nu instead of the contents of the given site as viewed by http://unblockproxy.nu is because you're not following the redirections correctly and you're not setting the referer in request headers. The cookies, content-disposition and all of the other headers seem to play no role in solving this.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $new_url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_REFERER, 'http://unblockproxy.nu');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$string = curl_exec($ch);
curl_close($ch);
echo $string;
It's important to note that some of the images, CSS and JS on some of the pages might not properly load because some use relative URLs instead of absolute ones. Just keep that in mind.
The problem is it requires two round-trips to the server to complete the request. Many sites use the method to reduce the number or requests by "bots". The first request creates a cookie (typically for a "session") which must be present in order for the form to be processed.
Perform the curl_exec() twice and see if you get the results you want. The first time the response will send a cookie which curl will save since you have enabled cookies. The second time you should get the results you want.
I am here with a lot of hope to solve my problem. I have this website i want to login to and access a member only page. so basically php code with cURL to login and then open a member only page. Below is the code i used. But each time i try to access member only page, it asks me to login. So it does not save in the session or cookie that i already logged in.
..........
set_time_limit(0);
$username = 'myemail#yahoo.com';
$password = 'mypassword';
$loginUrl = 'http://radaris.com/login/a.login';
$cookie_file_path = getcwd() . '/tmp/cookie.txt';
//init curl
$ch = curl_init();
//Set the URL to work with
curl_setopt($ch, CURLOPT_URL, $loginUrl);
// ENABLE HTTP POST
curl_setopt($ch, CURLOPT_POST, 0);
//Set the post parameters
curl_setopt($ch, CURLOPT_HEADER, 1); // set to 0 to eliminate header info from response
curl_setopt($ch, CURLOPT_POSTFIELDS, 'email='.$username.'&password='.$password."&remember_me=1");
//Handle cookies for the login
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
//Setting CURLOPT_RETURNTRANSFER variable to 1 will force cURL
//not to print out the results of its query.
//Instead, it will return the results as a string return value
//from curl_exec() instead of the usual true/false.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//execute the request (the login)
$store = curl_exec($ch);
echo "<font color=red>Login</font><br>".$store."<br><br>";
$postfields = array();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://radaris.com/my/');
curl_setopt($ch, CURLOPT_HEADER, 1); // set to 0 to eliminate header info from response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_POST, 1);
//Handle cookies for the login
// Edit: prior variable $postFields should be $postfields;
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$result = curl_exec($ch);
echo "<font color=red>Report</font><br>".$result."<br><br>";
..........
The Result i get is :
Login HTTP/1.1 200 OK Server: nginx Date: Thu, 12 Jun 2014 14:21:01
GMT Content-Type: application/json Transfer-Encoding: chunked
Connection: keep-alive Keep-Alive: timeout=20 Cache-Control: no-store,
no-cache, must-revalidate Cache-Control: post-check=0, pre-check=0
Expires: Wed, 14 Jan 2009 19:00:00 GMT X-Robots-Tag: noindex
{"/Rdf.showError":[["Invalid email or password","login_form"],["Check
your email","login_email"],["Check your password","login_password"]]}
Report HTTP/1.1 302 Found Server: nginx Date: Thu, 12 Jun 2014
14:21:03 GMT Content-Type: text/html; charset=utf-8 Transfer-Encoding:
chunked Connection: keep-alive Keep-Alive: timeout=20 Location:
/login?backurl=%2Fmy%2F HTTP/1.1 200 OK Server: nginx Date: Thu, 12
Jun 2014 14:21:03 GMT Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked Connection: keep-alive Keep-Alive:
timeout=20 Vary: Accept-Encoding Vary: Accept-Encoding Set-Cookie:
PHPSESSID=qdg80d48dd17hl879h86v9ruo5; path=/; HttpOnly Expires: Thu,
19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache,
must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Login We
never share or disclose your information!
The above are the headers only. in the 2nd header i get the login form again to login meaning the successful login in the first bit of my code did not save the session that is why when i access member only page, it asks to login.
I am really desperate to get this done right. Thanks everyone in advance.
You're using two separate curl handles, and you never set up the cookie stuff in the second one. Each curl handle is completely independent of each other, so if you don't tell the second handle about the cookiejar/cookiefile you created in the first one, you never actually use the cookie you got from the login request.
Technically, you do NOT have to do one-request-per-handle. A single handle can do multiple requests. The only time it might be easier to start a new one is if you made a complicated custom request with many options set, and it's easier to just start fresh rather than reset those options for the next request.
So your code sequence should be:
init curl
set up cookiefile/cookiefar and other options
do login request
do next next request
close curl
If you don't want to rewrite, then at least add the cookiejar/cookiefile options to the second request.