2010-03-02 4 views
3

J'ai un répertoire d'images qui sont alternativement affichées directement dans le navigateur, et d'autres fois téléchargées.Comment réécrire et définir les en-têtes en même temps dans Apache

Donc, disons que j'ai un fichier /gallery/gal_4254.jpg.

Je veux faire /download/gal_4254.jpg déclencher un téléchargement de l'image plutôt que de l'afficher./le téléchargement est vide, toutes les images sont dans/gallery.

Je peux orienter les requêtes vers le téléchargement dir aux autres fichiers avec succès

<Directory /var/www/download> 
    RewriteEngine on 
    RewriteRule (.*)$ /gallery/$1 
</Directory> 

et je peux déjà forcer les téléchargements dans la galerie dir en mettant

<Directory /var/www/gallery/> 
    ForceType "image/jpg" 
    Header set Content-Disposition "attachment" 
</Directory> 

réglage de sorte que les en-têtes est pas un problème . Je ne veux pas que/gallery ait les en-têtes, seulement les requêtes pour/gallery/* à travers/download/qui sont réécrites.

Mais, j'ai besoin de combiner les deux, de sorte que la demande est mappée au fichier dans l'autre répertoire ET le fichier est donné l'en-tête de la pièce jointe. J'ai essayé de changer l'ordre des sections de réécriture et d'en-tête en vain. Je pense qu'il perd l'en-tête lorsque la demande est réécrite dans l'autre répertoire.

Des suggestions sur la façon de faire cela dans Apache?

Je réalise que cela pourrait aussi être fait avec PHP, c'est pourquoi je l'ai posté ici par rapport à Server Fault. Une solution utilisant PHP serait la bienvenue aussi.

Répondre

2

solution simple php:

download.php

header('Content-Type: image/jpeg'); 
header('Content-Disposition: attachment; filename='.$_GET['img']); 
readfile('gallery/'.$_GET['img']); 

.htaccess

<Directory /var/www/download> 
    RewriteEngine on 
    RewriteRule (.*)$ /download.php?img=$1 
</Directory> 
2

Une solution combinée pourrait être la configuration suivante. Premier changement l'entrée du répertoire:

<Directory /var/www/download> 
    RewriteEngine on 
    RewriteRule (.*)$ download.php?getfile=$1 
</Directory> 

Le download.php doit contenir quelque chose comme ça (NON TESTÉ):

<?php 

if ($_GET['getfile']){ 
    $file = '/var/www/gallery/' . $_GET['getfile']; 
} 

$save_as_name = basename($file); 
header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
header('Pragma: no-cache'); 
header("Content-Type: application/octet-stream"); 
header("Content-Disposition: disposition-type=attachment; filename=\"$save_as_name\""); 

readfile($file); 
?> 

Cette shouldd rediriger toutes les requêtes de téléchargement à download.php qui gère la tour demande et force le dialogue des saveas à apparaître.

Paul

+0

Merci! Puisque vous et xaoc donniez à peu près la même réponse à 2 minutes d'intervalle, j'ai lancé une pièce et xaoc a obtenu l'acceptation. Vous avez néanmoins mon upvote reconnaissant. – JAL

1

Je viens de faire cela, après avoir trébuché sur votre exemple ;-) Je suis sûr que vous avez juste à changer votre "Directory/var/www/download "section à un" Emplacement/téléchargement "dans votre dernier exemple et vous êtes OK. Raison: «Directory» s'applique au répertoire physique résultant, APRÈS que les réécritures ont eu lieu, alors que «Location» s'applique à l'URI d'origine, peu importe que des réécritures aient eu lieu pour trouver le fichier physique.

Comme mod_rewrite est un énorme hack qui s'applique à divers moments, l'effet de votre code n'est pas très évident.

Ce que j'ai dans ma configuration workjing est:

<Location /contents/> 
    Header set Content-Disposition "attachment" 
</Location> 
... 
RewriteRule ^.*(/e-docs/.*)$ $1 

Ainsi, les URL comme /contents/myimage.jpg ET /contents/e-docs/myimage.jpg les deux obtiennent l'en-tête Content-Disposition, même si /contents/e-docs/myimage.jpg est en fait le fichier /e-docs/myimage.jpg, comme le dit la réécriture. Éviter PHP pour cela a l'avantage supplémentaire que vous pouvez servir ces images et les fichiers vidéo potentiellement énormes (comme dans mon cas) avec un serveur Apache statique léger, pas un processus back-end PHP de mémoire-hog.

+0

Bonne approche, merci d'ajouter cela. J'aimerais faire cela sans PHP, d'autant plus que cela semble être un problème qui devrait être entièrement résolu avec Apache. – JAL

Questions connexes