[PLUGINS] ~acces_restreint 3.3.5-->3.3.8
[ptitvelo/web/www.git] / www / plugins / accesrestreint_3_5 / action / api_docrestreint.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2009 *
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 /**
18 * acces aux documents joints securise
19 * verifie soit que le demandeur est authentifie
20 * soit que le document est publie, c'est-a-dire
21 * joint a au moins 1 article, breve ou rubrique publie
22 *
23 * URLs de la forme :
24 * docrestreint.api/id/cle/file
25 *
26 * @param null $arg
27 */
28 function action_api_docrestreint_dist($arg=null) {
29 $status = 404;
30
31 if (is_null($arg))
32 $arg =_request('arg');
33
34 $arg = explode("/",$arg);
35
36 // supprimer et vider les buffers qui posent des problemes de memory limit
37 // http://www.php.net/manual/en/function.readfile.php#81032
38 @ini_set("zlib.output_compression","0"); // pour permettre l'affichage au fur et a mesure
39 @ini_set("output_buffering","off");
40 @ini_set('implicit_flush', 1);
41 @ob_implicit_flush(1);
42 $level = ob_get_level();
43 while ($level--){
44 @ob_end_clean();
45 }
46
47
48 if (count($arg)>=3){
49
50 $id_document = intval(array_shift($arg));
51 $cle = array_shift($arg);
52 // file exige pour eviter le scan id_document par id_document
53 $f = implode("/",$arg);
54
55 if ($id_document==0
56 AND $cle==1
57 AND $f=="test/.test") {
58 echo "OK";
59 return;
60 }
61
62 include_spip('inc/documents');
63
64 $file = get_spip_doc($f);
65 spip_log($file,'dbg');
66
67 $status = $dcc = false;
68 $dossiers_a_exclure = array('nl');
69
70 // securite : on refuse tout ../ ou url absolue
71 if (strpos($f,'../') !== false
72 OR preg_match(',^\w+://,', $f)) {
73 $status = 403;
74 }
75 else if (!file_exists($file) OR !is_readable($file)) {
76 $status = 404;
77 }
78 // Si c'est dans un sous-dossier explicitement utilisé pour autre chose que les documents
79 // (exemple : les newsletters)
80 // et bien on ne teste pas l'accès
81 elseif (preg_match('%^(' . join('|', $dossiers_a_exclure) . ')/%', $f)){
82 $status = 200;
83 }
84 else {
85 $where = "documents.fichier=".sql_quote(set_spip_doc($file))
86 . ($id_document ? " AND documents.id_document=".intval($id_document): '');
87 spip_log($where,'dbg');
88
89 $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);
90 spip_log($doc,'dbg');
91 if (!$doc) {
92 $status = 404;
93 }
94 else {
95
96 // ETag pour gerer le status 304
97 $ETag = md5($file . ': '. filemtime($file));
98 if (isset($_SERVER['HTTP_IF_NONE_MATCH'])
99 AND $_SERVER['HTTP_IF_NONE_MATCH'] == $ETag) {
100 http_status(304); // Not modified
101 exit;
102 }
103 else {
104 header('ETag: '.$ETag);
105 }
106
107 //
108 // Verifier les droits de lecture du document
109
110 // en controlant la cle passee en argument si elle est dispo
111 // (perf issue : toutes les urls ont en principe cette cle fournie dans la page au moment du calcul de la page)
112 if ($cle){
113 include_spip('inc/securiser_action');
114 if (!verifier_cle_action($doc['id_document'].','.$f, $cle)) {
115 spip_log("acces interdit $cle erronee");
116 $status = 403;
117 }
118 }
119 // en verifiant le droit explicitement sinon, plus lent !
120 else {
121 if (!function_exists("autoriser"))
122 include_spip("inc/autoriser");
123 if (!autoriser('voir', 'document', $doc['id_document'])) {
124 $status = 403;
125 spip_log("acces interdit $cle erronee");
126 }
127 }
128 }
129 }
130 }
131
132
133 switch($status) {
134
135 case 403:
136 include_spip('inc/minipres');
137 echo minipres("","","",true);
138 break;
139
140 case 404:
141 http_status(404);
142 include_spip('inc/minipres');
143 echo minipres(_T('erreur').' 404',
144 _T('medias:info_document_indisponible'),"",true);
145 break;
146
147 default:
148 header("Content-Type: ". $doc['mime_type']);
149 // pour les images ne pas passer en attachment
150 // sinon, lorsqu'on pointe directement sur leur adresse,
151 // le navigateur les downloade au lieu de les afficher
152
153 if ($doc['inclus']=='non') {
154
155 $f = basename($file);
156 // ce content-type est necessaire pour eviter des corruptions de zip dans ie6
157 header('Content-Type: application/octet-stream');
158
159 header("Content-Disposition: attachment; filename=\"$f\";");
160 header("Content-Transfer-Encoding: binary");
161
162 // fix for IE catching or PHP bug issue
163 header("Pragma: public");
164 header("Expires: 0"); // set expiration time
165 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
166
167 }
168 else {
169 header("Expires: 3600"); // set expiration time
170 }
171
172 if ($cl = filesize($file))
173 header("Content-Length: ". $cl);
174
175 readfile($file);
176 break;
177 }
178
179 }
180
181 ?>