I'm not sure if I'm asking this properly.
I have two PHP pages located on the same server. The first PHP page sets a cookie with an expiration and the second one checks to see if that cookie was set. if it is set, it returns "on". If it isn't set, it returns "off".
If I just run the pages like
"www.example.com/set_cookie.php"
AND
"www.example.com/is_cookie_set.php"
I get an "on" from is_cookie_set.php.
Heres the problem, on the set_cookie.php file I have a function called is_set. This function executes the following cURL and returns the contents ("on" or "off"). Unfortunately, the contents are always returned as "off". however, if I check the file manually ("www.example.com/is_cookie_set.php") I can see that the cookie was set.
Heres the function :
<?php
function is_set()
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://example.com/is_cookie_set.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$contents = curl_exec ($ch);
curl_close ($ch);
echo $contents;
}
?>
Please note, I'm not using cURL to GET or SET cookies, only to check a page that checks if the cookie was set.
I've looked into CURLOPT_COOKIEJAR, and CURLOPT_COOKIEFILE, but I believe those are for setting cookies via cURL and I don't want to do this.
I believe you are making a confusion. When you are using curl, PHP will go to the trouble of acting like a client (like a browser maybe), and make that request for you. That is, the cookies that curl checks for have nothing to do with the cookies in your current browser. I think.
I'm not entirely sure what you are trying to do here but you are aware, as nc3b already states, that in your is_set() function, it's PHP acting as the client and not your browser, right? That means that your cookie test will always fail (= return with no cookies).
Cookies are stored by the client and sent along with every request to the server.
If you want to find out in PHP whether a cookie has been set - of course, you need to be on the same domain as the cookie for that - you can use plain if (isset($_COOKIE["cookiename"])).
Maybe you are trying to build a solution to query for a cookie on a remote host. For that, see this SO question:
Cross domain cookies
Curl acts like your browser as a http client.
If configured they both recceive and store cookies, but they are in no way related.
Curl doesn't use the browser cookies. If you want to use your browser cookies, you have to use the --cookie option switch. See the manpage for details: http://curl.haxx.se/docs/manpage.html
For example Firefox stores them in a file called cookies.txt.
Under linux its located under ~/.mozilla/firefox/$profilefolder/cookies.txt
Hint: If you use Firefox >= 3.0 the cookies are stored in a sqlite database. If you want to use them with curl, you have to extract a cookies.txt file by yourself.
Here are some examples how to do that:
http://roshan.info/blog/2010/03/14/using-firefox-30-cookies-with-wgetcurl/
http://slacy.com/blog/2010/02/using-cookies-sqlite-in-wget-or-curl/
sqlite3 -separator $'\t' cookies.sqlite \
'select host, "TRUE", path, case isSecure when 0 then "FALSE" else "TRUE" end, expiry, name, value from moz_cookies' > cookies.txt
Related
I'm working on a bit of PHP code that depends on a remote file which happens to be hosted on pastebin. The server I am working on has all the necessary functions enabled, as running it with FILE_URL set to http://google.com returns the expected results. I've also verified through php.ini for extra measure.
Everything should work, but it doesn't. Calling file() on a URL formed as such, http://pastebin.com/raw.php?i=<paste id here>, returns a 500 server error. Doing the same on the exact same file hosted locally or on google.com returns a reasonable result.
I have verified that the URL is set to the correct value and verified that the remote page is where I think that it is. I'm at a loss.
ini_set("allow_url_fopen", true);
// Prefer remote (up-to-date) file, fallback to local file
if( ini_get("allow_url_fopen") ){
$file = file( FILE_URL );
}
if(!isset( $file ) || !$file ) {
$file = file( LOCAL_FILE_PATH );
}
I wasn't able to test this, but you should use curl, try something like this:
<?php
$url = "http://pastebin.com/2ZdFcEKh";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
Pastebin appear to use a protection system that will automatically block IP addresses that issue requests that are "bot-like".
In the case of your example, you will get a 500 server error since the file() command never completes (since their protection system never closes the connection) and there is no timeout facility in your call. The script is probably considered "bot-like" since file() does not pass through all the standard HTTP headers a typical browser would.
To solve this problem, I would recommend investigating cURL and perhaps look at setting a browser user agent as a starting point to grant access to your script. I should also mention that it would be in your interests to investigate whether or not this is considered a breach of the Pastebin user agreement. While I cannot see any reference to using scripts in their FAQ (as of 2012/12/29), they have installed protection against scripts for a reason.
I have been searching for a way, to specify the cookie data for CURL. I have found some solutions on how to save the cookies from a visited page, but that's not what I need. What I want is, to write the data for the cookie myself, so CURL uses it.
You can use curl_setopt with the CURLOPT_COOKIE constant:
<?php
// create a new cURL resource
$ch = curl_init();
// cookies to be sent
curl_setopt($ch, CURLOPT_COOKIE, "fruit=apple; colour=red");
You really should read the documentation - it's listed with exactly the keywords you'd expect and contains a lot of helpful info:
-b, --cookie
(HTTP) Pass the data to the HTTP server as a cookie. It is supposedly
the data previously received from the server in a "Set-Cookie:" line.
The data should be in the format "NAME1=VALUE1; NAME2=VALUE2".
If no '=' symbol is used in the line, it is treated as a filename to
use to read previously stored cookie lines from, which should be used
in this session if they match. Using this method also activates the
"cookie parser" which will make curl record incoming cookies too,
which may be handy if you're using this in combination with the -L,
--location option. The file format of the file to read cookies from should be plain HTTP headers or the Netscape/Mozilla cookie file
format.
NOTE that the file specified with -b, --cookie is only used as input.
No cookies will be stored in the file. To store cookies, use the -c,
--cookie-jar option or you could even save the HTTP headers to a file using -D, --dump-header!
If this option is set more than once, the last one will be the one
that's used.
cURL can use a cookie file in Netscape format. Just create such a file yourself and use as the CURLOPT_COOKIEFILE option.
I was wondering if there is any way to check a page has been ran in a browser (by a human) in PHP.
I've got a page that only needs to be accessed through a cURL request. So I don't want users snooping around on it.
any ideas?
thanks
EDIT:
Because this is one of those questions that are not easily found on the web, here's the solution i used:
I came up with an idea thanks to anthony-arnold. Its not very stable, but it should do for now.
I simply sent the user agent in my cURL request:
//made a new var with the user agent string.
$user_agent = "anything I want in here, which will be my user agent";
//added this line in the cURL request to send the useragent to the target page:
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
and then I simply wrote an if statement to handle it:
if
($_SERVER['HTTP_USER_AGENT'] == "my expected useragent - the string i previously placed into the $user_agent var."){
echo "the useragent is as expected, do whatever";
}
else if
($_SERVER['HTTP_USER_AGENT'] != "my expected useragent - the string i previously placed into the $user_agent var."){
echo "useragent is not as expected, bye now."; exit();}
And that did the trick.
Check the User-Agent or use the get browser function to check which browser is requesting your page. You could configure your web server to fail unless a specific user agent is specified. You can set the user agent in cURL using the --user-agent switch (see the man page).
Unfortunately, the user agent can be spoofed so you can never be absolutely sure that the one sent by the client is in fact correct.
There is a problem with this idea though. If it's on the public web, you have to expect that people might try to access it in any way! If the HTTP request is valid, your server will respond to it (under default configuration). If you really don't want it accessed by any method other than your prescribed cURL one, then you might need to invest in some further authentication/authorization methods (e.g. username/passphrase authentication via SSL).
I've got a simple php script to ping some of my domains using file_get_contents(), however I have checked my logs and they are not recording any get requests.
I have
$result = file_get_contents($url);
echo $url. ' pinged ok\n';
where $url for each of the domains is just a simple string of the form http://mydomain.com/, echo verifies this. Manual requests made by myself are showing.
Why would the get requests not be showing in my logs?
Actually I've got it to register the hit when I send $result to the browser. I guess this means the webserver only records browser requests? Is there any way to mimic such in php?
ok tried curl php:
// create curl resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, "getcorporate.co.nr");
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
same effect though - no hit registered in logs. So far it only registers when I feed the http response back from my script to the browser. Obviously this will only work for a single request and not a bunch as is the purpose of my script.
If something else is going wrong, what debugging output can I look at?
Edit: D'oh! See comments below accepted answer for explanation of my erroneous thinking.
If the request is actually being made, it would be in the logs.
Your example code could be failing silently.
What happens if you do:
<?PHP
if ($result = file_get_contents($url)){
echo "Success";
}else{
echo "Epic Fail!";
}
If that's failing, you'll want to turn on some error reporting or logging and try to figure out why.
Note: if you're in safe mode, or otherwise have fopen url wrappers disabled, file_get_contents() will not grab a remote page. This is the most likely reason things would be failing (assuming there's not a typo in the contents of $url).
Use curl instead?
That's odd. Maybe there is some caching afoot? Have you tried changing the URL dynamically ($url = $url."?timestamp=".time() for example)?
Actually, it's gotten so messy that I'm not even sure curl is the culprit. So, here's the php:
$creds = array(
'pw' => "xxxx",
'login' => "user"
);
$login_url = "https://www.example.net/login-form"; //action value in real form.
$loginpage = curl_init();
curl_setopt($loginpage, CURLOPT_HEADER, 1);
curl_setopt($loginpage, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($loginpage, CURLOPT_URL, $login_url);
curl_setopt($loginpage, CURLOPT_POST, 1);
curl_setopt($loginpage, CURLOPT_POSTFIELDS, $creds);
$response = curl_exec($loginpage);
echo $response;
I get the headers (which match the headers of a normal, successful request), followed by the login page (I'm guessing curl captured this due to a redirect) which has an error to the effect of "Bad contact type".
I thought the problem was that the request had the host set to the requesting server, not the remote server, but then I noticed (in Firebug), that the request is sent as GET, not POST.
If I copy the login site's form, strip it down to just the form elements with values, and put the full URL for the action, it works just great. So I would think this isn't a security issue where the login request has to originate on the same server, etc. (I even get rid of the empty hidden values and all of the JS which set some of the other cookies).
Then again, I get confused pretty quickly.
Any ideas why it's showing up as GET, or why it's not working, for that matter?
When troubleshooting the entire class of PHP-cURL-related problems, you simply have to turn on CURLOPT_VERBOSE and give CURLOPT_STDERR a file handle.
tail -f your file, compare the headers and response to the ones you see in Firebug, and the problem should become clear.
The request is made from the server, and will not show up in Firebug. (You probably confused it with another request by your browser). Use wireshark to find out what really happens. You are not setting CURLOPT_FOLLOWLOCATION; redirects should not be followed.
Summarizing: Guess less, post more. Link to a pcap dump, and we will be able to tell exactly what you're doing wrong; or post the exact output of the php script, and we might.
The shown code does a multipart formpost (since you pass a hash array to the POSTFIELDS option), which probably is not what the target server expects.
try throwing in a print_r(curl_getinfo($loginpage)) at the end, see what the header data it sent back as.
also, if your trying to fake that your logging in from their site, your going to want to make sure your sending the correct referrer with your post, so that they "think" you were on the website when you sent it.