We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

php chunked encoding post with curl (multipart/formdata)

webspirit
webspirit asked
on
Medium Priority
7,605 Views
Last Modified: 2012-05-07
Hi,

I want to submit a form that is multipart/form-data
I try do do it with curl but I get a status 100 response form the server.

Here 's part of the headers:
Accept-Charset: utf-8, utf-16, *;q=0.1 Pragma: no-cache Cache-Control: no-cache Connection: Keep-Alive Transfer-Encoding: chunked Content-Type: multipart/form-data Expect: 100-continue

How can I make it work?

Thank you.
$agent = "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)";
	
	$header = array (
		'Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1',
		'Accept-Language: en,el-GR;q=0.9,el;q=0.8',
		'Accept-Charset: utf-8, utf-16, *;q=0.1',
	 	'Pragma: no-cache',
		'Cache-Control: no-cache',
		'Connection: Keep-Alive',
		'Transfer-Encoding: chunked',
		'Content-Type: multipart/form-data'
		
	);
 
		curl_setopt($ch, CURLOPT_COOKIE, $cookie);
		curl_setopt($ch, CURLOPT_USERAGENT, $agent);
		//curl_setopt($ch, CURLOPT_HEADER, 1);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
	 	curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); 
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,  2);
		curl_setopt($ch, CURLOPT_URL, $url); 
		curl_setopt($ch, CURLINFO_HEADER_OUT, true);
//This is for cookie handling.
		curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
		$result = curl_exec ($ch);
		echo curl_error($ch);
		$info = curl_getinfo($ch);

Open in new window

Comment
Watch Question

Ionut A. TudorPHP Programmer
CERTIFIED EXPERT

Commented:
Why are you using multipart/form-data ? The server gives you status 100 because it expects the data. Multipart/form-data is used for uploading files to web server so if you're not sending any data use simple Content-Type: text/plain

Author

Commented:
I tried but it didn't work. I 've captured the headers from the browser with Fiddler and I 'm trying to replicate that. Is there an option for curl to actually do the chunked data enconding itself? I am passing the post data as an assosiative array like it would be in a urlencoded form. Do I have to do the chunked encoding manually?


POST /something HTTP/1.1
User-Agent: Opera/9.80 (Windows NT 6.0; U; en) Presto/2.2.15 Version/10.00
Host: somehost
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: el-GR,el;q=0.9,en;q=0.8
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
Cookie: somecookies
Cookie2: $Version=1
Connection: Keep-Alive, TE
TE: deflate, gzip, chunked, identity, trailers
Content-Length: 2769
Content-Type: multipart/form-data; boundary=----------dQD6HRmfxrxw49A4m8uERh
 
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="postingKey"
 
SUvjkFNX7Ox53xu9
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="test"
 
OCcOh
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="U2FsdGVkX.183MTQyN:zE0MrhLOmUpqd3eL60xF19RmCzgs.XkMel5uouI-FnsR6LV0MQXrAwjIYAc"
 
demo
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="U2FsdGVkX183MTQyNz:E0MmzCsvWniexbzefYS2M.EgNq7gj:A:ChbO9Ug"
 
1
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="U2FsdGVkX1.83MTQyNzE0MgO7JImRbH7:sehcm.TqM2j.myOIUUZk8KD4A1mSPtghVxQa4iiy0zewJY"
 
11
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="U2FsdGVkX183MTQyNzE0MmmuIJgGIu2mcNuasDm19ghQU6bL_9qi8qqdEitEQ_3F"
 
some@test.com
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="U2FsdGVkX183MTQyNzE0MiDJurEL5R3MqyRqtqldkWMO6r4WSng1mWnKrdsLlXBv"
 
C
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="U2FsdGVkX183MTQyNzE0Mu-m2scEHi44PSRcp77KH3Ezz49IaB_Z89kFyYE08lt3PbA8JhDDMvk"
 
U2FsdGVkX183MTQyNzE0MvCYST-W4nASMwlt1CSfwR9wk0kEQRr6EDBqxe_cKs1tJZRn4gtwcqM
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="U2FsdGVkX183MTQ.yNzE0MuvRtnZjnOoER2Wrx0WjFPZP-1vTNLkdq7zW:_LB_ujWFK3nLoHwhLSM"
 
U2FsdGVkX183MTQyNzE0MmWorycRBYg5ba_juOUQ-y3Ociu-J8LrSHR8potuzeuc
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="U2FsdGVkX183MTQyNzE0MtBwYuxmp6mwk.H3N3KFHGrd6dDDwB7YwlaBh78hB2fZC"
 
ds
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="image1"
 
add
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="imgfile1"; filename=""
 
 
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="image2"
 
add
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="imgfile2"; filename=""
 
 
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="image3"
 
add
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="imgfile3"; filename=""
 
 
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="image4"
 
add
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="imgfile4"; filename=""
 
 
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="U2FsdGVkX183MTQyNzE0Mu-m2scEHi44PSRcp77KH3Ezz49IaB_Z89kFyYE08lt3V1YyrFApuQ8"
 
U2FsdGVkX183MTQyNzE0MvCYST-W4nASMwlt1CSfwR9wk0kEQRr6EDBqxe_cKs1tt3N92akbEm4
------------dQD6HRmfxrxw49A4m8uERh
Content-Disposition: form-data; name="U2Fsd:.GVkX183MTQyNzE0MmWorycRBYg5XFIlxjF:D5DBBqA2R9Jzbqzk88G:q2R77y"
 
Continue
------------dQD6HRmfxrxw49A4m8uERh--

Open in new window

Ionut A. TudorPHP Programmer
CERTIFIED EXPERT

Commented:
Yes every variable you're sending needs to be urlencoded if the form's enctype is application/x-www-form-urlencoded which is the default one. In your case if its multipart/form-data then cURL has its own way to send the file contents. Add the below options it should work
// $post variable needs to contain the local file path that you want to upload
$post = array 
( 
    'type' => 'direct', 
    'userfile[]' => '@C:\full\path\file.txt',
); 
 
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);

Open in new window

Author

Commented:
The form contains 10 inputs out of which 4 are files and the rest are normal (text). The files are optional (images). So, do I need to put in the array 4 empty files? And how should I pass the other 6 text variables this way? Make a file for each variable?

Thank you.
Ionut A. TudorPHP Programmer
CERTIFIED EXPERT

Commented:
You just add their local file path like this:

$post = array 
( 
    'type' => 'direct', 
    'userfile[]' => '@C:\full\path\file.txt',
    'userfile[]' => '@C:\full\path\file.jpg',
    'userfile[]' => '@C:\full\path\file2.jpg',
    'userfile[]' => '@C:\full\path\file3.jpg',
); 

Open in new window

Author

Commented:
I made a simple form for test purposes. Then I made a php script based on your suggestions.
I still can't make it work :(
It returns nothing and the headers are:

POST /test.php HTTP/1.1 Host: 85.17.135.223 Accept: */* Content-Length: 10448 Expect: 100-continue Content-Type: multipart/form-data; boundary=----------------------------b64cdfea8248

Could you please test it? The form is live at http://85.17.135.223/test.php

Thank you.

// The html form
 
<html>
<body>
<form>
<input type="text" name="a" value="value1" />
<input type="file" name="file1" />
<input type="submit" /> 
</form>
</body>
 
// The actual code for the php script.
$url = 'http://85.17.135.223/test.php';
$file = getcwd().'/'.'step3.php';
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); 
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('type' => 'direct', 'file1'=>"@$file", 'value1'=>'aaaaa1'));
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
$result = curl_exec ($ch);
echo curl_error($ch);
$info = curl_getinfo($ch);
var_dump($info);

Open in new window

Author

Commented:
I just noticed there was an minor error, but it did not had any effect.

This
curl_setopt($ch, CURLOPT_POSTFIELDS, array('type' => 'direct', 'file1'=>"@$file", 'value1'=>'aaaaa1'));

should be replaced by
curl_setopt($ch, CURLOPT_POSTFIELDS, array('type' => 'direct', 'file1'=>"@$file", 'a'=>'aaaaa1'));

Also, I did check the file path, it is correct.

Author

Commented:
Also, forgot to mention the full code for the test.php file
<?php
 
if (!empty($_REQUEST)) {
	var_dump ($_REQUEST);
}
 
?>
 
<html>
<body>
<form>
<input type="text" name="a" value="value1" />
<input type="file" name="file1" />
<input type="submit" /> 
</form>
</body>

Open in new window

PHP Programmer
CERTIFIED EXPERT
Commented:
Unlock this solution with a free trial preview.
(No credit card required)
Get Preview
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a free trial preview!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.