acceder_document.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <?php
  2. /***************************************************************************\
  3. * SPIP, Systeme de publication pour l'internet *
  4. * *
  5. * Copyright (c) 2001-2014 *
  6. * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
  7. * *
  8. * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
  9. * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
  10. \***************************************************************************/
  11. if (!defined('_ECRIRE_INC_VERSION')) return;
  12. include_spip('inc/headers');
  13. // acces aux documents joints securise
  14. // verifie soit que le demandeur est authentifie
  15. // soit que le document est publie, c'est-a-dire
  16. // joint a au moins 1 article ou rubrique publie
  17. // http://code.spip.net/@action_acceder_document_dist
  18. function action_acceder_document_dist() {
  19. include_spip('inc/documents');
  20. // $file exige pour eviter le scan id_document par id_document
  21. $f = rawurldecode(_request('file'));
  22. $file = get_spip_doc($f);
  23. $arg = rawurldecode(_request('arg'));
  24. $status = $dcc = false;
  25. if (strpos($f,'../') !== false
  26. OR preg_match(',^\w+://,', $f)) {
  27. $status = 403;
  28. }
  29. else if (!file_exists($file) OR !is_readable($file)) {
  30. $status = 404;
  31. } else {
  32. $where = "D.fichier=".sql_quote(set_spip_doc($file))
  33. . ($arg ? " AND D.id_document=".intval($arg): '');
  34. $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);
  35. if (!$doc) {
  36. $status = 404;
  37. } else {
  38. // ETag pour gerer le status 304
  39. $ETag = md5($file . ': '. filemtime($file));
  40. if (isset($_SERVER['HTTP_IF_NONE_MATCH'])
  41. AND $_SERVER['HTTP_IF_NONE_MATCH'] == $ETag) {
  42. http_status(304); // Not modified
  43. exit;
  44. } else {
  45. header('ETag: '.$ETag);
  46. }
  47. //
  48. // Verifier les droits de lecture du document
  49. // en controlant la cle passee en argument
  50. //
  51. include_spip('inc/securiser_action');
  52. $cle = _request('cle');
  53. if (!verifier_cle_action($doc['id_document'].','.$f, $cle)) {
  54. spip_log("acces interdit $cle erronee");
  55. $status = 403;
  56. }
  57. }
  58. }
  59. switch($status) {
  60. case 403:
  61. include_spip('inc/minipres');
  62. echo minipres();
  63. break;
  64. case 404:
  65. http_status(404);
  66. include_spip('inc/minipres');
  67. echo minipres(_T('erreur').' 404',
  68. _T('medias:info_document_indisponible'));
  69. break;
  70. default:
  71. header("Content-Type: ". $doc['mime_type']);
  72. // pour les images ne pas passer en attachment
  73. // sinon, lorsqu'on pointe directement sur leur adresse,
  74. // le navigateur les downloade au lieu de les afficher
  75. if ($doc['inclus']=='non') {
  76. // Si le fichier a un titre avec extension,
  77. // ou si c'est un nom bien connu d'Unix, le prendre
  78. // sinon l'ignorer car certains navigateurs pataugent
  79. $f = basename($file);
  80. if (isset($doc['titre'])
  81. AND (preg_match('/^\w+[.]\w+$/', $doc['titre']) OR $doc['titre'] == 'Makefile'))
  82. $f = $doc['titre'];
  83. // ce content-type est necessaire pour eviter des corruptions de zip dans ie6
  84. header('Content-Type: application/octet-stream');
  85. header("Content-Disposition: attachment; filename=\"$f\";");
  86. header("Content-Transfer-Encoding: binary");
  87. // fix for IE catching or PHP bug issue
  88. header("Pragma: public");
  89. header("Expires: 0"); // set expiration time
  90. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  91. }
  92. if ($cl = filesize($file))
  93. header("Content-Length: ". $cl);
  94. readfile($file);
  95. break;
  96. }
  97. }
  98. ?>