예제 #1
0
파일: documents.php 프로젝트: rhertzog/lcs
function generer_url_document_dist($id_document, $args='', $ancre='') {

	include_spip('inc/autoriser');
	if (!autoriser('voir', 'document', $id_document)) return '';

	$r = sql_fetsel("fichier,distant", "spip_documents", "id_document=".sql_quote($id_document));

	if (!$r) return '';

	$f = $r['fichier'];

	if ($r['distant'] == 'oui') return $f;

	// Si droit de voir tous les docs, pas seulement celui-ci
	// il est inutilement couteux de rajouter une protection

	$r = autoriser('voir', 'document');

	if ($r AND $r !== 'htaccess') return get_spip_doc($f);

	return generer_acceder_document($f, $id_document, $args, $ancre);
}
예제 #2
0
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 {
		$path = set_spip_doc($file);
		$path2 = generer_acceder_document($f, $arg);
		$where = "(documents.fichier=".sql_quote($path)
		  . ' OR documents.fichier=' . sql_quote($path2) . ')'
		  . ($arg ? (" AND documents.id_document=".intval($arg)) : '');

		$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);
		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('info_document_indisponible'));
		break;

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

		// 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'];

		$f = "filename=\"$f\"";

		// Pour les document affichables par les navigateurs,
		// ne pas envoyer "Content-Disposition: attachment" sinon 
		// le navigateur cree un fichier au lieu de l'afficher.
		// Mais la propriete "affichable" n'est pas toujours devinable,
		// il faut quand meme donner un nom au fichier eventuel. 
		// Celui-ci est malheureusement souvent ignore, cf
		// http://greenbytes.de/tech/tc2231/

		if ($doc['inclus']!=='non') {
			header("Content-Disposition: inline; $f");
		} else {

			header("Content-Disposition: attachment; $f;");

			// ce content-type est necessaire
			// pour eviter des corruptions de zip dans ie6
			header('Content-Type: application/octet-stream');
			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;
	}

}