Is it possible to detect if the ftp resource is disconnected or timed out?
A sample script
<?php
$connection = ftp_connect('127.0.0.1');
ftp_login($connection, '123', '456');
sleep(660); // proftpd has 600 as default no transfer timeout
ftp_chdir($connection, '/');
ftp_close($connection);
Then we got a warning
Warning:
ftp_chdir():
No transfer timeout (600 seconds):
closing control connection in line 5
Is it possible to check if disconnected or timed out?
if(!$connection)
doesnt work because the resource exists...
But the resource is timed out :/
You can use this something like this
if(is_array(ftp_nlist($connection, "."))){
echo "Connected";
}
References:
http://php.net/manual/en/function.is-array.php
http://php.net/manual/en/function.ftp-nlist.php
Related
I have a PC that is running some FTP via PHP that I know used to work 1-2 months ago, but now I return to it I find that the PC is no longer working. I know I have been using the PC but I cannot think of what might have changed.
The PHP is throwing out error messages reading
Unable to build data connection: Connection refused
...when I use the ftp_put() function.
The cut down code I am using is:
<?php
$trackErrors = ini_get('track_errors');
ini_set('track_errors', 1);
$server="***.***.***.***";
$port=21;
echo "<LI>Connecting to $server:$port<BR>";
$conn_id = ftp_connect($server,$port,9999999) or die("<BR>Unable to connect to ".$server.":$port server.");
if ( !$conn_id ) {
$errmsg = $php_errormsg;
echo "<BR><LI>ERR:$errmsg";
}
else {
$passive=false;
echo "<LI>Setting Passive Mode=$passive";
ftp_pasv($conn_id, $passive);
$user="*********";
$pass="*********";
echo "<LI>Connecting as $user/*****";
if (!ftp_login($conn_id, $user, $pass)) {
$msg = "Failed to login to $selected_server as $user; <BR>check logincredentials in the Settings";
echo "<BR><LI>$msg";
$errmsg = $php_errormsg;
echo "<LI>ERR:$errmsg";
return $msg;
}
ftp_set_option($conn_id, FTP_TIMEOUT_SEC, 10000);
if (!#ftp_put($conn_id, "test.txt", "C:......test.txt", FTP_BINARY)) {
echo "<BR><LI>ftp_put failed";
$errmsg = $php_errormsg;
echo "<LI>ERR:$errmsg";
}
echo "<HR>Done";
}
?>
the output when running this as a webpage is
Connecting to ***.***.***.***:21
Setting Passive Mode=
Connecting as *******/*****
ftp_put failed
ERR:ftp_put(): Unable to build data connection: Connection refused
Done
The result is that the ftp_put() gives the error message and leaves a zero (0) byte file with the right filename on the server.
The strange thing is is that
the same code/connection info works on another laptop ok
the same connection info works ok using FileZilla when pushing a file
the problem occurs on several servers (ie. it's not just one specific destination that has the problem)
Also, this doesn't seem to have anything to do with the passive mode (it fails with and without this enabled)
Does anyone have any suggestions?
Thanks
Abe
You are using the active FTP mode. In the active mode the server tries to connect to the client. In most network configurations, that's not possible as the client machine is usually behind a firewall.
That's why the server fails with:
Unable to build data connection: Connection refused
It's specifically ProFTPD error message for this situation.
See my article on the active and passive FTP connection modes for details.
The code can work on other machines, if they have firewall disabled or if they have rules that allow incoming traffic on unprivileged ports.
FileZilla works because it defaults to the passive mode (as most modern FTP clients do).
You have claimed to try the passive mode too, yet to get the same error message.
That's because you are using the ftp_pasv call incorrectly.
You have to move the ftp_pasv call after the ftp_login.
$user = "*********";
$pass = "*********";
echo "<LI>Connecting as $user/*****";
if (!ftp_login($conn_id, $user, $pass)) {
// ...
}
$passive = true;
echo "<LI>Setting Passive Mode=$passive";
ftp_pasv($conn_id, $passive);
The documentation clearly suggests it:
Please note that ftp_pasv() can only be called after a successful login or otherwise it will fail.
For a similar issue (just with Pure-FTPd), see PHP upload via FTP - ftp_put() I won't open a connection to x.x.x.x (only to y.y.y.y).
I am very new to php, and i am trying to connect to ftp and post a form, which has a few text fields, and 3 image upload, the images will be uploaded to the server. I am using godaddy, and they dont allow ftp_connect, only fsocketopen(),and only available on ports 80 (http) and 443(https). Can i have some advice on how to approach this(fsockopen)?
I researched and below is what i got, i assume the first part is server, second part is the port so i assume is 80(as godaddy said only that 2 ports are available), but what are the last 3? The $error_number,$error_string, and the last part?
Thanks for your time. Sorry that if the question is a newbie question. I researched for a while, i still can't fix it.
fsockopen('abc.com', '80', $error_number, $error_string, 30)
<?php
$ftp_user_name='name';
$ftp_user_pass='pass';
$connection = 'server';
$errno='';
$connect= fsockopen("abc.info", 80, $errno, $errstr, 30) or die ("Cannot connect to host");
$login = ftp_login($connect, $ftp_user_name, $ftp_user_pass);
if (!$connect)
{die ("FTP connection has encountered an error!");}
//exit;
if (!$login)
{die ("But failed at login Attempted to connect to $connection for user $ftp_user_name....");}
?>
At the risk of sounding conceited, RTM please.
From the PHP Docs:
errno If provided, holds the system level error number that
occurred in the system-level connect() call. If the value returned in
errno is 0 and the function returned FALSE, it is an indication that
the error occurred before the connect() call. This is most likely due
to a problem initializing the socket.
errstr The error message as a string.
timeout The connection timeout, in seconds.
That is the script I have
<?php
$timeout = 10;
$target = "tls://testbed-epp.nominet.org.uk:700";
$result = stream_socket_client($target, $errno, $errstr, 30, STREAM_CLIENT_CONNECT);
if ($result === False) {
throw new Exception("Error connecting to $target: $errstr (code $errno)");
}
echo "Connected";
And it throws an exception
Error connecting to tls://testbed-epp.nominet.org.uk:700: (code 0)
There is also a warning
WARNING: stream_socket_client(): Failed to enable crypto
At the same time running
openssl s_client -connect testbed-epp.nominet.org.uk:700
in a terminal connects flawlessly.
Any ideas will be appreciated
Try this instead:
$result = stream_socket_client("testbed-epp.nominet.org.uk:700", $errno, $errstr);
EDIT: also you can setup secure connection via stream_socket_enable_crypto() function, but you should note that it must be used AFTER initialization of socket connection.
Well, i tested your code on my apache server, and it is working fine. Can you check your apache configs. In the configs there is a parameter called "Registered Stream Socket Transports ". Just check if tls exists as a value over there, else there is some other problem, but it definitely isn't your script
$timeout =- 10;
^----
You're setting $timeout to be negative 10 seconds. e.g. you're killing the connection attempt before it can EVER get started.
I am using fsockopen() to send data via TCP to a remote host:
$s = fsockopen($host, $port);
fwrite($s, $data);
fclose($s);
How can I detect afterwards if the connection was closed (with a FIN) or aborted (with a RST) by the remote host?
According to the documentation socket_last_error() and socket_send() can be helpful for you:
socket_send() returns the number of bytes sent, or FALSE on error.
socket_last_error() returns the last error on the socket
I believe, that PHP is able to detect if the connection was closed, however not sure about this.
When i try to upload files using PHP's ftp_put function, earlier it was erroring:
Warning: ftp_put() [function.ftp-put]: No data connection
Now, i tried to put passive mode on:
ftp_pasv($conn_id, true);
then comes error:
Warning: ftp_put() [function.ftp-put]: Type set to I. in
ftp_login is done properly and it says Successfully.
Now it gives new warning: Warning: ftp_put() [function.ftp-put]: abc.txt: Cannot open or remove a file containing a running program.
Any ideas, why file not tranferring ?
Thanks !
Here is my code snippet:
$conn_id = ftp_connect($ftp_server) or die("Couldn't connect to $ftp_server");
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass) or die("You do not have access to this ftp server!");
if ((!$conn_id) || (!$login_result)) {
// wont ever hit this, b/c of the die call on ftp_login
echo "<span style='color:#FF0000'><h2>FTP connection has failed! <br />";
echo "Attempted to connect to $ftp_server for user $ftp_user_name</h2></span>";
exit;
} else {
//echo "Connected to $ftp_server, for user $ftp_user_name <br />";
}
//turn passive mode on
ftp_pasv($conn_id, true);
$upload = ftp_put($conn_id, $destination_file.$name, $filename, FTP_BINARY);
if (!$upload) {
echo "<span style='color:#FF0000'><h2>FTP upload of $filename has failed!</h2></span> <br />";
} else {
echo 'Uploaded';
}
ftp_close($conn_id);
http://php.net/ftp_pasv
$resource = ftp_connect('ftp.example.com');
ftp_login($resource, 'username', 'password');
# set this to true
ftp_pasv($resource, true);
ftp_get(...);
ftp_put(...);
I was recieving same (not very descriptive) error message E_WARNING ftp_get(): Type set to I..
I found out that it is because server running PHP did not have visible public IP (it is virtual server on my workstation).
Solution was using passive mode. Default setting (active mode) did not have problem on live server, because live server has visible public IP.
The last error you are seeing happens when the FTP daemon is stuck with the uploaded file open and waiting for you to write to it.
Anytime you successfully open a connection over an FTP server, be prepared to close the connection with the following function when the process completes or terminates due to any errors.
ftp_close($conn_id);
It's possible your script is leaving its connections open and the FTP server is getting confused by this. Try adding ftp_close in the appropriate places and see if the script runs more smoothly.
I've tried using the ftp functions in PHP and found it was much easier to use file_put_contents() like the following:
$remote_file = "ftp://username:password#host.com/path/to/file.txt";
file_put_contents($remote_file, $file_contents);
You can still check if it was successful and all that good stuff of course too.
Your ftp setup looks ok, try putting the filename $destination_file.$name in a single variable, dump the variable and make sure this file exists with absolute path if it is not in the same folder as your script. That is the only detail I saw in a quick glance, that could choke your upload.
Make sure your file is not opened in an editor! And if the file is .txt you can use FTP_ASCII although being in binary should not cause a problem.
Good-luck!
I found its solution as below:
I just talked to EUKHOST server support
Main point in this was that the support person now opened a passive port range for FTP on server, and he told us to try the FTP upload now. If you could try it with some testfile and it went through successfully..
Add following lines at the end of
open /etc/vsftpd.conf and add
pasv_promiscuous=YES___ at the end.
In my case, the issue triggering this error was that the file I was trying to upload was too large for the recieving server's configuration.