2 votes

Le fichier Laravel téléchargé depuis AWS S3 avec Filesystem est corrompu

Je télécharge des fichiers sur Amazon S3 avec le système de fichiers Laravel. Le processus de téléchargement fonctionne très bien, mais lorsque je télécharge les fichiers sont corrompus. J'ai téléchargé manuellement les fichiers depuis le seau S3 et de cette façon les fichiers ne sont pas corrompus, donc j'ai pensé que le problème n'était pas le téléchargement.

Je télécharge les fichiers comme suit :

/**
 * Upload the file to Amazon S3.
 *
 * @param UploadedFile $file
 * @param $path
 * @return $this|bool
 */
protected function upload(UploadedFile $file, $path)
{
    $this->filename = $path . '/' . time() . '_' . str_replace(' ', '-', $file->getClientOriginalName());

    $disk = Storage::cloud();

    if ($disk->put($this->filename, fopen($file, 'r+'))) {

        $this->save();

        return $this;
    }

    return false;
}

Et pour le téléchargement, j'ai essayé ceci :

/**
 * @param Document $document
 * @return Response
 */
public function download(Document $document)
{
    $file = Storage::cloud()->get($document->path);

    $file_info = new finfo(FILEINFO_MIME_TYPE);

    return response($file, 200)->withHeaders([
        'Content-Type'        => $file_info->buffer($file),
        'Content-Disposition' => 'inline; filename="' . $document->name . '"'
    ]);
}

Et ceci :

/**
 * @param Document $document
 * @return Response
 */
public function download(Document $document)
{
    $stream = Storage::cloud()->getDriver()->readStream($document->path);

    $file = stream_get_contents($stream);

    $file_info = new finfo(FILEINFO_MIME_TYPE);

    return response($file, 200)->withHeaders([
        'Content-Type'        => $file_info->buffer($file),
        'Content-Disposition' => 'inline; filename="' . $document->name . '"'
    ]);
}

Avec les deux fonctions de téléchargement, j'obtiens les fichiers, mais ils sont corrompus. Toute aide est la bienvenue !

3voto

enriqg9 Points 781

Le problème était que le tampon de sortie contenait un espace blanc. L'utilisation de ob_end_clean() avant de renvoyer la réponse a résolu le problème, mais si l'on trouve un espace blanc dans un fichier avant l'ouverture de l'élément <?php il n'était pas nécessaire d'utiliser la balise ob_end_clean() .

Voici le code sans utiliser d'url présignée :

/**
 * Download document from S3.
 *
 * @param Document $document
 * @return Response
 */
public function download(Document $document)
{
    $s3Client = Storage::cloud()->getAdapter()->getClient();

    $stream = $s3Client->getObject([
        'Bucket' => 'bucket',
        'Key'    => $document->path
    ]);

    return response($stream['Body'], 200)->withHeaders([
        'Content-Type'        => $stream['ContentType'],
        'Content-Length'      => $stream['ContentLength'],
        'Content-Disposition' => 'inline; filename="' . $document->name . '"'
    ]);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X