source: spip-zone/_core_/plugins/medias/action/acceder_document.php

Last change on this file was 113294, checked in by spip.franck@…, 2 months ago

Il parait que le futur c'est maintenant :-D

File size: 3.8 KB
Line 
1<?php
2
3/***************************************************************************\
4 *  SPIP, Systeme de publication pour l'internet                           *
5 *                                                                         *
6 *  Copyright (c) 2001-2019                                                *
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
13if (!defined('_ECRIRE_INC_VERSION')) {
14        return;
15}
16
17include_spip('inc/headers');
18
19// acces aux documents joints securise
20// verifie soit que le demandeur est authentifie
21// soit que le document est publie, c'est-a-dire
22// joint a au moins 1 article ou rubrique publie
23
24// https://code.spip.net/@action_acceder_document_dist
25function action_acceder_document_dist() {
26        include_spip('inc/documents');
27
28        // $file exige pour eviter le scan id_document par id_document
29        $f = rawurldecode(_request('file'));
30        $file = get_spip_doc($f);
31        $arg = rawurldecode(_request('arg'));
32
33        $status = false;
34        if (strpos($f, '../') !== false
35                or preg_match(',^\w+://,', $f)
36        ) {
37                $status = 403;
38        } else {
39                if (!file_exists($file) or !is_readable($file)) {
40                        $status = 404;
41                } else {
42                        $where = 'D.fichier=' . sql_quote(set_spip_doc($file))
43                                . ($arg ? ' AND D.id_document=' . intval($arg) : '');
44
45                        $doc = sql_fetsel(
46                                'D.id_document, D.titre, D.fichier, T.mime_type, T.inclus, D.extension',
47                                'spip_documents AS D LEFT JOIN spip_types_documents AS T ON D.extension=T.extension',
48                                $where
49                        );
50                        if (!$doc) {
51                                $status = 404;
52                        } else {
53                                // ETag pour gerer le status 304
54                                $ETag = md5($file . ': ' . filemtime($file));
55                                if (isset($_SERVER['HTTP_IF_NONE_MATCH'])
56                                        and $_SERVER['HTTP_IF_NONE_MATCH'] == $ETag
57                                ) {
58                                        http_status(304); // Not modified
59                                        exit;
60                                } else {
61                                        header('ETag: ' . $ETag);
62                                }
63
64                                //
65                                // Verifier les droits de lecture du document
66                                // en controlant la cle passee en argument
67                                //
68                                include_spip('inc/securiser_action');
69                                $cle = _request('cle');
70                                if (!verifier_cle_action($doc['id_document'] . ',' . $f, $cle)) {
71                                        spip_log("acces interdit $cle erronee");
72                                        $status = 403;
73                                }
74                        }
75                }
76        }
77
78        switch ($status) {
79                case 403:
80                        include_spip('inc/minipres');
81                        echo minipres();
82                        break;
83
84                case 404:
85                        http_status(404);
86                        include_spip('inc/minipres');
87                        echo minipres(_T('erreur') . ' 404', _T('medias:info_document_indisponible'));
88                        break;
89
90                default:
91                        header('Content-Type: ' . $doc['mime_type']);
92
93                        // pour les images ne pas passer en attachment
94                        // sinon, lorsqu'on pointe directement sur leur adresse,
95                        // le navigateur les downloade au lieu de les afficher
96
97                        if ($doc['inclus'] == 'non') {
98                                // Si le fichier a un titre avec extension,
99                                // ou si c'est un nom bien connu d'Unix, le prendre
100                                // sinon l'ignorer car certains navigateurs pataugent
101
102                                $f = basename($file);
103                                if (isset($doc['titre'])
104                                        and (preg_match('/^\w+[.]\w+$/', $doc['titre']) or $doc['titre'] == 'Makefile')
105                                ) {
106                                        $f = $doc['titre'];
107                                }
108
109                                // ce content-type est necessaire pour eviter des corruptions de zip dans ie6
110                                header('Content-Type: application/octet-stream');
111
112                                header("Content-Disposition: attachment; filename=\"$f\";");
113                                header('Content-Transfer-Encoding: binary');
114
115                                // fix for IE catching or PHP bug issue
116                                header('Pragma: public');
117                                header('Expires: 0'); // set expiration time
118                                header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
119                        }
120
121                        if ($cl = filesize($file)) {
122                                header('Content-Length: ' . $cl);
123                        }
124
125                        readfile($file);
126                        break;
127        }
128}
Note: See TracBrowser for help on using the repository browser.