开发者

Upload File via RESTful API?

I was trying to make an RESTful API call to upload videos through POST method. What I am lacking is that I don't know the best practices for writing this kind of API as well I don't find any resource on the internet to follow. Right now I am doing this:

I am working in PHP and zend framework ( Zend_Rest_Route ).

First approach:

using file_get_contents on client side and POST it to API using curl, and on server side using file_put_contents to write that data and sending an appropriate response.

Second:

using Zend_File_Treansfer to receive file at server side, and putting address of my upload api end point in zend_form with setting method as post. In this case file is uploaded to server, but after submitting the form, the url in address bar points to the api server and never comes back to the form.

Am I doing it right?, if not do let me know wh开发者_如何学编程at are the best practices and how to accomplish this.

Thank you for your time.


Something like this worked for me:

public function postAttachment($fileName, $fileMimetype, $fileContents, $postURL, $username, $password) 
{
    $auth = base64_encode($username . ':' . base64_decode($password));
    $header = array("Authorization: Basic ".$auth);
    array_push($header, "Accept: */*");     
    $boundary =  "----------------------------".substr(md5(rand(0,32000)), 0, 12); 

    $data = ""; 
    $data .= "--".$boundary."\r\n"; 

    //Collect Filedata          
    $data .= "Content-Disposition: form-data; name=\"file\"; filename=\"".$fileName."\"\r\n"; 
    $data .= "Content-Type: ".$fileMimetype."\r\n"; 
    $data .= "\r\n";
    $data .= $fileContents."\r\n"; 
    $data .= "--".$boundary."--";
    // add more parameters or files here

    array_push($header, 'Content-Type: multipart/form-data; boundary='.$boundary);
    $params = array('http' => array( 
       'method' => 'POST', 
       'protocol_version' => 1.1, 
       'user_agent' => 'File Upload Agent',
       'header' => $header, 
       'content' => $data 
    )); 
   $ctx = stream_context_create($params); 
   $fp = fopen($postURL, 'rb', false, $ctx); 

   if (!$fp) { 
      throw new Exception("Problem with ".$postURL." ".$php_errormsg); 
   } 
   $responseBody = @stream_get_contents($fp); 
   if ($responseBody === false) { 
      throw new Exception("Problem reading data from ".$postURL.", ".$php_errormsg); 
   } 
}

If you want to post several files, or add other multi-part parameters, it's easy to add these in other boundaries too.

I found some of this code on another post, and you can probably find similar code in the PHP wiki (http://www.php.net/manual/en/function.stream-context-create.php#90411). BUT ... That code was not properly handling the carriage return + line feeds and my server was summarily rejecting that post. In addition, that the older code was also using HTTP version 1.0 -- (which does not re-use sockets). When using HTTP 1.1 sockets are re-used when posting lots of files. (This works with HTTPS too.) I added my own user agent - If your are tricking some server into thinking this is a browser post, you might want to change the user agent to spoof a browser.


have you tried adding a redirect to end of your controller action that handles the upload? (if not you really should as its good practice to redirect after post) (make sure you redirect AFTER your logic has executed). In essence the 'page' that receives the post data should just work on the data, and any information you want to return to the user about that post action should be given to them on the page you redirect them to.

[form]--POST-->['post' controller action]--redirect (302)-->[page with success/failure info]

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜