Skip to content
Extraits de code Groupes Projets
acceder_document.php 3,68 ko
Newer Older
<?php

/***************************************************************************\
 *  SPIP, Systeme de publication pour l'internet                           *
 *                                                                         *
 *  Copyright (c) 2001-2014                                                *
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
 *                                                                         *
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
\***************************************************************************/

if (!defined('_ECRIRE_INC_VERSION')) return;

include_spip('inc/headers');

// acces aux documents joints securise
// verifie soit que le demandeur est authentifie
// soit que le document est publie, c'est-a-dire
// joint a au moins 1 article ou rubrique publie

// http://code.spip.net/@action_acceder_document_dist
function action_acceder_document_dist() {
	include_spip('inc/documents');

	// $file exige pour eviter le scan id_document par id_document
	$f = rawurldecode(_request('file'));
	$file = get_spip_doc($f);
	$arg = rawurldecode(_request('arg'));

	$status = $dcc = false;
	if (strpos($f,'../') !== false
	OR preg_match(',^\w+://,', $f)) {
		$status = 403;
	}
	else if (!file_exists($file) OR !is_readable($file)) {
		$status = 404;
	} else {
kent1@arscenic.info's avatar
kent1@arscenic.info a validé
		$where = "D.fichier=".sql_quote(set_spip_doc($file))
		. ($arg ? " AND D.id_document=".intval($arg): '');

		$doc = sql_fetsel("D.id_document, D.titre, D.fichier, T.mime_type, T.inclus, D.extension", "spip_documents AS D LEFT JOIN spip_types_documents AS T ON D.extension=T.extension",$where);
		if (!$doc) {
			$status = 404;
		} else {

			// ETag pour gerer le status 304
			$ETag = md5($file . ': '. filemtime($file));
			if (isset($_SERVER['HTTP_IF_NONE_MATCH'])
			AND $_SERVER['HTTP_IF_NONE_MATCH'] == $ETag) {
				http_status(304); // Not modified
				exit;
			} else {
				header('ETag: '.$ETag);
			}

			//
			// Verifier les droits de lecture du document
			// en controlant la cle passee en argument
			//
			include_spip('inc/securiser_action');
			$cle = _request('cle');
			if (!verifier_cle_action($doc['id_document'].','.$f, $cle)) {
				spip_log("acces interdit $cle erronee");
				$status = 403;
			}
		}
	}

	switch($status) {

	case 403:
		include_spip('inc/minipres');
		echo minipres();
		break;

	case 404:
		http_status(404);
		include_spip('inc/minipres');
		echo minipres(_T('erreur').' 404',
			_T('medias:info_document_indisponible'));
		break;

	default:
		header("Content-Type: ". $doc['mime_type']);

		// pour les images ne pas passer en attachment
		// sinon, lorsqu'on pointe directement sur leur adresse,
		// le navigateur les downloade au lieu de les afficher

		if ($doc['inclus']=='non') {

		  // Si le fichier a un titre avec extension,
		  // ou si c'est un nom bien connu d'Unix, le prendre
		  // sinon l'ignorer car certains navigateurs pataugent

			$f = basename($file);
			if (isset($doc['titre'])
				AND (preg_match('/^\w+[.]\w+$/', $doc['titre']) OR $doc['titre'] == 'Makefile'))
				$f = $doc['titre'];

			// ce content-type est necessaire pour eviter des corruptions de zip dans ie6
			header('Content-Type: application/octet-stream');

			header("Content-Disposition: attachment; filename=\"$f\";");
			header("Content-Transfer-Encoding: binary");

			// fix for IE catching or PHP bug issue
			header("Pragma: public");
			header("Expires: 0"); // set expiration time
			header("Cache-Control: must-revalidate, post-check=0, pre-check=0");

		}

		if ($cl = filesize($file))
			header("Content-Length: ". $cl);

		readfile($file);
		break;
	}

}

?>