web-dev-qa-db-fra.com

Ignorer l'encodage json dans api de repos

J'essaie de créer un plugin de téléchargement sécurisé.

J'ai trouvé l'api de repos la meilleure option pour cette tâche, mais je ne peux pas changer d'en-tête comme Content-Type:. Dans le rappel register_rest_route, ces en-têtes sont déjà définis. Si je mets Content-disposition: attachment, filename=asd.txt je reçois ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION en chrome.

Je sais que le repos n’est pas destiné à gérer ces tâches, mais je n’ai trouvé aucune alternative. S'il y en a, merci de m'en parler.

Les données téléchargées semblent être au format JSON.

J'en ai marre de wordpress "magic". Ces tâches seraient si faciles à utiliser avec PHP mais _ wordpress ne fait que compliquer les choses.

S'il vous plaît quelqu'un me dit comment désactiver ces en-têtes magiques *** ou me recommander un moyen de téléchargements sécurisés (php) dans mon plugin.

(Non, je ne veux pas utiliser de plugins tiers. J'ai essayé plusieurs d'entre eux. Aucun d'entre eux n'a fonctionné jusqu'ici ...: D Tout ce wordpress est un énorme pas en arrière après Symfony ...)

Voici mon expérimental code:

add_action('rest_api_init', function() {
    register_rest_route('secure-downloads/v1', '/download/(?P<filename>.*)', 
    array(
        'methods' => 'GET',
        'callback' => 'secure_downloads_handle_download'
    ));
});
function secure_downloads_handle_download(WP_REST_Request $request)
{
    $filename = urldecode($request->offsetGet('filename'));
    if(strpos($filename, '/..'))
    {
        return new WP_REST_Response('', 403);
    }
    $path = SECURE_DOWNLOADS_UPLOAD_DIR . $filename;
    return new WP_REST_Response(file_get_contents($path), 200, array(
        'Content-Type' => 'application/octet-stream',
        'Content-Transfer-Encoding' => 'Binary',
        'Content-disposition' => 'attachment, filename=\\' . $filename . '\\'
    ));
}
2
Jumi

Voici ce que j'ai découvert:

L'erreur ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION était la mauvaise composition de l'en-tête Content-Disposition. Voici le bon:

array(
    'Content-Disposition' => 'attachment; filename="' . $filename . '"'
)

Notez le point-virgule après l'attachement, le guillemet double autour du nom du fichier et le majuscule D dans le mot de disposition comme @ Tom J Nowell l'a souligné.

Cela résout le problème des en-têtes mais le WP_REST_Response génère toujours les fichiers tels qu’ils ont été codés JSON. Alors je suis allé à la manière conventionnelle:

header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Type: application/octet-stream');
readfile($path);
exit;
0
Jumi

Il devrait suffire d'ajouter le champ de disposition du contenu.

Mais plus précisément, il s’agit de Content -Disposition et non de contenu - d isposition

J'ajouterais également une validation à votre paramètre de nom de fichier qui est passé à file_get_contents pour s'assurer qu'il existe et qu'il est valide. Sinon, vous pourriez être vulnérable aux attaques de traversée de répertoire ou aux demandes d'URL à distance

1
Tom J Nowell