webspirit
asked on
php chunked encoding post with curl (multipart/formdata)
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.
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);
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
ASKER
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--
Yes every variable you're sending needs to be urlencoded if the form's enctype is application/x-www-form-url encoded 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);
ASKER
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.
Thank you.
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',
);
ASKER
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=----------------- ---------- -b64cdfea8 248
Could you please test it? The form is live at http://85.17.135.223/test.php
Thank you.
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=-----------------
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);
ASKER
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.
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.
ASKER
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>
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.