We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 19388
    • 297 Posts
    Hi,
    We have been having problems with custom resource types. We have two sites so different, but both need to use resource type ( image/jpeg or application/pdf ) to show a document accesed by a certain url. For example: www.mydomain.com/showFile.html?file=bill_0001.pdf or loading an image <img src="www.mydomain.com/showImage.html?file=2" />
    The way we do it is:
    - Create an snippet ( see code below )
    - Create a page
    - Disable cache
    - Change media type to image/jpeg or application/pdf
    - Call snippet uncached ( we have tried some combination of cached/uncached )

    When we are requesting the image, it is shown as if the file were corrupt, with some lines over the image and other colors , an semibroken image.
    When we are requesting the PDF file, we get an error message from acrobat.

    But, if we put the snippet code in a php file and we call it directly, it works fine!

    For example:
    www.mydomain.com/assets/snippets/billing/showFile.php?file=bill_0001.pdf
    <img src="www.mydomain.com/assets/snippets/images/showFile.php??file=2" />

    We can do it in this way, but it is not the way we like, because we have to recreate the session and we can not interact with MODx API. We have to do everything before and store results in sessions.

    It is like if MODx were adding some code before our request, that is corrupting our files.

    Any ideas about this?

    EDIT: We’re using EVO 1.0.4, PHP 5.2.14, Mysql 5.0.91, Linux

    Snippet/PHP code ( pdf ):
    <?php
    $path = '/home/thepearl/public_html/modxevo/plantillas/';
    $file = 'Plantilla_Seccionales_v2-2_web.pdf';
    
    $fichero=$path.$file;
    $len = filesize($fichero);
    header("Cache-Control: no-store, no-cache, must-revalidate");
    header("Pragma: no-cache");
    header("Content-type: application/pdf");
    header("Content-Length: $len");
    header("Content-Disposition: inline; filename=$file");
    ob_clean();
    flush();
    readfile($fichero);
    ?>
    


      • 19388
      • 297 Posts
      I’ve downloaded an http sniffer and made some test.
      There are two big differences in the raw output:

      Content-Type: application/pdf; charset=UTF-8

      vs

      Content-Type: application/pdf

      But I don’t think this is the problem, and we have made a test with charset=YTF-8 too with same results.

      The BIG problem is that in the raw output, a lot of code has dissappeared!

      The file size is 280KB ( pdf )

      I attach an screenshot comparing the RAW output
        • 15625
        • 10 Posts
        What’s the size of the truncated file?

        Looking / Figuring...

        -K
          -Ken
          God is good all the time!

          Cleary Baptist Church • http://cleary.org • http://missionsurge.com

          [=][=][=][=][=]
          | THE WALL |
          [=][=][=][=][=]
          • 3632
          • 22 Posts
          Maybe a dumb question but are you setting your template to none?
            • 19388
            • 297 Posts
            The file truncated is 250KB aprox. The strange is that is truncated, and then there is data again!
            Another file smaller ( I don’t remember the size now ) is shown correctly.
            Yes, The template is set to blank
              • 13481
              • 97 Posts
              I’ve recently done this and used the code below.

              <?php
              ###############################################################
              # File Download 1.31
              ###############################################################
              # Visit http://www.zubrag.com/scripts/ for updates
              ###############################################################
              # Sample call:
              #    download.php?f=phptutorial.zip
              #
              # Sample call (browser will try to save with new file name):
              #    download.php?f=phptutorial.zip&fc=php123tutorial.zip
              ###############################################################
              
              // Allow direct file download (hotlinking)?
              // Empty - allow hotlinking
              // If set to nonempty value (Example: example.com) will only allow downloads when referrer contains this text
              define('ALLOWED_REFERRER', '');
              
              // Download folder, i.e. folder where you keep all files for download.
              // MUST end with slash (i.e. "/" )
              define('BASE_DIR',MODX_BASE_PATH . 'assets/files/');
              
              // log downloads?  true/false
              define('LOG_DOWNLOADS',false);
              
              // log file name
              define('LOG_FILE','downloads.log');
              
              // Allowed extensions list in format 'extension' => 'mime type'
              // If myme type is set to empty string then script will try to detect mime type
              // itself, which would only work if you have Mimetype or Fileinfo extensions
              // installed on server.
              $allowed_ext = array (
              
                // archives
                //'zip' => 'application/zip',
              
                // documents
                'pdf' => 'application/pdf',
                'doc' => 'application/msword',
                'xls' => 'application/vnd.ms-excel',
                //'ppt' => 'application/vnd.ms-powerpoint',
              
                // executables
                //'exe' => 'application/octet-stream',
              
                // images
              //  'gif' => 'image/gif',
              //  'png' => 'image/png',
              //  'jpg' => 'image/jpeg',
              //  'jpeg' => 'image/jpeg',
              //
              //  // audio
              //  'mp3' => 'audio/mpeg',
              //  'wav' => 'audio/x-wav',
              //
              //  // video
              //  'mpeg' => 'video/mpeg',
              //  'mpg' => 'video/mpeg',
              //  'mpe' => 'video/mpeg',
              //  'mov' => 'video/quicktime',
              //  'avi' => 'video/x-msvideo'
              );
              
              
              
              ####################################################################
              ###  DO NOT CHANGE BELOW
              ####################################################################
              
              // If hotlinking not allowed then make hackers think there are some server problems
              if (ALLOWED_REFERRER !== ''
              && (!isset($_SERVER['HTTP_REFERER']) || strpos(strtoupper($_SERVER['HTTP_REFERER']),strtoupper(ALLOWED_REFERRER)) === false)
              ) {
                die("Internal server error. Please contact system administrator.");
              }
              
              // Make sure program execution doesn't time out
              // Set maximum script execution time in seconds (0 means no limit)
              set_time_limit(0);
              
              if (!isset($_GET['f']) || empty($_GET['f'])) {
                die("Please specify file name for download.");
              }
              
              // Nullbyte hack fix
              if (strpos($_GET['f'], "\0") !== FALSE) die('');
              
              // Get real file name.
              // Remove any path info to avoid hacking by adding relative path, etc.
              $fname = basename($_GET['f']);
              
              // Check if the file exists
              // Check in subfolders too
              function find_file ($dirname, $fname, &$file_path) {
              
                $dir = opendir($dirname);
              
                while ($file = readdir($dir)) {
                  if (empty($file_path) && $file != '.' && $file != '..') {
                    if (is_dir($dirname.'/'.$file)) {
                      find_file($dirname.'/'.$file, $fname, $file_path);
                    }
                    else {
                      if (file_exists($dirname.'/'.$fname)) {
                        $file_path = $dirname.'/'.$fname;
                        return;
                      }
                    }
                  }
                }
              
              } // find_file
              
              // get full file path (including subfolders)
              $file_path = '';
              find_file(BASE_DIR, $fname, $file_path);
              
              if (!is_file($file_path)) {
                die("File does not exist. Make sure you specified correct file name.");
              }
              
              // file size in bytes
              $fsize = filesize($file_path);
              
              // file extension
              $fext = strtolower(substr(strrchr($fname,"."),1));
              
              // check if allowed extension
              if (!array_key_exists($fext, $allowed_ext)) {
                die("Not allowed file type.");
              }
              
              // get mime type
              if ($allowed_ext[$fext] == '') {
                $mtype = '';
                // mime type is not set, get from server settings
                if (function_exists('mime_content_type')) {
                  $mtype = mime_content_type($file_path);
                }
                else if (function_exists('finfo_file')) {
                  $finfo = finfo_open(FILEINFO_MIME); // return mime type
                  $mtype = finfo_file($finfo, $file_path);
                  finfo_close($finfo);
                }
                if ($mtype == '') {
                  $mtype = "application/force-download";
                }
              }
              else {
                // get mime type defined by admin
                $mtype = $allowed_ext[$fext];
              }
              
              // Browser will try to save file with this filename, regardless original filename.
              // You can override it if needed.
              
              if (!isset($_GET['fc']) || empty($_GET['fc'])) {
                $asfname = $fname;
              }
              else {
                // remove some bad chars
                $asfname = str_replace(array('"',"'",'\\','/'), '', $_GET['fc']);
                if ($asfname === '') $asfname = 'NoName';
              }
              
              // set headers
              header("Pragma: public");
              header("Expires: 0");
              header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
              header("Cache-Control: public");
              header("Content-Description: File Transfer");
              header("Content-Type: $mtype");
              header("Content-Disposition: attachment; filename=\"$asfname\"");
              header("Content-Transfer-Encoding: binary");
              header("Content-Length: " . $fsize);
              
              // download
              // @readfile($file_path);
              $file = @fopen($file_path,"rb");
              if ($file) {
                while(!feof($file)) {
                  print(fread($file, 1024*8));
                  flush();
                  if (connection_status()!=0) {
                    @fclose($file);
                    die();
                  }
                }
                @fclose($file);
              }
              
              // log downloads
              if (!LOG_DOWNLOADS) die();
              
              $f = @fopen(LOG_FILE, 'a+');
              if ($f) {
                @fputs($f, date("m.d.Y g:ia")."  ".$_SERVER['REMOTE_ADDR']."  ".$fname."\n");
                @fclose($f);
              }
              ?>
              


              I didn’t write this code, but it works fine in MODx (doesn’t specify a license but says its free). To use, place it in a snippet and call it from a page that has a blank template (content type text/html). You call your file by entering the url of the file in your browser and adding ?f=filename to it.

              If this is a 1.0.4 specific issue then this might not help (I’m running 1.0.2 on my test install). I spent a while trying to fix your code, but since what i have works, maybe just try that.

              James
                • 19388
                • 297 Posts
                I’ve tried some code extracted from your post but I’m having the same problem sad
                Tried new headers, fopen instead readfile, @ to hide possible errors... but always the same. It is really strange :S
                  • 19388
                  • 297 Posts
                  We are finally using a modified version of File Download Plugin (v1.2) Created By: Adam Strzelecki
                  This plugin make things better reading and showing files. I think problem is cache, flushing, partial contents and multipart content.
                  If you see the code you can see what it does
                  http://modxcms.com/extras/package/?package=148
                    • 19388
                    • 297 Posts
                    He have finally abandoned MODx to do this part sad
                    We could load pdfs/xfdf with FileDownload Plugin but we were having a lot of problems, I think related with cache or others. Files were corrupted a lot of times and it was unfunctional. What we finally did was use variable sessions to secure PDF/XFDF visualization an make an external script to read the files.