[SPIP] ~2.1.12 -->2.1.25
[velocampus/web/www.git] / www / ecrire / action / acceder_document.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2014 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
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 \***************************************************************************/
12
13 if (!defined('_ECRIRE_INC_VERSION')) return;
14
15 include_spip('inc/headers');
16
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
20
21 // http://doc.spip.org/@action_acceder_document_dist
22 function action_acceder_document_dist() {
23 include_spip('inc/documents');
24
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'));
29
30 $status = $dcc = false;
31 if (strpos($f,'../') !== false
32 OR preg_match(',^\w+://,', $f)) {
33 $status = 403;
34 }
35 else if (!file_exists($file) OR !is_readable($file)) {
36 $status = 404;
37 } else {
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)) : '');
43
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);
45 if (!$doc) {
46 $status = 404;
47 } else {
48
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
54 exit;
55 } else {
56 header('ETag: '.$ETag);
57 }
58
59 //
60 // Verifier les droits de lecture du document
61 // en controlant la cle passee en argument
62 //
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");
67 $status = 403;
68 }
69 }
70 }
71
72 switch($status) {
73
74 case 403:
75 include_spip('inc/minipres');
76 echo minipres();
77 break;
78
79 case 404:
80 http_status(404);
81 include_spip('inc/minipres');
82 echo minipres(_T('erreur').' 404',
83 _T('info_document_indisponible'));
84 break;
85
86 default:
87 header("Content-Type: ". $doc['mime_type']);
88
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
92
93 $f = basename($file);
94 if (isset($doc['titre'])
95 AND (preg_match('/^\w+[.]\w+$/', $doc['titre']) OR $doc['titre'] == 'Makefile'))
96 $f = $doc['titre'];
97
98 $f = "filename=\"$f\"";
99
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/
107
108 if ($doc['inclus']!=='non') {
109 header("Content-Disposition: inline; $f");
110 } else {
111
112 header("Content-Disposition: attachment; $f;");
113
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");
118
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");
123
124 }
125
126 if ($cl = filesize($file))
127 header("Content-Length: ". $cl);
128
129 readfile($file);
130 break;
131 }
132
133 }
134
135 ?>