forum_attachment.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. <?php
  2. /**
  3. * [Discuz!] (C)2001-2099 Comsenz Inc.
  4. * This is NOT a freeware, use is subject to license terms
  5. *
  6. * $Id: forum_attachment.php 34304 2014-01-15 11:11:23Z nemohou $
  7. */
  8. if(!defined('IN_DISCUZ')) {
  9. exit('Access Denied');
  10. }
  11. define('NOROBOT', TRUE);
  12. @list($_GET['aid'], $_GET['k'], $_GET['t'], $_GET['uid'], $_GET['tableid']) = daddslashes(explode('|', base64_decode($_GET['aid'])));
  13. $requestmode = !empty($_GET['request']) && empty($_GET['uid']);
  14. $aid = intval($_GET['aid']);
  15. $k = $_GET['k'];
  16. $t = $_GET['t'];
  17. $authk = !$requestmode ? substr(md5($aid.md5($_G['config']['security']['authkey']).$t.$_GET['uid']), 0, 8) : md5($aid.md5($_G['config']['security']['authkey']).$t);
  18. if($k != $authk) {
  19. if(!$requestmode) {
  20. showmessage('attachment_nonexistence');
  21. } else {
  22. exit;
  23. }
  24. }
  25. if(!empty($_GET['findpost']) && ($attach = C::t('forum_attachment')->fetch($aid))) {
  26. dheader('location: forum.php?mod=redirect&goto=findpost&pid='.$attach['pid'].'&ptid='.$attach['tid']);
  27. }
  28. if($_GET['uid'] != $_G['uid'] && $_GET['uid']) {
  29. $_G['uid'] = $_GET['uid'] = intval($_GET['uid']);
  30. $member = getuserbyuid($_GET['uid']);
  31. loadcache('usergroup_'.$member['groupid']);
  32. $_G['group'] = $_G['cache']['usergroup_'.$member['groupid']];
  33. $_G['group']['grouptitle'] = $_G['cache']['usergroup_'.$_G['groupid']]['grouptitle'];
  34. $_G['group']['color'] = $_G['cache']['usergroup_'.$_G['groupid']]['color'];
  35. }
  36. $tableid = 'aid:'.$aid;
  37. if($_G['setting']['attachexpire']) {
  38. if(TIMESTAMP - $t > $_G['setting']['attachexpire'] * 3600) {
  39. $aid = intval($aid);
  40. if($attach = C::t('forum_attachment_n')->fetch($tableid, $aid)) {
  41. if($attach['isimage']) {
  42. dheader('location: '.$_G['siteurl'].'static/image/common/none.gif');
  43. } else {
  44. if(!$requestmode) {
  45. showmessage('attachment_expired', '', array('aid' => aidencode($aid, 0, $attach['tid']), 'pid' => $attach['pid'], 'tid' => $attach['tid']));
  46. } else {
  47. exit;
  48. }
  49. }
  50. } else {
  51. if(!$requestmode) {
  52. showmessage('attachment_nonexistence');
  53. } else {
  54. exit;
  55. }
  56. }
  57. }
  58. }
  59. $readmod = getglobal('config/download/readmod');
  60. $readmod = $readmod > 0 && $readmod < 5 ? $readmod : 2;
  61. $refererhost = parse_url($_SERVER['HTTP_REFERER']);
  62. $serverhost = $_SERVER['HTTP_HOST'];
  63. if(($pos = strpos($serverhost, ':')) !== FALSE) {
  64. $serverhost = substr($serverhost, 0, $pos);
  65. }
  66. if(!$requestmode && $_G['setting']['attachrefcheck'] && $_SERVER['HTTP_REFERER'] && !($refererhost['host'] == $serverhost)) {
  67. showmessage('attachment_referer_invalid', NULL);
  68. }
  69. periodscheck('attachbanperiods');
  70. loadcache('threadtableids');
  71. $threadtableids = !empty($_G['cache']['threadtableids']) ? $_G['cache']['threadtableids'] : array();
  72. if(!in_array(0, $threadtableids)) {
  73. $threadtableids = array_merge(array(0), $threadtableids);
  74. }
  75. $archiveid = in_array($_GET['archiveid'], $threadtableids) ? intval($_GET['archiveid']) : 0;
  76. $attachexists = FALSE;
  77. if(!empty($aid) && is_numeric($aid)) {
  78. $attach = C::t('forum_attachment_n')->fetch($tableid, $aid);
  79. $thread = C::t('forum_thread')->fetch_by_tid_displayorder($attach['tid'], 0, '>=', null, $archiveid);
  80. if($_G['uid'] && $attach['uid'] != $_G['uid']) {
  81. if($attach) {
  82. $attachpost = C::t('forum_post')->fetch($thread['posttableid'], $attach['pid'], false);
  83. $attach['invisible'] = $attachpost['invisible'];
  84. unset($attachpost);
  85. }
  86. if($attach && $attach['invisible'] == 0) {
  87. $thread && $attachexists = TRUE;
  88. }
  89. } else {
  90. $attachexists = TRUE;
  91. }
  92. }
  93. if(!$attachexists) {
  94. if(!$requestmode) {
  95. showmessage('attachment_nonexistence');
  96. } else {
  97. exit;
  98. }
  99. }
  100. if(!$requestmode) {
  101. $forum = C::t('forum_forumfield')->fetch_info_for_attach($thread['fid'], $_G['uid']);
  102. $_GET['fid'] = $forum['fid'];
  103. if($attach['isimage']) {
  104. $allowgetattach = !empty($forum['allowgetimage']) || (($_G['group']['allowgetimage'] || $_G['uid'] == $attach['uid']) && !$forum['getattachperm']) || forumperm($forum['getattachperm']);
  105. } else {
  106. $allowgetattach = !empty($forum['allowgetattach']) || (($_G['group']['allowgetattach'] || $_G['uid'] == $attach['uid']) && !$forum['getattachperm']) || forumperm($forum['getattachperm']);
  107. }
  108. if($allowgetattach && ($attach['readperm'] && $attach['readperm'] > $_G['group']['readaccess']) && $_G['adminid'] <= 0 && !($_G['uid'] && $_G['uid'] == $attach['uid'])) {
  109. showmessage('attachment_forum_nopermission', NULL, array(), array('login' => 1));
  110. }
  111. $ismoderator = in_array($_G['adminid'], array(1, 2)) ? 1 : ($_G['adminid'] == 3 ? C::t('forum_moderator')->fetch_uid_by_tid($attach['tid'], $_G['uid'], $archiveid) : 0);
  112. $ispaid = FALSE;
  113. $exemptvalue = $ismoderator ? 128 : 16;
  114. if(!$thread['special'] && $thread['price'] > 0 && (!$_G['uid'] || ($_G['uid'] != $attach['uid'] && !($_G['group']['exempt'] & $exemptvalue)))) {
  115. if(!$_G['uid'] || $_G['uid'] && !($ispaid = C::t('common_credit_log')->count_by_uid_operation_relatedid($_G['uid'], 'BTC', $attach['tid']))) {
  116. showmessage('attachment_payto', 'forum.php?mod=viewthread&tid='.$attach['tid']);
  117. }
  118. }
  119. $exemptvalue = $ismoderator ? 64 : 8;
  120. if($attach['price'] && (!$_G['uid'] || ($_G['uid'] != $attach['uid'] && !($_G['group']['exempt'] & $exemptvalue)))) {
  121. $payrequired = $_G['uid'] ? !C::t('common_credit_log')->count_by_uid_operation_relatedid($_G['uid'], 'BAC', $attach['aid']) : 1;
  122. $payrequired && showmessage('attachement_payto_attach', 'forum.php?mod=misc&action=attachpay&aid='.$attach['aid'].'&tid='.$attach['tid']);
  123. }
  124. }
  125. $isimage = $attach['isimage'];
  126. $_G['setting']['ftp']['hideurl'] = $_G['setting']['ftp']['hideurl'] || ($isimage && !empty($_GET['noupdate']) && $_G['setting']['attachimgpost'] && strtolower(substr($_G['setting']['ftp']['attachurl'], 0, 3)) == 'ftp');
  127. if(empty($_GET['nothumb']) && $attach['isimage'] && $attach['thumb']) {
  128. $db = DB::object();
  129. $db->close();
  130. !$_G['config']['output']['gzip'] && ob_end_clean();
  131. dheader('Content-Disposition: inline; filename='.getimgthumbname($attach['filename']));
  132. dheader('Content-Type: image/pjpeg');
  133. if($attach['remote']) {
  134. $_G['setting']['ftp']['hideurl'] ? getremotefile(getimgthumbname($attach['attachment'])) : dheader('location:'.$_G['setting']['ftp']['attachurl'].'forum/'.getimgthumbname($attach['attachment']));
  135. } else {
  136. getlocalfile($_G['setting']['attachdir'].'/forum/'.getimgthumbname($attach['attachment']));
  137. }
  138. exit();
  139. }
  140. $filename = $_G['setting']['attachdir'].'/forum/'.$attach['attachment'];
  141. if(!$attach['remote'] && !is_readable($filename)) {
  142. $storageService = Cloud::loadClass('Service_Storage');
  143. $storageService->checkAttachment($attach);
  144. if(!$requestmode) {
  145. showmessage('attachment_nonexistence');
  146. } else {
  147. exit;
  148. }
  149. }
  150. if(!$requestmode) {
  151. if(!$ispaid && !$forum['allowgetattach']) {
  152. if(!$forum['getattachperm'] && !$allowgetattach) {
  153. showmessage('getattachperm_none_nopermission', NULL, array(), array('login' => 1));
  154. } elseif(($forum['getattachperm'] && !forumperm($forum['getattachperm'])) || ($forum['viewperm'] && !forumperm($forum['viewperm']))) {
  155. showmessagenoperm('getattachperm', $forum['fid']);
  156. }
  157. }
  158. $exemptvalue = $ismoderator ? 32 : 4;
  159. if(!$isimage && !($_G['group']['exempt'] & $exemptvalue)) {
  160. $creditlog = updatecreditbyaction('getattach', $_G['uid'], array(), '', 1, 0, $thread['fid']);
  161. if($creditlog['updatecredit']) {
  162. if($_G['uid']) {
  163. $k = $_GET['ck'];
  164. $t = $_GET['t'];
  165. if(empty($k) || empty($t) || $k != substr(md5($aid.$t.md5($_G['config']['security']['authkey'])), 0, 8) || TIMESTAMP - $t > 3600) {
  166. dheader('location: forum.php?mod=misc&action=attachcredit&aid='.$attach['aid'].'&formhash='.FORMHASH);
  167. exit();
  168. }
  169. } else {
  170. showmessage('attachment_forum_nopermission', NULL, array(), array('login' => 1));
  171. }
  172. }
  173. }
  174. }
  175. $range = 0;
  176. if($readmod == 4 && !empty($_SERVER['HTTP_RANGE'])) {
  177. list($range) = explode('-',(str_replace('bytes=', '', $_SERVER['HTTP_RANGE'])));
  178. }
  179. if(!$requestmode && !$range && empty($_GET['noupdate'])) {
  180. if($_G['setting']['delayviewcount']) {
  181. $_G['forum_logfile'] = './data/cache/forum_attachviews_'.intval(getglobal('config/server/id')).'.log';
  182. if(substr(TIMESTAMP, -1) == '0') {
  183. attachment_updateviews($_G['forum_logfile']);
  184. }
  185. if(@$fp = fopen(DISCUZ_ROOT.$_G['forum_logfile'], 'a')) {
  186. fwrite($fp, "$aid\n");
  187. fclose($fp);
  188. } elseif($_G['adminid'] == 1) {
  189. showmessage('view_log_invalid', '', array('logfile' => $_G['forum_logfile']));
  190. }
  191. } else {
  192. C::t('forum_attachment')->update_download($aid);
  193. }
  194. }
  195. $db = DB::object();
  196. $db->close();
  197. !$_G['config']['output']['gzip'] && ob_end_clean();
  198. if($attach['remote'] && !$_G['setting']['ftp']['hideurl'] && $isimage) {
  199. dheader('location:'.$_G['setting']['ftp']['attachurl'].'forum/'.$attach['attachment']);
  200. }
  201. $filesize = !$attach['remote'] ? filesize($filename) : $attach['filesize'];
  202. $attach['filename'] = '"'.(strtolower(CHARSET) == 'utf-8' && strexists($_SERVER['HTTP_USER_AGENT'], 'MSIE') ? urlencode($attach['filename']) : $attach['filename']).'"';
  203. dheader('Date: '.gmdate('D, d M Y H:i:s', $attach['dateline']).' GMT');
  204. dheader('Last-Modified: '.gmdate('D, d M Y H:i:s', $attach['dateline']).' GMT');
  205. dheader('Content-Encoding: none');
  206. if($isimage && !empty($_GET['noupdate']) || !empty($_GET['request'])) {
  207. dheader('Content-Disposition: inline; filename='.$attach['filename']);
  208. } else {
  209. dheader('Content-Disposition: attachment; filename='.$attach['filename']);
  210. }
  211. if($isimage) {
  212. dheader('Content-Type: image');
  213. } else {
  214. dheader('Content-Type: application/octet-stream');
  215. }
  216. dheader('Content-Length: '.$filesize);
  217. $xsendfile = getglobal('config/download/xsendfile');
  218. if(!empty($xsendfile)) {
  219. $type = intval($xsendfile['type']);
  220. $cmd = '';
  221. switch ($type) {
  222. case 1: $cmd = 'X-Accel-Redirect'; $url = $xsendfile['dir'].$attach['attachment']; break;
  223. case 2: $cmd = $_SERVER['SERVER_SOFTWARE'] <'lighttpd/1.5' ? 'X-LIGHTTPD-send-file' : 'X-Sendfile'; $url = $filename; break;
  224. case 3: $cmd = 'X-Sendfile'; $url = $filename; break;
  225. }
  226. if($cmd) {
  227. dheader("$cmd: $url");
  228. exit();
  229. }
  230. }
  231. if($readmod == 4) {
  232. dheader('Accept-Ranges: bytes');
  233. if(!empty($_SERVER['HTTP_RANGE'])) {
  234. $rangesize = ($filesize - $range) > 0 ? ($filesize - $range) : 0;
  235. dheader('Content-Length: '.$rangesize);
  236. dheader('HTTP/1.1 206 Partial Content');
  237. dheader('Content-Range: bytes='.$range.'-'.($filesize-1).'/'.($filesize));
  238. }
  239. }
  240. $attach['remote'] ? getremotefile($attach['attachment']) : getlocalfile($filename, $readmod, $range);
  241. function getremotefile($file) {
  242. global $_G;
  243. @set_time_limit(0);
  244. if(!@readfile($_G['setting']['ftp']['attachurl'].'forum/'.$file)) {
  245. $ftp = ftpcmd('object');
  246. $tmpfile = @tempnam($_G['setting']['attachdir'], '');
  247. if($ftp->ftp_get($tmpfile, 'forum/'.$file, FTP_BINARY)) {
  248. @readfile($tmpfile);
  249. @unlink($tmpfile);
  250. } else {
  251. @unlink($tmpfile);
  252. return FALSE;
  253. }
  254. }
  255. return TRUE;
  256. }
  257. function getlocalfile($filename, $readmod = 2, $range = 0) {
  258. if($readmod == 1 || $readmod == 3 || $readmod == 4) {
  259. if($fp = @fopen($filename, 'rb')) {
  260. @fseek($fp, $range);
  261. if(function_exists('fpassthru') && ($readmod == 3 || $readmod == 4)) {
  262. @fpassthru($fp);
  263. } else {
  264. echo @fread($fp, filesize($filename));
  265. }
  266. }
  267. @fclose($fp);
  268. } else {
  269. @readfile($filename);
  270. }
  271. @flush(); @ob_flush();
  272. }
  273. function attachment_updateviews($logfile) {
  274. $viewlog = $viewarray = array();
  275. $newlog = DISCUZ_ROOT.$logfile.random(6);
  276. if(@rename(DISCUZ_ROOT.$logfile, $newlog)) {
  277. $viewlog = file($newlog);
  278. unlink($newlog);
  279. if(is_array($viewlog) && !empty($viewlog)) {
  280. $viewlog = array_count_values($viewlog);
  281. foreach($viewlog as $id => $views) {
  282. if($id > 0) {
  283. $viewarray[$views][] = intval($id);
  284. }
  285. }
  286. foreach($viewarray as $views => $ids) {
  287. C::t('forum_attachment')->update_download($ids, $views);
  288. }
  289. }
  290. }
  291. }
  292. ?>