0
Answered

Upload File via API

prondeaux 2 years ago updated by Vlad R 2 years ago 7

Hi!

I can't figure out how to upload a file via the API.
Here is the function I'm using in PHP:

public function uploadFile($access_token, $username, $filename, $cfile, $localPath)
    {
        // header
        $headr = [];
        $headr[0] = 'Content-Type: multipart/form-data';
        $headr[1] = 'Authorization: Bearer '.$access_token;
        $headr[2] = 'Content-Disposition: form-data; name="file"; filename="'.$filename.'"';
        $c = curl_init();
        curl_setopt($c, CURLOPT_URL, 'http://localhost/filerun/api.php/files/upload/?path=/ROOT/HOME/users/'.$username.'/'.$filename);
        curl_setopt($c, CURLOPT_HTTPHEADER, $headr);
        curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($c, CURLOPT_CUSTOMREQUEST, "PUT");
        curl_setopt($c, CURLOPT_POSTFIELDS, [
            'file' => $cfile,
        ]);
        curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
        $resp = curl_exec($c);
        curl_close($c);
    }


$cfile contains a curl_file.
This function works with a .pdf file but not with any other type (ex: .jpg, .png)


I tried out with a .txt and here is the result I obtain in filerun:

--------------------------91f363b335b04e0b
Content-Disposition: form-data; name="file"; filename="test.txt"
Content-Type: text/plain


Ceci est un fichier .txt de test
--------------------------91f363b335b04e0b--


while I just wrote in my file:


"Ceci est un fichier .txt de test"


but as mentioned in the doc:


Example

curl -X PUT --header "Authorization: Bearer neY6uAjKO1KqQh98RZZ5DOgYjIPMuu9duvvHGUiN" -T your-file.ext https://demo.filerun.co/api.php/files/upload/?path=/ROOT/HOME/make-new-folder/my-file.ext
  • neY6uAjKO1KqQh98RZZ5DOgYjIPMuu9duvvHGUiN - is the previously received “access_token”
  • your-file.ext - is the path of the file you want to upload from the local computer
  • https://demo.filerun.co - is the URL of your FileRun installation
  • /ROOT/HOME/make-new-folder/my-file.ext - is the remote path where you wish the file to be uploaded. FileRun will create the folder “make-new-folder” if it doesn't already exist.


I tried to replace :

curl_setopt($c, CURLOPT_POSTFIELDS, [
            'file' => $cfile,
        ]);

with:

curl_setopt($c, CURLOPT_POSTFIELDS, [
            'file' => $localPath,
        ]);

And it didn't work neither.


Is there anyone having an idea on how to resolve this? That would be so nice!




PS: It's also mentioned in the doc that I could use 

?path=/ROOT/HOME/make-new-folder/my-file.ext

But the make-new-folder is never created and triggers error:

{
    "success": false,
    "error": "The destination folder no longer exists!"
}


Cheers!



Answer

Answer

Well I figured it out!

So I was actually using a PUT request as mentionned in the doc:

curl_setopt($c, CURLOPT_CUSTOMREQUEST, "PUT");


I replaced this line by this one in order to make a POST request and it worked:

curl_setopt($c, CURLOPT_POST, 1);


Here is a working example using PHP cURL. Maybe it could help someone:


public function uploadFile($access_token, $username, $filename, $cfile)
    {
        // header
        $headr = [];
        $headr[0] = 'Content-Type: multipart/form-data';
        $headr[1] = 'Authorization: Bearer '.$access_token;
        $headr[2] = 'Content-Disposition: name="file"; filename="'.$filename.'"';
        $c = curl_init();
        curl_setopt($c, CURLOPT_URL, 'http://localhost/filerun/api.php/files/upload/?path=/ROOT/HOME/users/'.$username.'/'.$filename);
        curl_setopt($c, CURLOPT_HTTPHEADER, $headr);
        curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($c, CURLOPT_POST, 1);
        curl_setopt($c, CURLOPT_POSTFIELDS, [
            'file' => $cfile,
        ]);
        curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
        $resp = curl_exec($c);
        curl_close($c);
    }


Thanks Vlad for "putting" me on the correct track!

Under review

The "upload" API method will not create folders if they do not exist on the server, so you need to make sure the remote path is valid. I have now corrected the documentation on this.

You say the upload works for PDF files, what is the server/FileRun HTTP response when you try to upload something else?


If I send a pdf or another type of file I receive the same response:

{
    "success": true,
    "error": false,
    "data": []
}

In any case the file uploaded appears in filerun but images can't be opened and texts contains extra information. Only .pdf are opened correctly.


If I drag and drop those same files directly into the filerun interface, it works fine.

What's the "extra information" you see in text files?

For example, I uploaded a file containing this line of text:

Ceci est un fichier .txt de test



After uploading it via curl, it now shows this:


--------------------------91f363b335b04e0b
Content-Disposition: form-data; name="file"; filename="test.txt"
Content-Type: text/plain
Ceci est un fichier .txt de test
--------------------------91f363b335b04e0b--


Looks like your request is a multipart request. Your code is probably missing setting the request as HTTP PUT instead of POST.

Answer

Well I figured it out!

So I was actually using a PUT request as mentionned in the doc:

curl_setopt($c, CURLOPT_CUSTOMREQUEST, "PUT");


I replaced this line by this one in order to make a POST request and it worked:

curl_setopt($c, CURLOPT_POST, 1);


Here is a working example using PHP cURL. Maybe it could help someone:


public function uploadFile($access_token, $username, $filename, $cfile)
    {
        // header
        $headr = [];
        $headr[0] = 'Content-Type: multipart/form-data';
        $headr[1] = 'Authorization: Bearer '.$access_token;
        $headr[2] = 'Content-Disposition: name="file"; filename="'.$filename.'"';
        $c = curl_init();
        curl_setopt($c, CURLOPT_URL, 'http://localhost/filerun/api.php/files/upload/?path=/ROOT/HOME/users/'.$username.'/'.$filename);
        curl_setopt($c, CURLOPT_HTTPHEADER, $headr);
        curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($c, CURLOPT_POST, 1);
        curl_setopt($c, CURLOPT_POSTFIELDS, [
            'file' => $cfile,
        ]);
        curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
        $resp = curl_exec($c);
        curl_close($c);
    }


Thanks Vlad for "putting" me on the correct track!