[ Index ]

PHP Cross Reference of MantisBT

title

Body

[close]

/ -> file_download.php (source)

   1  <?php
   2  # MantisBT - A PHP based bugtracking system
   3  
   4  # MantisBT is free software: you can redistribute it and/or modify
   5  # it under the terms of the GNU General Public License as published by
   6  # the Free Software Foundation, either version 2 of the License, or
   7  # (at your option) any later version.
   8  #
   9  # MantisBT is distributed in the hope that it will be useful,
  10  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  # GNU General Public License for more details.
  13  #
  14  # You should have received a copy of the GNU General Public License
  15  # along with MantisBT.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Add file and redirect to the referring page
  19   *
  20   * @package MantisBT
  21   * @copyright Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
  22   * @copyright Copyright (C) 2002 - 2011  MantisBT Team - mantisbt-dev@lists.sourceforge.net
  23   * @link http://www.mantisbt.org
  24   *
  25   * @uses core.php
  26   * @uses access_api.php
  27   * @uses authentication_api.php
  28   * @uses bug_api.php
  29   * @uses config_api.php
  30   * @uses constant_inc.php
  31   * @uses database_api.php
  32   * @uses file_api.php
  33   * @uses gpc_api.php
  34   * @uses http_api.php
  35   * @uses utility_api.php
  36   */
  37  
  38  $g_bypass_headers = true; # suppress headers as we will send our own later
  39  define( 'COMPRESSION_DISABLED', true );
  40  
  41  /**
  42   * MantisBT Core API's
  43   */
  44  require_once ( 'core.php' );
  45  require_api( 'access_api.php' );
  46  require_api( 'authentication_api.php' );
  47  require_api( 'bug_api.php' );
  48  require_api( 'config_api.php' );
  49  require_api( 'constant_inc.php' );
  50  require_api( 'database_api.php' );
  51  require_api( 'file_api.php' );
  52  require_api( 'gpc_api.php' );
  53  require_api( 'http_api.php' );
  54  require_api( 'utility_api.php' );
  55  
  56  auth_ensure_user_authenticated();
  57  
  58  $f_show_inline = gpc_get_bool( 'show_inline', false );
  59  
  60  # To prevent cross-domain inline hotlinking to attachments we require a CSRF
  61  # token from the user to show any attachment inline within the browser.
  62  # Without this security in place a malicious user could upload a HTML file
  63  # attachment and direct a user to file_download.php?file_id=X&type=bug&show_inline=1
  64  # and the malicious HTML content would be rendered in the user's browser,
  65  # violating cross-domain security.
  66  if ( $f_show_inline ) {
  67      # Disable errors for form_security_validate as we need to send HTTP
  68      # headers prior to raising an error (the error handler within
  69      # error_api.php doesn't check that headers have been sent, it just
  70      # makes the assumption that they've been sent already).
  71      if ( !@form_security_validate( 'file_show_inline' ) ) {
  72          http_all_headers();
  73          trigger_error( ERROR_FORM_TOKEN_INVALID, ERROR );
  74      }
  75  }
  76  
  77  $f_file_id = gpc_get_int( 'file_id' );
  78  $f_type    = gpc_get_string( 'type' );
  79  
  80  $c_file_id = (integer)$f_file_id;
  81  
  82  # we handle the case where the file is attached to a bug
  83  # or attached to a project as a project doc.
  84  $query = '';
  85  switch ( $f_type ) {
  86      case 'bug':
  87          $t_bug_file_table = db_get_table( 'bug_file' );
  88          $query = "SELECT *
  89              FROM $t_bug_file_table
  90              WHERE id=" . db_param();
  91          break;
  92      case 'doc':
  93          $t_project_file_table = db_get_table( 'project_file' );
  94          $query = "SELECT *
  95              FROM $t_project_file_table
  96              WHERE id=" . db_param();
  97          break;
  98      default:
  99          access_denied();
 100  }
 101  $result = db_query_bound( $query, Array( $c_file_id ) );
 102  $row = db_fetch_array( $result );
 103  extract( $row, EXTR_PREFIX_ALL, 'v' );
 104  
 105  if ( $f_type == 'bug' ) {
 106      $t_project_id = bug_get_field( $v_bug_id, 'project_id' );
 107  } else {
 108      $t_project_id = $v_project_id;
 109  }
 110  
 111  # Check access rights
 112  switch ( $f_type ) {
 113      case 'bug':
 114          if ( !file_can_download_bug_attachments( $v_bug_id, (int)$v_user_id ) ) {
 115              access_denied();
 116          }
 117          break;
 118      case 'doc':
 119          # Check if project documentation feature is enabled.
 120          if ( OFF == config_get( 'enable_project_documentation' ) ) {
 121              access_denied();
 122          }
 123  
 124          access_ensure_project_level( config_get( 'view_proj_doc_threshold' ), $v_project_id );
 125          break;
 126  }
 127  
 128  # throw away output buffer contents (and disable it) to protect download
 129  while ( @ob_end_clean() );
 130  
 131  if ( ini_get( 'zlib.output_compression' ) && function_exists( 'ini_set' ) ) {
 132      ini_set( 'zlib.output_compression', false );
 133  }
 134  
 135  http_security_headers();
 136  
 137  # Make sure that IE can download the attachments under https.
 138  header( 'Pragma: public' );
 139  
 140  # To fix an IE bug which causes problems when downloading
 141  # attached files via HTTPS, we disable the "Pragma: no-cache"
 142  # command when IE is used over HTTPS.
 143  global $g_allow_file_cache;
 144  if ( ( isset( $_SERVER["HTTPS"] ) && ( "on" == utf8_strtolower( $_SERVER["HTTPS"] ) ) ) && is_browser_internet_explorer() ) {
 145      # Suppress "Pragma: no-cache" header.
 146  } else {
 147      if ( !isset( $g_allow_file_cache ) ) {
 148          header( 'Pragma: no-cache' );
 149      }
 150  }
 151  header( 'Expires: ' . gmdate( 'D, d M Y H:i:s \G\M\T', time() ) );
 152  
 153  header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s \G\M\T', $v_date_added ) );
 154  
 155  $t_filename = file_get_display_name( $v_filename );
 156  
 157  # For Internet Explorer 8 as per http://blogs.msdn.com/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx
 158  # Don't let IE second guess our content-type!
 159  header( 'X-Content-Type-Options: nosniff' );
 160  
 161  http_content_disposition_header( $t_filename, $f_show_inline );
 162  
 163  header( 'Content-Length: ' . $v_filesize );
 164  
 165  # If finfo is available (always true for PHP >= 5.3.0) we can use it to determine the MIME type of files
 166  $finfo_available = false;
 167  if ( class_exists( 'finfo' ) ) {
 168      $t_info_file = config_get( 'fileinfo_magic_db_file' );
 169  
 170      if ( is_blank( $t_info_file ) ) {
 171          $finfo = new finfo( FILEINFO_MIME );
 172      } else {
 173          $finfo = new finfo( FILEINFO_MIME, $t_info_file );
 174      }
 175  
 176      if ( $finfo ) {
 177          $finfo_available = true;
 178      }
 179  }
 180  
 181  $t_content_type = $v_file_type;
 182  
 183  # dump file content to the connection.
 184  switch ( config_get( 'file_upload_method' ) ) {
 185      case DISK:
 186          $t_local_disk_file = file_normalize_attachment_path( $v_diskfile, $t_project_id );
 187  
 188          if ( file_exists( $t_local_disk_file ) ) {
 189              if ( $finfo_available ) {
 190                  $t_file_info_type = $finfo->file( $t_local_disk_file );
 191  
 192                  if ( $t_file_info_type !== false ) {
 193                      $t_content_type = $t_file_info_type;
 194                  }
 195              }
 196  
 197              header( 'Content-Type: ' . $t_content_type );
 198              if ( config_get( 'file_download_xsendfile_enabled' ) ) {
 199                  $t_xsendfile_header_name = config_get( 'file_download_xsendfile_header_name' );
 200                  header( $t_xsendfile_header_name . ': ' . $t_local_disk_file );
 201              } else {
 202                  readfile( $t_local_disk_file );
 203              }
 204          }
 205          break;
 206      case FTP:
 207          $t_local_disk_file = file_normalize_attachment_path( $v_diskfile, $t_project_id );
 208  
 209          if ( !file_exists( $t_local_disk_file ) ) {
 210              $ftp = file_ftp_connect();
 211              file_ftp_get ( $ftp, $t_local_disk_file, $v_diskfile );
 212              file_ftp_disconnect( $ftp );
 213          }
 214  
 215          if ( $finfo_available ) {
 216              $t_file_info_type = $finfo->file( $t_local_disk_file );
 217  
 218              if ( $t_file_info_type !== false ) {
 219                  $t_content_type = $t_file_info_type;
 220              }
 221          }
 222  
 223          header( 'Content-Type: ' . $t_content_type );
 224          readfile( $t_local_disk_file );
 225          break;
 226      default:
 227          if ( $finfo_available ) {
 228              $t_file_info_type = $finfo->buffer( $v_content );
 229  
 230              if ( $t_file_info_type !== false ) {
 231                  $t_content_type = $t_file_info_type;
 232              }
 233          }
 234  
 235          header( 'Content-Type: ' . $t_content_type );
 236          echo $v_content;
 237  }


Generated: Thu Jul 28 15:48:31 2011 Cross-referenced by PHPXref 0.7