3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
6 * Copyright (c) 2001-2014 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
13 if (!defined('_ECRIRE_INC_VERSION')) return;
15 include_spip('inc/headers');
17 // acces aux documents joints securises
18 // verifie que le document est publie, c'est-a-dire
19 // joint a au moins 1 article, breve ou rubrique publie
21 // http://doc.spip.org/@action_acceder_document_dist
22 function action_acceder_document_dist() {
23 include_spip('inc/documents');
25 // $file exige pour eviter le scan id_document par id_document
26 $f = rawurldecode(_request('file'));
27 $file = get_spip_doc($f);
28 $arg = rawurldecode(_request('arg'));
30 $status = $dcc = false;
31 if (strpos($f,'../') !== false
32 OR preg_match(',^\w+://,', $f)) {
35 else if (!file_exists($file) OR !is_readable($file)) {
38 $path = set_spip_doc($file);
39 $path2 = generer_acceder_document($f, $arg);
40 $where = "(documents.fichier=".sql_quote($path)
41 . ' OR documents.fichier=' . sql_quote($path2) . ')'
42 . ($arg ?
(" AND documents.id_document=".intval($arg)) : '');
44 $doc = sql_fetsel("documents.id_document, documents.titre, documents.fichier, types.mime_type, types.inclus, documents.extension", "spip_documents AS documents LEFT JOIN spip_types_documents AS types ON documents.extension=types.extension",$where);
49 // ETag pour gerer le status 304
50 $ETag = md5($file . ': '. filemtime($file));
51 if (isset($_SERVER['HTTP_IF_NONE_MATCH'])
52 AND $_SERVER['HTTP_IF_NONE_MATCH'] == $ETag) {
53 http_status(304); // Not modified
56 header('ETag: '.$ETag);
60 // Verifier les droits de lecture du document
61 // en controlant la cle passee en argument
63 include_spip('inc/securiser_action');
64 $cle = _request('cle');
65 if (!verifier_cle_action($doc['id_document'].','.$f, $cle)) {
66 spip_log("acces interdit $cle erronee");
75 include_spip('inc/minipres');
81 include_spip('inc/minipres');
82 echo minipres(_T('erreur').' 404',
83 _T('info_document_indisponible'));
87 header("Content-Type: ". $doc['mime_type']);
89 // Si le fichier a un titre avec extension,
90 // ou si c'est un nom bien connu d'Unix, le prendre
91 // sinon l'ignorer car certains navigateurs pataugent
94 if (isset($doc['titre'])
95 AND (preg_match('/^\w+[.]\w+$/', $doc['titre']) OR $doc['titre'] == 'Makefile'))
98 $f = "filename=\"$f\"";
100 // Pour les document affichables par les navigateurs,
101 // ne pas envoyer "Content-Disposition: attachment" sinon
102 // le navigateur cree un fichier au lieu de l'afficher.
103 // Mais la propriete "affichable" n'est pas toujours devinable,
104 // il faut quand meme donner un nom au fichier eventuel.
105 // Celui-ci est malheureusement souvent ignore, cf
106 // http://greenbytes.de/tech/tc2231/
108 if ($doc['inclus']!=='non') {
109 header("Content-Disposition: inline; $f");
112 header("Content-Disposition: attachment; $f;");
114 // ce content-type est necessaire
115 // pour eviter des corruptions de zip dans ie6
116 header('Content-Type: application/octet-stream');
117 header("Content-Transfer-Encoding: binary");
119 // fix for IE catching or PHP bug issue
120 header("Pragma: public");
121 header("Expires: 0"); // set expiration time
122 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
126 if ($cl = filesize($file))
127 header("Content-Length: ". $cl);