Hallo allemaal,

Ik ben aan het proberen om met curl post een file van een server naar een andere te sturen.
Mijn eerste poging was een upload.html te maken en de file naar $message te posten en dan te herposten naar een andere server, niet iets wat veel gebeurd dus.
Ik snap niet echt wat er mis ging, alles bleek erin te zitten:
array(1) {
["message"]=>
array(5) {
["name"]=>
string(11) "compare.iso"
["type"]=>
string(24) "application/octet-stream"
["tmp_name"]=>
string(14) "/tmp/phpS3TvRI"
["error"]=>
int(0)
["size"]=>
int(800)
}
}

Het enige dat niet normaal was is dat het niet in $_files zat maar dus in $message.
Dit heb ik opgegeven en ben ik met dit begonnen:

$curlUrl="http://".$ip."/uploadtest.php";
$ch = curl_init();

curl_setopt($ch,CURLOPT_URL, $curlUrl);
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, 'file='.$message);
$result = curl_exec($ch);
curl_close($ch);


Met dit krijg ik geen data aan aan de externe server, het array is leeg zegt hij, iemand een idee?
Een file uploaden via cUrl doe je (tegenwoordig) zo: https://secure.php.net/manual/en/curlfile.construct.php . Je $filename laat je dan direct naar de tmp_name van je upload wijzen (en de MIME type kun je ook overnemen).

$upload = $_FILES['upload']; //'upload' vervangen door de name van je file input
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $curlUrl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ['file' => new CURLFile($upload['tmp_name'],$upload['type'])]);
curl_exec($ch);
Ik doe nu dit:
    $fname = 'bitcoin.jpg';   
    $cfile = new CURLFile(realpath($fname));

        $post = array (
                  'file' => $cfile
                  );
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);


Als ik jou manier probeer:
curl_setopt($ch, CURLOPT_POSTFIELDS, ['file' => new CURLFile($_FILES["message"]["tmp_name"],$_FILES["message"]["type"])]);


Dan krijg ik:
(
    [file] => Array
        (
            [name] => php0rUkRZ
            [type] => 
            [tmp_name] => 
            [error] => 1
            [size] => 0
        )

)
Even een stapje terug: je hebt:
1) upload.html vanwaaruit je (via een browser) een bestand upload naar:
2) een PHP bestand dat alles weer via cUrl doorstuurt naar:
3) een andere server op $ip met uploadtest.php

Mijn code was bedoeld voor stap 2 (de tussenstap: ontvangen en weer doorsturen). Wat jij nou hierboven hebt staan doet me meer denken aan het begin van de keten (stap 1), maar dan niet vanuit een browsers, maar (ook) vanuit PHP.

Kun je de complete code die je nu voor elke stap hebt even in aparte blokken hier neer zetten? Dan kunnen we het complete plaatje zien.
upload.html:
 <form action="/index.php" method="post" enctype="multipart/form-data">
    message: <input type="file" name="message">
  <input type="submit" value="Submit">
</form>


index.php:
    $target_url = "http://$ip/uploadtest.php";           
    $fname = "image.jpg";
    $cfile = new CURLFile(realpath($fname));

        $post = array (
                  'file' => $cfile
                  );

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $target_url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");   
    curl_setopt($ch, CURLOPT_HTTPHEADER,array('Content-Type: multipart/form-data'));
    curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);   
    curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);  
    curl_setopt($ch, CURLOPT_TIMEOUT, 100);
    curl_setopt($ch, CURLOPT_POSTFIELDS, ['file' => new CURLFile($_FILES["message"]["tmp_name"],$_FILES["message"]["type"])]);

    $result = curl_exec ($ch);

    if ($result === FALSE) {
        echo "Error sending" . $fname .  " " . curl_error($ch);
        curl_close ($ch);
    }else{
        curl_close ($ch);
        echo  "Result: " . $result;
    }


uploadtest.php:
$uploaddir = realpath('./') . '/uploads/';
$uploadfile = $uploaddir . basename($_FILES['file']['name']);
echo '<pre>';
	if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
	    echo "File is valid, and was successfully uploaded.\n";
	} else {
	    echo "Possible file upload attack!\n";
	}
	echo 'Here is some more debugging info:';
	print_r($_FILES);
	echo "\n<hr />\n";
	print_r($_POST);
print "</pr" . "e>\n";




Nou, bijna goed. In index.php moet je regel 19 (zoals hierboven) uitbreiden met

    curl_setopt($ch, CURLOPT_POSTFIELDS, ['file' => new CURLFile($_FILES["message"]["tmp_name"],$_FILES["message"]["type"],$_FILES["message"]["name"])]);
Dus ook nog even de echte naam meegeven = 3e parameter.

Ik krijg dan (in de browser, dus als resultaat van upload.html POST naar index.php):
Result:
File is valid, and was successfully uploaded.
Here is some more debugging info:Array
(
    [file] => Array
        (
            [name] => atmega16u2.jpg
            [type] => image/jpeg
            [tmp_name] => E:\server\temp\upload\php92DF.tmp
            [error] => 0
            [size] => 925857
        )

)


Array
(
)
("atmega16u2.jpg" is de naam van m'n originele bestand).

Overigens kan index.php nog wel een beetje opschoning gebruiken: regel 3 t/m 7 doen niks meer, en $fname hangt er ook maar een beetje bij.
Dat had ik moeten onderzoeken, ik dacht nog waarom hij er niet bij was in jou voorbeeld.
Nee deze code is puur voor te testen en een zeer klein stuk van een groter geheel vandaar de rommel.

Het is meer proof of concept code nu.

Merci voor de hulp!

Reageren