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.
Related
Recently i started working on the Payment Gateway( further spelled as 'PG') process for my site. The process involves sending the Post data by form to PG server by redirecting to their page, and receiving a response from the PG about the Transaction via POST data sent by redirecting the URL to our server page.
The problem arises here, as my server unable to retrieve the POST Data sent from PG server.
As I am coding in PHP, I tried to print all the response coming from PG with print_r($_POST); and even tried with print_r($_REQUEST);. I didn't find any data printing except the PHPSESSID and some other data array.
As for the confirmation I checked whether they were sending the Data or not with the IE addon known as "TamperIE". It is showing all the POST data sending to their server. But it is not at all coming to our server. I tried this process on another Server: there I was able to get the POST response, but not with currently working server.
Can you suggest what might be the problem?
Simulate the request from the other server by using curl, make a test.php with the following content:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/path/to/form");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$data = array(
'foo' => 'foo foo foo',
'bar' => 'bar bar bar',
'baz' => 'baz baz baz'
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$output = curl_exec($ch);
curl_close($ch);
And run it using cli to get the debugging information and see what is wrong. Don't forget offcourse to put the variables supposed to be returned from the server and the exact url
Use CURl for this, its secure and reliable.
If possible send a unique code (order id) of your sales/purchase order in PG request and I'm sure your PG will send back that unique code in the POST data and with the help of that unique code you can track that order id to update the status of the order.
By using this approach you do not need to worry about the session.
I found the reason why this issue is occurring.
In the .htaccess file I written the line for the Redirection:
RewriteRule ^ http://mysite.com{REQUEST_URI} [R=301,L]
If I remove the above line from the file, I am able to receive the POST Fields from PG server, But I am loosing the SESSION DATA stored before proceeding for PG contains the Booking Info. These session are unable to show in the response page, as server generating totally new session from the response page.
I found one alternate solution for this issue:
I am using the following code in all the pages which require the session as:
$lifetime=60*30;
session_set_cookie_params ( $lifetime , '/', '.mysite.com');
After adding above code before session_start();.
Now I am able to get both POST data from PG and also able to retain the SESSION Values.
However, I think this is not an ideal solution for this issue. If anyone can suggest any SERVER Configuration for the URL Redirection and maintaining the SESSION values after REDIRECTION it will be great. Thank you All :-)
I am developing an application in which the input I receive is through an SMS gateway ( and not a browser). I need to process the data obtained through SMS and pass it onto another PHP file which will finish the processing and send back an SMS to the SMS gateway.
However, when I try to redirect from page1.php to page2.php, it is not working with the following code:
page1.php:
$url = "location:http://www.iweavesolutions.com/$extra?sms=".$msg."&keyword=".$key."&num=".$msg_num."&src=".$source;
header($url);
page2.php:
$msg = $_GET['sms'];
$msg_num = $_GET['num'];
$keyword = $_GET['keyword'];
$src = $_GET['src'];
send_sms($msg,$msg_num);
However, the header call in the first page doesn't seem to work. php documentation says that header is used for browser related activities. In my application there is no browser at all. So, do I need to change my mechanism for passing values across files? Please help
please refer to "CURL"
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,"http://www.iweavesolutions.com");
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,2);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'variable1=abc&variable2=123');
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true);
curl_setopt($ch,CURLOPT_MAXREDIRS,1);
$buffer = curl_exec($ch);
curl_close($ch);
some thing like this
Sending a location:[someUrl] header as an answer to a request just tells the requesting client to do another request to that location. It is up to the client whether to follow this redirect or not. Browsers will usually do this, other clients may not.
If the client you're dealing with (the SMS gateway) does not follow location header redirects, you need to check with the clients documentation if there is some mechanism to make him do that. If there is no way to redirect the client, you need to change your server side logic to get rid of the need for the redirect, i.e. you need to call the processing logic in your 'page2.php' directly from 'page1.php' without the indirection of the redirect (or bundle the whole logic in one file, etc.).
The SMS gateway probably does not implement HTTP properly. IME this is not uncommon.
As a side note, your first script (assuming it is complete) is written assuming register_globals is enabled - this has been deprecated for a long time, and does not url-encode the values - which may be the cause of the issue here. If not, you'll need to either:
fix the SMS gateway
change the end point registered on the SMS gateway to eliminate the ned for redirection
include the code from the redirected script into the current endpoint script
proxy the request from the gateway in the endpoint script.
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
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)?
I have a form on my site which sends data to some remote site - simple html form.
What I want to do is to use data user enters into form for statistical purposes.
So I instead of sending data to the remote page I send it first to my script which resends it the remote site.
The thing is I need it to behave in exact way the usual form would behave taking user to the remote site and displaying resources.
When I use this code it kinda works but not in the way I want it to:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $action);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$result = curl_exec($ch);
curl_close($ch);
Problem is that it displays response in the same script. For example if $action is for example:
somesite.com/processform.php and my script name is mysqcript.php it would display the response of "somesite.com/processform.php" inside "mysqcript.php" so all the relative links are not working.
How do I make it to send the user to "somesite.com/processform.php"? Same thing that pressing the button would do?
Leonti
I think you will have to do this on your end, as translating relative paths is the client's job. It should be simple: Just take the base directory of the request you made
http://otherdomain.com/my/request/path.php
and add it in front of every outgoing link that does not begin with "/" or a protocol ("http://", "ftp://").
Detecting all the outgoing links is hard, but I am 100% sure there are ready-made PHP classes that do that. Check for example this article and the getLinks() function in the user comments. I am not 100% sure whether this is what you need but it certainly goes to the right direction.
Here are a couple of possible solutions, which I post separately so they don't get mixed up with the one I recommend:
1 - keep using cURL, parse the response and add a <base/> tag to it. It should work for pretty much everything on that page.
<base href="http://realsite.com/form_url.php" />
2 - do not alter the submit URL. Submit the form to the real URL, but capture its content using some Javascript library (YUI does that) and send it to your script via XHR. It's still kind of hacky though.
There are several ways to do that. Here's one of the easiest: just use a 307 redirect.
header('Location: http://realsite.com/form_url.php', true, 307');
You can do your logging and stuff either before or after header() but if you do it after calling header() you will need to start your script with
ignore_user_abort(true);
Note that browsers are supposed to notify the user that their form is being redirected.