6

I want to upload a file to a PHP form on a remote server with a certain URL. The upload form is a file upload form (Multipart/form-data), and my script should take a local file, and send it to that form.

The files are somewhat large, but the form file size limit is 1GB, which is no problem. But what is more pressing is that, due to some circumstances, I have to send the file as a stream!

This means having the file read line by line and then somehow upload it without creating a temporary file to assign via CURLOPTS_POSTFILDS.

So in short:

  • I need to use the CURLOPTS_READFUNCTION (I think) to get the contents of the file line by line
  • the method has to be POST
  • this has to simulate a regular file upload on the remote server upload form (so I guess I'd need some sort of a dummy filename for that)

I have tried a lot of ways to do this but I have failed. I am very new to cURL, I have tried a lot of info from other StackOverflow questions and other forums to no avail.

I have come to the conclusion that it might not be possible, but as I said, I have little idea of what I'm doing so I need some info or guidelines from someone more experienced. So far I think that CURLOPT_INFILE and CURLOPT_READFUNCTION are only working with PUT method, but I have to use POST.

Sorry for the long question, I hope it makes sense. And thanks in advance for any help or info.

EDIT

Here is some code as suggested:

$fh = fopen('php://memory','rw'); fwrite( $fh, $content); //maybe write the contents to memory here? rewind($fh); $options = array( CURLOPT_RETURNTRANSFER => true ,CURLOPT_SSL_VERIFYPEER => false ,CURLOPT_SSL_VERIFYHOST => 1 ,CURLOPT_FOLLOWLOCATION => 0 ,CURLOPT_HTTPHEADER => array( 'Content-type: multipart/form-data' ) ,CURLOPT_INFILE => $fh //I want to read the contents from this file ,CURLOPT_INFILESIZE => sizeof($content) ); $ch = curl_init(); curl_setopt ($ch, CURLOPT_URL, 'remote_form_url_here'); curl_setopt ($ch, CURLOPT_POST, true); $post = array( 'userfile' => '@i_do_not_have_a_file_to_put_here;filename=myfile.txt' ); curl_setopt ($ch, CURLOPT_POSTFIELDS, $post); curl_setopt_array ($ch, $options); //have the reading occur line by line when making the infile curl_setopt($ch, CURLOPT_READFUNCTION, function($ch, $fd, $length) use ($fh) { $line = fgets($fh); if ($line !== false) return $line; else return false; }); $response = curl_exec($ch); echo $response; fclose($fh); 

This code is mostly assembled from answers found around, but the parts that use the file handler do not seem to fit. I want to use a file handler, but it seems that if there is no way to confuse the form into thinking that the contents are a file and to pass some random file name.

This code does not even work (won't get to post the form at all), or some variations of it even show forbidden as a result.

Just for reference this is the test form I'm using to emulate the real situation i'm in until i make it work (don't want to send a ton of requests to the real server):

<form enctype="multipart/form-data" action="up.php" method="POST"> Send this file: <input name="userfile" type="file" /> <input type="submit" value="Send File" /> </form> 

And this is the behind code:

$target_path = "./ups/"; $target_path = $target_path . basename( $_FILES['userfile']['name']); if(move_uploaded_file($_FILES['userfile']['tmp_name'], $target_path)) { echo "The file ". basename( $_FILES['userfile']['name']). " has been uploaded"; } else{ echo "There was an error uploading the file, please try again!"; } var_dump($_FILES['userfile']); 
5
  • 1
    No it is not a duplicate, as stated before I have read these questions and they do not refer to my case. I do not want to upload the whole file at once, I already know how to do that. What I want is, as stated before, to read the file line by line (USING CURLOPTS_READFUNCTION) but preserving the method as POST!!!! EDIT: Think of it as there being no file, just a string variable, and I can't save temporary files. Or as having to use a file handler without having an actual file path. Commented Jun 19, 2013 at 15:55
  • Seeing your not-working code (even simplified) may help others to narrow down on your problem. What you are trying to do may not be possible unless you specify a valid (but dummy?) INFILE, as this appears to be passed as a streamhandler to your callback function (but you do not necessarily need to use this to read the "chunks" of data). Commented Jun 19, 2013 at 16:11
  • Doesn't look like this is possible when you don't control the receiving end. In addition, PHP does not implement 100% of curl's capabilities (ie. HTTPPOST and curl_formadd). Alternatively, you may be able to manually construct the HTTP POST request, in the way that you would like, using fsockopen. Commented Jun 19, 2013 at 20:19
  • I understand, that is well explained. But am I right into thinking that I would still need to send the whole post data at once? Commented Jun 20, 2013 at 12:09
  • Maybe. It all depends on the receiving end's implementation. You may be able to use multi-part with boundries and chunked data, but not sure. Don't think that works with apache/FastCGI but do not know. Commented Jun 20, 2013 at 20:29

1 Answer 1

1

If it works OK in the browser, you may use chrome dev tools. On Network Tab, find the post request. Right click -> Copy as cURL .

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.