Curl file upload with multipart/form-data

22,627

Solution 1

Replace this line:

$postdata = array("file[]" => "@/".realpath($file));

with:

$postdata = array("file[]" => "@/".realpath($file).";type=video/mp4");

and it should work.

Solution 2

I've used curl for connecting with a web service and upload a file using a similar idea of this post, but it didn't work. The reasons where different to the previous answer, so I will describe my solution; maybe my experience is useful to others.

I had two problems. The first one is that my web service didn't like absolute path in the filename. If $file in the OP code has a path, then using:

$postdata = array('file[]' => "@/".realpath($file));

becomes:

Content-Disposition: form-data; name="file[]"; filename="/tmp/iy56ham"

and that path generated a BAD REQUEST. So I had to use chdir, basename and dirname in order to avoid using paths in the $postdata.

On the other hand, curl sent an extra header, not shown in the OP:

Expect: 100-continue

My web service didn't like it (neither twitter WS) and it answered with a:

417 Expectation Failed

To avoid curl sending that offending header you can use:

curl_setopt( $curlHandler, CURLOPT_HTTPHEADER, array('Expect:') );

so you set an empty Expect header and curl will not overwritten with 100-continue.

Hope this help someone...

Share:
22,627
Admin
Author by

Admin

Updated on November 23, 2020

Comments

  • Admin
    Admin over 3 years

    I have a problem with the file upload with curl. I want to upload a file of my server on a video hosting site. The script needs the Content-type: multipart/form-data and Content-type: video/mp4, but I dont know how I can do it. After the upload the file have the content type application/octet-stream.

    Here is the script

    class curl
    {
             function __construct($use = 1)
             {
             $this->ch = curl_init();
                     if($use = 1)
                     {
                             curl_setopt ($this->ch, CURLOPT_POST, 1);
                             curl_setopt ($this->ch, CURLOPT_COOKIEJAR, 'cookie.txt');
                             curl_setopt ($this->ch, CURLOPT_FOLLOWLOCATION, 1);
                             curl_setopt ($this->ch, CURLOPT_RETURNTRANSFER, 1);
                     }
                     else
                     {
                             return 'There is the possibility, that this script wont work';
                     }
             }
             function first_connect($loginform,$logindata)
             {
                     curl_setopt($this->ch, CURLOPT_URL, $loginform);
                     curl_setopt($this->ch, CURLOPT_POSTFIELDS, $logindata);
             }
             function store()
             {
                     $this->content = curl_exec ($this->ch);
             }
             function execute($page)
             {
                     curl_setopt($this->ch, CURLOPT_URL, $page);
                     $this->content = curl_exec ($this->ch);
             }
             function close()
             {
                     curl_close ($this->ch);
             }
    
             function __toString()
             {
             return $this->content;
             }
    
             function upload($file)
             {
                curl_setopt($this->ch, CURLOPT_HTTPHEADER, array("Content-type: multipart/form-data"));
                curl_setopt($this->ch, CURLOPT_URL, 'http://uploadsite.com/index.php?act=files&do=upload');
                $postdata = array("file[]" => "@/".realpath($file));
                echo $postdata;
                curl_setopt($this->ch, CURLOPT_POSTFIELDS, $postdata);
                curl_exec ($this->ch);
             }
    }
    
    
    $getit = new curl();
    $getit->first_connect('http://uploadsite.com/index.php?act=login&login=true','login=true&file_session=&email=xxx%40yahoo.de&password=xxx&upload=Login');
    $getit->store();
    $getit->execute('http://uploadsite.com/index.php?act=user&do=home');
    $getit->upload('Sample.mp4');
    

    And the package from livehttpheaders

    http://uploadsite.com/index.php?act=files&do=upload
    
    POST /index.php?act=files&do=upload HTTP/1.1
    Host: yourupload.com
    User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20100101 Firefox/15.0.1
    Accept: text/javascript, text/html, application/xml, text/xml, */*
    Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    X-Requested-With: XMLHttpRequest
    Referer: http://yourupload.com/index.php?act=user&do=home
    Content-Length: 41648931
    Content-Type: multipart/form-data; boundary=---------------------------265001916915724
    Cookie: _pk_ref.9.d1ba=%5B%22%22%2C%22%22%2C1347200605%2C%22http%3A%2F%2F62.75.242.162%2Findex.php%22%5D; _pk_id.9.d1ba=08e499ca1b88c81c.1345157523.12.1347203814.1347189831.; PHPSESSID=jjajqi2mi7fe1blso5qvge9ue5; _pk_ses.9.d1ba=*; member_id=3051; member_pass=xxx
    Pragma: no-cache
    Cache-Control: no-cache
    -----------------------------265001916915724
    Content-Disposition: form-data; name="file[]"; filename="Sample.mp4"
    Content-Type: video/mp4
    
    
    HTTP/1.1 200 OK
    Server: nginx/0.7.67
    Date: Sun, 09 Sep 2012 15:23:56 GMT
    Content-Type: text/html
    Transfer-Encoding: chunked
    Connection: keep-alive
    X-Powered-By: PHP/5.3.3-7+squeeze13
    Expires: Thu, 19 Nov 1981 08:52:00 GMT
    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    Pragma: no-cache