muuucho's avatar
Level 11

Can't display images from remote server using SFTP

$invoices holds one file name. This file i stored on a remote server named sftp. The settings in .env for this server are correct. I know that since I have another script that successfully uploads files to the remote server using those credentials.

My view:

@foreach($invoices as $invoice)
                Image: <img src="{{ route('image', ['filename' => 'thumbnails/'.$invoice->file_name_thumbnail ]) }}" alt="">
            @endforeach

Route:

    Route::get('/image/show/{filename?}', [ImageController::class, 'show'])->where('filename', '(.*)')->name('image');

ImageController:

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Storage;
use Illuminate\Http\Request;

class ImageController extends Controller
{
    public function show($filename)
    {
        $extension = pathinfo($filename, PATHINFO_EXTENSION);
        #$extension = 'pdf';
        $disk = Storage::disk('sftp');
        if ($disk->exists($filename)) {
            \Log::info('exists');
            return response()->stream(function () use ($disk, $filename) {
                echo $disk->get($filename);
            }, 200, [
                'Content-Type' => 'image/'.$extension,
                'Content-Disposition' => 'inline; filename="' . $filename . '"',
            ]);
        }
        abort(404);
    }
}

The word exists gets written to the log file. When I inspect the code inte browser, the url goes to

<img src="http://my-local-server/image/show/thumbnails/H2txUyQwvc5aMgtrY6KU7Y8e3JSjxeMSXkeDktM4.jpg" alt="">

And in my remote server this file exists in the folder thumbnails and the file name is correct. So, why doesn't the image shows as expected?

0 likes
4 replies
LaryAI's avatar
Level 58

The issue you're facing is likely related to the Content-Type header in your response. The pathinfo function is used to determine the file extension, but it might not always return the correct MIME type for the image. Additionally, if the file extension is not recognized, the browser might not display the image correctly.

Here's a solution to ensure the correct MIME type is used:

  1. Use the mime_content_type function to determine the correct MIME type of the file.
  2. Ensure that the SFTP disk is correctly configured in your config/filesystems.php and .env file.

Here's how you can modify your ImageController:

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Storage;
use Illuminate\Http\Request;

class ImageController extends Controller
{
    public function show($filename)
    {
        $disk = Storage::disk('sftp');
        if ($disk->exists($filename)) {
            \Log::info('exists');
            $fileContent = $disk->get($filename);
            $tempFilePath = tempnam(sys_get_temp_dir(), 'image');
            file_put_contents($tempFilePath, $fileContent);
            $mimeType = mime_content_type($tempFilePath);
            unlink($tempFilePath);

            return response()->stream(function () use ($fileContent) {
                echo $fileContent;
            }, 200, [
                'Content-Type' => $mimeType,
                'Content-Disposition' => 'inline; filename="' . $filename . '"',
            ]);
        }
        abort(404);
    }
}

Explanation:

  • Temporary File: We create a temporary file to determine the MIME type using mime_content_type. This function reads the file's content to determine its type, which is more reliable than using the file extension.
  • MIME Type: The correct MIME type is set in the Content-Type header, ensuring the browser can render the image properly.
  • Cleanup: The temporary file is deleted after determining the MIME type to avoid cluttering the server with temporary files.

Make sure your SFTP configuration in config/filesystems.php and .env is correct and that the server has the necessary permissions to access the files. This should resolve the issue and allow the images to be displayed correctly.

azimidev's avatar
azimidev
Best Answer
Level 55

can you try this modified verion

1 like
muuucho's avatar
Level 11

@azimidev Thanks, the problem is that the uploaded file is have the wrong MIME type: [2024-10-20 08:10:26] local.INFO: File exists on SFTP server: thumbnails/H2txUyQwvc5aMgtrY6KU7Y8e3JSjxeMSXkeDktM4.jpg
[2024-10-20 08:10:26] local.INFO: MIME Type: text/plain

Please or to participate in this conversation.