Luracast / Restler

Simple and effective multi-format Web API Server to host your PHP API as Pragmatic REST and/or RESTful API
http://luracast.com/products/restler/
GNU Lesser General Public License v2.1
1.36k stars 315 forks source link

Download a file #639

Closed kaizirlewagen closed 4 years ago

kaizirlewagen commented 4 years ago

Using version 3.1.0.

I try to downlad a "server" file throug an api call.

i use this class ...

function getPDF() {           
  $file = $_SERVER['DOCUMENT_ROOT'].'api/cache/'.'example.pdf';

  header('Content-Description: File Transfer');
  header('Content-Type: application/octet-stream');
  header('Content-Disposition: attachment; filename='.basename($file));
  header('Expires: 0');
  header('Cache-Control: must-revalidate');
  header('Pragma: public');
  header('Content-Length: ' . filesize($file));
  ob_clean();
  flush();
  readfile($file);
  die();
}

The download link will be shown at swagger ui, but if i download the file, the file is corrupt or i get an empty pdf file.

Has somebody a download file solution with Restler?

Thx.

Arul- commented 4 years ago

Can you try returning the string $file first and see if it is pointing to the pdf properly?

kaizirlewagen commented 4 years ago

$file contains the valid path to the example.pdf file. The file exists and is valid.

The download link which is shown through the restler api, contains a "valid" pdf file, but an "white paged" pdf file. And not my pdf file from the filesystem.

Arul- commented 4 years ago

Attached a tested and working example _017_download.zip

Basically here is what is needed

index.php

<?php

require_once '../../../vendor/restler.php';

use Luracast\Restler\PassThrough;
use Luracast\Restler\Restler;

PassThrough::$mimeTypes['pdf']='application/pdf';

$r = new Restler();
$r->addAPIClass('Document');
$r->handle();

And the Document class

<?php

use Luracast\Restler\PassThrough;

class Document
{
    function download()
    {
        PassThrough::file('sample.pdf', true);
    }
}

calling document/download triggers the download

Take a look at PassThrough class to understand how it works!

HTH Arul

kaizirlewagen commented 4 years ago

Thank you for the example!

It works ... but only if i call the api function directly through document/download with the browser.

If i try to use the api function through the explorer, then the file is not valid anymore. Without the explorer it is ok.

kaizirlewagen commented 4 years ago

I check also "my" downloader version (which is not so smart like the restler version), it works also through the direct call.

It looks like the problem will be located in the explorer.

Arul- commented 4 years ago

That's a bug in Swagger. Just add a description to your API method to tell the users to use download directly.

This will show up in swagger UI so users will know!

igorsantos07 commented 3 years ago

I guess that example 17 is still missing from the docs site? :) Could be handy at #648, glad I stumbled upon it by accident haha

Edit: maybe not, since I'm at 3.0.0 and that class isn't present yet. I guess it was silently introduced at v3.1? I found no mention of it in the release notes from GitHub... 3.1 seems like a bugfix release. Anyhow, I was going to upgrade but the class doesn't cater for files generated on-the-fly either. It seems the idea is just to cover what the HTTP server would normally do, but from inside the API?