Upload using CURL, wrong filesize

Hi,

I'm using the following code to upload files using CURL, but it changes the filesize and corrupt the files. Why?

$filnavn = $_FILES['upld_file']['tmp_name'];
$fp = fopen( $filnavn, 'r' );
$stat = fstat( $fp );

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, 'ftp://SERVERIP/testuploads/' . $_FILES['upld_file']['name'] );
curl_setopt( $ch, CURLOPT_USERPWD, 'USER:PASS' );
curl_setopt( $ch, CURLOPT_INFILE, $fp );
curl_setopt( $ch, CURLOPT_INFILESIZE, $stat['size'] ); // Same problem when disabled
curl_setopt( $ch, CURLOPT_UPLOAD, 1 );
$result = curl_exec( $ch );
curl_close( $ch );
fclose( $fp );

if($result != 1 ) {

      echo "Error uploading your file using ASCII mode";
      
}else{

      echo "File uploaded using ASCII mode<br />";
      echo "Filename: ".$_FILES['upld_file']['name'];
      
}
kgp43Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

nicholassolutionsCommented:
curl_setopt( $ch, CURLOPT_INFILE, $fp ); is passing a file handle $fp as the option -- it should be a string containing the file name instead, e.g. $_FILES['upld_file']['name']  Give that a try and see what happens.

Hope that helps,
Matt
kgp43Author Commented:
Changed it but now all uploads has 0 byte filesize

$filnavn = $_FILES['upld_file']['tmp_name'];
$fp = fopen($filnavn, 'r');
$stat = fstat($fp);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'ftp://SERVERIP/testuploads/' . $_FILES['upld_file']['name']);
curl_setopt($ch, CURLOPT_USERPWD, 'USER:PASS');
curl_setopt($ch, CURLOPT_INFILE, $_FILES['upld_file']['name']);
curl_setopt($ch, CURLOPT_INFILESIZE, $stat['size']);
curl_setopt($ch, CURLOPT_UPLOAD, 1);
$result = curl_exec($ch);
curl_close($ch);
fclose($fp );

if($result != 1) {

      echo "Error uploading your file";
      
}else{

      echo "File uploaded<br />";
      echo "Filename: ".$_FILES['upld_file']['name'];
      
}
nicholassolutionsCommented:
oh whoops, I guess maybe what you want is $filnavn = $_FILES['upld_file']['tmp_name']; since that is where the data actually is.
Bootstrap 4: Exploring New Features

Learn how to use and navigate the new features included in Bootstrap 4, the most popular HTML, CSS, and JavaScript framework for developing responsive, mobile-first websites.

kgp43Author Commented:
Should I change this aswell "curl_setopt($ch, CURLOPT_URL, 'ftp://SERVERIP/testuploads/' . $_FILES['upld_file']['name']);"
So it uses $filnavn instead?
kgp43Author Commented:
Changed it so it used $filnavn instead, but same problem (0 filesize)

$filnavn = $_FILES['upld_file']['tmp_name'];
$fp = fopen($filnavn, 'r');
$stat = fstat($fp);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'ftp://SERVERIP/testuploads/' . $_FILES['upld_file']['name']);
curl_setopt($ch, CURLOPT_USERPWD, 'USER:PASS');
curl_setopt($ch, CURLOPT_INFILE, $filnavn);
curl_setopt($ch, CURLOPT_INFILESIZE, $stat['size']);
curl_setopt($ch, CURLOPT_UPLOAD, 1);
$result = curl_exec($ch);
curl_close($ch);
fclose($fp );

if($result != 1) {

     echo "Error uploading your file";
     
}else{

     echo "File uploaded<br />";
     echo "Filename: ".$_FILES['upld_file']['name'];
     
}
nicholassolutionsCommented:
hmm, let me give this a try myself and get back to you
kgp43Author Commented:
okay :)
nicholassolutionsCommented:
OK, I was wrong when I told you to pass the name instead of the file handle -- sorry about that, I was looking at a site where the guy apparently didn't know what he was talking about and I just repeated it like an idiot myself...Anyways, I tried this on my server and it worked. To be honest, I'm not sure what was wrong with what you were doing, but give this a try and see if you have the same problem:

------------------begin-----------------------------------------

<form enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<input name="upld_file" type="file"><input type="submit" name="submit" value="Upload">
</form>
<br><br><hr>

<?php
if(isset($_FILES['upld_file'])){

   $username = 'user';
   $password = 'pass';
   $ip = '123.123.123.123';
   $path = 'www/';

   $ftpURL = 'ftp://'.$ip.'/'.$path;

   $filepath = $_FILES['upld_file']['tmp_name'];
   $filename = $_FILES['upld_file']['name'];
   $fp = fopen($filepath, 'rb');

   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $ftpURL.$filename);
   curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
   curl_setopt($ch, CURLOPT_INFILE, $fp);
   curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filepath));
   curl_setopt($ch, CURLOPT_UPLOAD, 1);

   curl_exec($ch);
   fclose($fp);

   if(curl_errno($ch)) {
        echo 'ERROR: '.curl_error($ch);
   }else{
        curl_close($ch);
        echo "File uploaded<br />";
        echo "Filename: $filename<br>";
   }
}
?>

-------------end-------------------------------

Matt
kgp43Author Commented:
trying it now :)

Do you know if it's possible to upload in ASCII mode?
nicholassolutionsCommented:
Yes, I think it's:
curl_setopt($ch, CURLOPT_TRANSFERTEXT, 1);
kgp43Author Commented:
trying the standard way first to see if that works :)
kgp43Author Commented:
Still receive uploads with 0 byte filesize... weird
nicholassolutionsCommented:
but no error mesage? hmmm....
kgp43Author Commented:
no error messages that im aware of
kgp43Author Commented:
My users uploaded 20 files as a test

- 7 with 0 byte filesize after upload (file created but 0 filesize)
- 1 at 11MB
- 1 at 6MB
- Rest below 1MB

They get no errors
kgp43Author Commented:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ftpURL.$filename);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filepath));
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_exec($ch);
fclose($fp);

if(curl_errno($ch)) {
      echo 'Error uploading your file using BINARY mode<br />'.curl_error($ch);
}else{
      curl_close($ch);
      echo "File uploaded using BINARY mode<br />";
      echo "Filename: $filename<br />";
      echo "Filesize: ".$_FILES['upld_file']['size']." bytes<br />";
}
hernst42Commented:
If you upload files via ftp why don't you use the ftp-extension of php for that purpose at it gives you more information why a upload might fail. See http://de3.php.net/ftp
kgp43Author Commented:
Already used phpftp to ftp the files, but it kept crashing (7/10 didnt upload and no errors was posted).
Created tons of topics about this and was told it was phpftp that wasnt able to handle the current load (~3000 uploads per day (avg 4.3MB/file), should be capable of uploading 10.000/day). Was told to try CURL, but that dosent seems to work (0 filesize).

Think I did everything possible to post errors when something goes wrong.

// Check for errors
switch ($_FILES['upld_file']['error']) // http://www.php.net/manual/en/features.file-upload.errors.php
{

      case 1:
            echo "<font color=red>The uploaded file exceeds the upload_max_filesize directive in php.ini</font>";
            break;
      
      case 2:
            echo "<font color=red>The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form</font>";
            break;
      
      case 3:
            echo "<font color=red>The uploaded file was only partially uploaded</font>";
            break;
      
      case 4:
            echo "<font color=red>No file was uploaded</font>";
            break;
      
      case 6:
            echo "<font color=red>Missing a temporary folder</font>";
            break;
      
      case 0:
            
            // Post filesize
            echo $_FILES['upld_file']['size']." bytes ready to be uploaded (not uploaded yet)<br />
            <br />
            --------------------------------------------<br />
            <b>STATUS:</b><br />
            --------------------------------------------<br />
            <br />";
      
                        
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $ftpURL.$filename);
            curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
            curl_setopt($ch, CURLOPT_INFILE, $fp);
            curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filepath));
            curl_setopt($ch, CURLOPT_UPLOAD, 1);
            curl_exec($ch);
            fclose($fp);
            
            if(curl_errno($ch)) {
                  echo 'Error uploading your file using ASCII mode<br />'.curl_error($ch);
            }else{
                  curl_close($ch);
                  echo "File uploaded using ASCII mode<br />";
                  echo "Filename: $filename<br />";
                  echo "Filesize: ".$_FILES['upld_file']['size']." bytes<br />";
            }
kgp43Author Commented:
Please note the the file from the form is beeing uploaded okay (always did), the problem is when it FTP the file to the correct fileserver.
kgp43Author Commented:
Forgot this (it's above the code posted above):

// FTP server info
$username = 'username';
$password = 'password';
$ip = '123.123.123.123';
$path = 'testuploads/';

// FTP url
$ftpURL = 'ftp://'.$ip.'/'.$path;

// File info
$filepath = $_FILES['upld_file']['tmp_name'];
$filename = $_FILES['upld_file']['name'];
$fp = fopen($filepath, 'rb');
hernst42Commented:
I guess there is more a problem on the remote-server than on the client/webserver side. A analysis should be done there (e.g. maximum connections reached, ...)
kgp43Author Commented:
How do I perform such a analysis?
The same problem accure on our other fileserver (have two atm).
nicholassolutionsCommented:
have you tried FTPing to the same server as the upload is done on? Do you still get an error when you try that?
kgp43Author Commented:
havent tried that.

Do I just change the ip to the same servers ip or is there a smarter way?
nicholassolutionsCommented:
yeah just change $ip to the webserver's, and the user and pass also...
hernst42Commented:
For FTP-serveranalysis better ask in http://www.experts-exchange.com/Networking/Linux_Networking/ and post links to the related questions in PHP where you have problems.

1st step is to read the logs of the ftp-server, you might also increase the logging-level of the ftp-server to get more information about this.
kgp43Author Commented:
btw. I tried using the serverip and typed the wrong username and it came with an error message (incorrect user/password) - this was not the case while using the fileserver ip. It just posted the "success" message like everything was okay.
kgp43Author Commented:
hernst42: will do that after this test (upload to same server)

getting this error:
Error uploading your file using ASCII mode
Couldn't cd to testuploads  <-----

folder created in root of the account and chmod to 777
kgp43Author Commented:
lol, typed the ip of one of my other servers which had an account with the same username, doh!
waiting for my users to test this out since im on a connection limilar to dialup atm :(
nicholassolutionsCommented:
BTW, maybe this is a stupid question, but have you tried just transfering files from your own computer using FTP? EVen if you're on dialup, try just sending a small text file and see if it goes thorugh if you haven't done that already.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
kgp43Author Commented:
I always upload files up to 1MB to see if it works and it always does.
Files below 1MB usualy works.
nicholassolutionsCommented:
OK, I've tested this code once again on my server, FTPing to both the same server and a remote one, and it works fine, so there must be something wrong with your FTP setup on the file server. I think hernst42 is right that asking in the Linux Networking TA is probably likely to get you better help than here on that front.

---------------------------------------------------------------------------------------

<form enctype="multipart/form-data" action="ul.php" method="post">
<input name="upld_file" type="file"><input type="submit" name="submit"
value="Upload">
</form>
<br><br><hr>

<?php
if (isset($_FILES['upld_file'])){
// FTP server info
$username = 'user';
$password = 'pass';
$ip = '123.123.123';
$path = 'www/';
$mode = 'BINARY'; //'ASCII' for ASCII mode

// FTP url
$ftpURL = 'ftp://'.$ip.'/'.$path;

// File info
$filepath = $_FILES['upld_file']['tmp_name'];
$filename = $_FILES['upld_file']['name'];
$fp = fopen($filepath, 'rb');



// Check for errors
switch ($_FILES['upld_file']['error']) // http://www.php.net/manual/en/features.file-upload.errors.php
{

     case 1:
          echo "<font color=red>The uploaded file exceeds the upload_max_filesize directive in php.ini</font>";
          break;

     case 2:
          echo "<font color=red>The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form</font>";
          break;

     case 3:
          echo "<font color=red>The uploaded file was only partially uploaded</font>";
          break;

     case 4:
          echo "<font color=red>No file was uploaded</font>";
          break;

     case 6:
          echo "<font color=red>Missing a temporary folder</font>";
          break;

     case 0:

          // Post filesize
          echo $_FILES['upld_file']['size'].' bytes ready to be uploaded (not uploaded yet)<br />
          <br />
          --------------------------------------------<br />
          <b>STATUS:</b><br />
          --------------------------------------------<br />
          <br />';


          $ch = curl_init();
          curl_setopt($ch, CURLOPT_URL, $ftpURL.$filename);
          curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
          curl_setopt($ch, CURLOPT_INFILE, $fp);
          curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filepath));
          curl_setopt($ch, CURLOPT_UPLOAD, TRUE);
          curl_exec($ch);
          if ($mode=='ASCII') curl_setopt($ch, CURLOPT_TRANSFERTEXT, TRUE);
          fclose($fp);

          //run in verbose mode
          curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
          $fout = fopen('php://output', 'w');
          curl_setopt($ch, CURLOPT_STDERR, $fout);

          if(curl_errno($ch)) {
               echo 'Error uploading your file using ASCII mode<br />'.curl_error($ch);
          }else{
               curl_close($ch);
               echo "File uploaded using $mode mode<br />";
               echo "Filename: $filename<br />";
               echo "Filesize: ".$_FILES['upld_file']['size']." bytes<br />";
          }
          fclose($fout);

    }


}
?>

kgp43Author Commented:
Well, phpftp worked okay aswell until the load/uploads increases then it started to make problems (same things seems to be the case with CURL).
Im making a new topic at the other forum with a link to this one.

Thanks for your help so far :)
Should I give out points?
kgp43Author Commented:
kgp43Author Commented:
anyone?
nicholassolutionsCommented:
I've been following the other thread, but I'm still a little stumped. I have two ideas, I guess:

1) Have you tried transferring a file with your code that is *already* on your server? That is, upload a 50MB file to your first server, and then just use the CURL code to ftp it to your fileserver. I'd be interested to know if this also fails or not.

2) maybe you could use the ftp program on your server directly, or use sockets. What version of PHP do you have, and what is the OS on the server that accepts the initial upload?

-Matt
kgp43Author Commented:
1) Changed it so it FTP'ed a 50MB file *already* placed at the main server to the same server and a fileserver, made it run atleast 3 times on each - all was ftp'ed successful.

2) Server info (both main and fileservers):

RHE
PHP 4.3.11
kgp43Author Commented:
So FTP a file from one server to another (and the same) is working okay, but it cant FTP a file uploaded by a form, even when they are uploaded okay to the tmp folder (can always echo the correct filesize after upload).

Think this is a odd problem.
nicholassolutionsCommented:
Hmmm, well at least that means the problem is actually not with the CURL code itself, which is good to know. Just to be sure, have a read through this page (including the comments) and make sure you haven't missed anything simple.

Maybe give this a try: upload the file like you have been, then do:
if (is_uploaded_file($filepath)) move_uploaded_file($filepath, $filename);

This will move the file to the same directory as the script, with the name $filename. Then FTP this to your fileserver, and do:

unlink($filename);

to get rid of the file on your main server.

-Matt
kgp43Author Commented:
Okay, I added the thing you suggested and waiting for my users to report back.

Does this mean I can go back to phpftp or will it be more wise to switch to CURL?
kgp43Author Commented:
This is the current code, did I do it correct (test uploader):

<?
// Get time, 36000 seconds (10h) (60MB at 10Kb/sec)
set_time_limit(36000);

// Display all errors
ini_set('display_errors', true);

// Error handling, 0=off 1=on
error_reporting(1);

// Check if any file is submitted
if (!$_FILES['upld_file']['name']) {

      echo "<font color=red>No file selected</font>";
      exit();
}

// Get the file extention
$file_type = $_FILES['upld_file']['name'];
$file_type = pathinfo($file_type);
$file_type = strtolower($file_type['extension']);

// FTP server info
$username = 'user';
$password = 'pass';
$ip = '123.123.123.123';
$path = 'testuploads/';

// FTP url
$ftpURL = 'ftp://'.$ip.'/'.$path;

// File info
$filepath = $_FILES['upld_file']['tmp_name'];
$filename = $_FILES['upld_file']['name'];
$fp = fopen($filepath, 'rb');

// Check if file has been moved to the tmp folder, if not then move it to the same folder as this page
// Unlink after upload (later)
if (is_uploaded_file($filepath)) move_uploaded_file($filepath, $filename);

// Check for errors
switch ($_FILES['upld_file']['error']) // http://www.php.net/manual/en/features.file-upload.errors.php
{

      case 1:
            echo "<font color=red>The uploaded file exceeds the upload_max_filesize directive in php.ini</font>";
            break;
      
      case 2:
            echo "<font color=red>The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form</font>";
            break;
      
      case 3:
            echo "<font color=red>The uploaded file was only partially uploaded</font>";
            break;
      
      case 4:
            echo "<font color=red>No file was uploaded</font>";
            break;
      
      case 6:
            echo "<font color=red>Missing a temporary folder</font>";
            break;
      
      case 0:
            
            // Post filesize
            echo $_FILES['upld_file']['size']." bytes ready to be uploaded (not uploaded yet)<br />
            <br />
            --------------------------------------------<br />
            <b>STATUS:</b><br />
            --------------------------------------------<br />
            <br />";
      
            // ASCII filetypes
            $ascii_filetypes = array('htm', 'html', 'shtml', 'cnf', 'css', 'forward', 'map', 'pwd', 'txt', 'grp', 'ctl', 'nfo');
      
            if (in_array($file_type, $ascii_filetypes)) {
                        
                  $ch = curl_init();
                  curl_setopt($ch, CURLOPT_URL, $ftpURL.$filename);
                  curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
                  curl_setopt($ch, CURLOPT_INFILE, $fp);
                  curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filepath));
                  curl_setopt($ch, CURLOPT_UPLOAD, 1);
                  curl_exec($ch);
                  fclose($fp);
                  
                  if(curl_errno($ch)) {
                        echo 'Error uploading your file using ASCII mode<br />'.curl_error($ch);
                  }else{
                        curl_close($ch);
                        echo "File uploaded using ASCII mode<br />";
                        echo "Filename: $filename<br />";
                        echo "Filesize: ".$_FILES['upld_file']['size']." bytes<br />";
                  }
            
            }else{
                  
                  $ch = curl_init();
                  curl_setopt($ch, CURLOPT_URL, $ftpURL.$filename);
                  curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
                  curl_setopt($ch, CURLOPT_INFILE, $fp);
                  curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filepath));
                  curl_setopt($ch, CURLOPT_UPLOAD, 1);
                  curl_exec($ch);
                  fclose($fp);
                  
                  if(curl_errno($ch)) {
                        echo 'Error uploading your file using BINARY mode<br />'.curl_error($ch);
                  }else{
                        curl_close($ch);
                        echo "File uploaded using BINARY mode<br />";
                        echo "Filename: $filename<br />";
                        echo "Filesize: ".$_FILES['upld_file']['size']." bytes<br />";
                  }
                  
            }
      break;
      
}
// (did this earlier) Check if file has been moved to the tmp folder, if not then move it to the same folder as this page
// Unlink after upload (later)
unlink($filename);

echo "<br /><br /><br />
<font color=red><b>Remember to paste and copy the entire text on this page when you report back! (including this one)</b></font>";
?>
nicholassolutionsCommented:
>>Does this mean I can go back to phpftp or will it be more wise to switch to CURL

If you can get this to work, then I would assume yes, you can. Probably the only way to know is to try though.
kgp43Author Commented:
I added the code you suggested but still get 0 filesize uploads.
Can it be a issue with the tmp folder (like too small)?
The server admins made it (awhile back) so it automatic delete inactive files in the tmp folder when it gets too full.
kgp43Author Commented:
increased the size of the tmp folder which seems to solve the problems.
will get back to you in a couple of days.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.