views:

150

answers:

4

Hi,

with html forms we can upload a file from a client to a server with enctype="multipart/form-data", input type="file" and so on.

Is there a way to have a file already ON the server and transfer it to another server the same way?

Thanks for hints.

// WoW! This is the fastest question answering page i have ever seen!!

A: 

Ex. if you have a file called mypicture.gif on server A and want to send it to server B, you can use CURL.

  1. Server A reads the content as a String.
  2. Post the string with CURL to Server B
  3. Server B fetches the String and stores it as a file called mypictyre-copy.gif

See http://php.net/manual/en/book.curl.php

Some sample PHP code:

<?php
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_VERBOSE, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
    curl_setopt($ch, CURLOPT_URL, _VIRUS_SCAN_URL);
    curl_setopt($ch, CURLOPT_POST, true);
    // same as <input type="file" name="file_box">
    $post = array(
        "file_box"=>"@/path/to/myfile.jpg",
    );
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post); 
    $response = curl_exec($ch);
?>
PHP_Jedi
A: 

FTP is probably a better choice than HTTP, if the servers are both under your control.

Coronatus
Unfortunately, not
qualle
FTP is not a good choice since it is troublesome to traverse firewalls and NAT gateways. Stick with HTTP or even better use HTTPS. Advanced solutions also take webdav into consideration, but NEVER FTP!
Raven
If both servers are under the askers' control (like I said in the answer), I don't see how firewalls are a problem?
Coronatus
Well, because every server should have a firewall only allowing used ports to be open (stateful). This can not be achieved with FTP.Too many servers are too open because of programers still choosing ftp.
Raven
+1  A: 

When the browser is uploading a file the server, it send an HTTP POST requests, that contains the file's content.

You'll have te replicate that.


With PHP, the simplest (or, at least, most used) solution is probably to work with curl.

If you take a look at the list of options you can set with curl_setopt, you'll see this one : CURLOPT_POSTFIELDS (quoting) :

The full data to post in a HTTP "POST" operation.
To post a file, prepend a filename with @ and use the full path.
This can either be passed as a urlencoded string like 'para1=val1&para2=val2&...' or as an array with the field name as key and field data as value.
If value is an array, the Content-Type header will be set to multipart/form-data.


Not tested, but I suppose that something like this should do the trick -- or, at least, help you get started :

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/your-destination-script.php");
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setpopt($ch, CURLOPT_POSTFIELDS, array(
        'file' => '@/..../file.jpg',    // you'll have to change the name, here, I suppose
        // some other fields ?
));
$result = curl_exec($ch);
curl_close($ch);

Basically, you :

  • are using curl
  • have to set the destination URL
  • indicate you want curl_exec to return the result, and not output it
  • are using POST, and not GET
  • are posting some data, including a file -- note the @ before the file's path.
Pascal MARTIN
I think this is going to work and i'll try this! Thanks :-)(Hey u got the same prename then me so ur answer has to be right^^)
qualle
You're welcome :-) have fun ! *(lots of people with our name, I see ^^ )*
Pascal MARTIN
+1, I didn't realize it was as simple as using the `@` symbol with PHP :-)
Andy E
A: 

Hi,

you can do it in the same way. Just this time your server who received the file first is the client and the second server is your server. Try using these:

For the webpage on the second server:

  <form>
         <input type="text" name="var1" />
         <input type="text" name="var2" />
         <input type="file" name="inputname" />
         <input type="submit" />
  </form>

And as a script to send the file on the first server:

<?php
function PostToHost($host, $port, $path, $postdata, $filedata) {
     $data = "";
     $boundary = "---------------------".substr(md5(rand(0,32000)),0,10);
     $fp = fsockopen($host, $port);

     fputs($fp, "POST $path HTTP/1.0\n");
     fputs($fp, "Host: $host\n");
     fputs($fp, "Content-type: multipart/form-data; boundary=".$boundary."\n");

     // Ab dieser Stelle sammeln wir erstmal alle Daten in einem String
     // Sammeln der POST Daten
     foreach($postdata as $key => $val){
         $data .= "--$boundary\n";
         $data .= "Content-Disposition: form-data; name=\"".$key."\"\n\n".$val."\n";
     }
     $data .= "--$boundary\n";

     // Sammeln der FILE Daten
     $data .= "Content-Disposition: form-data; name=\"{$filedata[0]}\"; filename=\"{$filedata[1]}\"\n";
     $data .= "Content-Type: image/jpeg\n";
     $data .= "Content-Transfer-Encoding: binary\n\n";
     $data .= $filedata[2]."\n";
     $data .= "--$boundary--\n";

     // Senden aller Informationen
     fputs($fp, "Content-length: ".strlen($data)."\n\n");
     fputs($fp, $data);

     // Auslesen der Antwort
     while(!feof($fp)) {
         $res .= fread($fp, 1);
     }
     fclose($fp);

     return $res;
}

$postdata = array('var1'=>'test', 'var2'=>'test');
$data = file_get_contents('Signatur.jpg');
$filedata = array('inputname', 'filename.jpg', $data);

echo PostToHost ("localhost", 80, "/test3.php", $postdata, $filedata);
?>

Both scripts are take from here: http://www.coder-wiki.de/HowTos/PHP-POST-Request-Datei

Raven