douyiqi9640 2016-03-13 15:32
浏览 48

WP没有发送正确的标头来下载文件

I have a WP plugin that sends a link to an email to download a file in hidden location. User selects a file, then a token containing the file ID etc. is written to a database, and a link is sent. Upon clicking the link (ex. mysite.com/thank-you/?id=asd687asd68as7d6a8sdd7sd768as7d6, the "thank you" page makes a request to a php function to donload the file.

There's also a dummy "download engine" page with a shortcode [download_page] that initiates the download.

Weird thing is that while this setup works just fine at test environment, and has worked for over a year at production site, it suddenly stopped working: call for DownloadFile() returns 0KB and correct headers at test site, and initiates the download, but returns full HTML file and, of course, no download.

I cannot spot any changes in configuration (both sites run WP 4.2.7). Only difference seems to be the WooCommerce plugin, and Google Analytics snippet included in production site.And that test site runs PHP 5.3 while productiopn site runs 5.6.

I'd be very grateful if somebody had an insight of what's happening.. Why are headers ignored? (There's no "Headers already sent" error.) Why is full HTML of the dummy "download engine" page displayed?

BTW it's an out-of-the-box theme, but I cannot spot no faults in it. But still, maybe.. Where I'm to look for a culprit lines? What could force a page to show full HTML instead of headers sent by php?

Relevant code is such: (download manager.php):

<?php 
  /*
  Plugin Name: Hidden Download Manager
  Description: Bla bla
  */
  include_once('add_meta_boxes.php');
  include_once('mfdm_frontend_functions.php');
  add_action( 'init', 'program_register' );
  add_shortcode( 'download_page', 'downloadFile' );
?>

(thank_you.tpl.php)

<?php
  /**
  Template Name: Thank You
  */
  $HOST = get_option('mfdm_dbhost');
  $USER = get_option('mfdm_dbuser');
  $PWORD = get_option('mfdm_dbpwd');
  $DB = get_option('mfdm_dbname');
  $connect_db = mysqli_connect($HOST,$USER,$PWORD,$DB) or die("Some error occurred during connection " . mysqli_error($connect_db));
  if(get_magic_quotes_gpc()) {
    $id = stripslashes($_GET['id']);
  } else {
    $id = $_GET['id'];
  }
  $result = $connect_db->query("SELECT * FROM 3_downloadkey WHERE uniqueid = '$id'");
  $row = resultToArray($result);
  $redirect = '';
  if (!$row) { 
    // redirect to 'invalid' page
    $redirect = get_option('mfdm_link_invalid_page');
    wp_redirect($redirect);
    exit;
  }
    get_header();
    $plugindir = plugin_dir_url(0).'mouseful_download/';

    // embed the javascript file that makes the AJAX request
    wp_enqueue_script( 'processLink_request', $plugindir . 'mf_downloads.js', array( 'jquery' ) );

    // declare the URL to the file that handles the AJAX request (wp-admin/admin-ajax.php)
    wp_localize_script('processLink_request', 'ProcessLink', array(
      'ajaxurl' => admin_url('admin-ajax.php'),
      'postCommentNonce' => wp_create_nonce( 'ProcessLink-post-comment-nonce' ),
      'downloadHiddenPage' => get_option('mfdm_download_hidden_page')
    )
  );
?>
<link rel="stylesheet" type="text/css" media="all" href="<?=$plugindir;?>mf_downloads.css">


<body onLoad="setTimeout('downloadLink()', 1000)"></body>
<div class="contents about">
  <div class="row">
    <div class="col banner">
       <p><?php the_title(); ?></p>
    </div>
  </div>        
<div class="row2"><div class="col">
<?php
    while ( have_posts() ) : the_post();
        the_content();
    endwhile;
?>
</div></div></div>
<?php 
  get_footer(); 
?>

(mfdm_frontend_functions.php):

<?php
  add_action( 'wp_ajax_nopriv_downloadLink-submit', 'downloadFile' );
  add_action( 'wp_ajax_downloadLink-submit', 'downloadFile' );

function downloadFile() {
  $HOST = get_option('mfdm_dbhost');
  $USER = get_option('mfdm_dbuser');
  $PWORD = get_option('mfdm_dbpwd');
  $DB = get_option('mfdm_dbname');
  $id = $_POST['app'];
  $connect_db = mysqli_connect($HOST,$USER,$PWORD,$DB);
  $result = $connect_db->query("SELECT * FROM 3_downloadkey WHERE uniqueid = '$id'");
  $row = resultToArray($result);
  $app_ID = $row[0]['app_ID'];
  ob_start();
  // get app name 
  $base_dir = get_option('mfdm_applications_folder');
  define('BASE_DIR',$base_dir);
  $fname = get_post_meta($app_ID, 'meta_source', true);
  $app_download_name = get_post_meta($app_ID, 'meta_program_name', true);

  $file_path = '';
  $file_path = find_file1(BASE_DIR, $fname, $file_path);
  if (!is_file($file_path)) {
    die("File does not exist. Make sure you specified correct file name.");
  }
  $fsize = filesize($file_path); 
  $fext = strtolower(substr(strrchr($fname,"."),1));
  $mime_types = array(
    'msi' => 'application/x-ole-storage',
    'zip' => 'application/zip',
    'exe' => 'application/x-msdownload',
    'sh' => 'application/x-sh',
    'iso' => 'application/octet-stream',
    'dmg' => 'application/octet-stream',
    'pdf' => 'application/pdf',
  );
  $mm_type = $mime_types[$fext];
  if ($fd = fopen ($file_path, "r")) {
  $fsize = filesize($file_path);
  $path_parts = pathinfo($file_path);
  $ext = strtolower($path_parts["extension"]);
  header("Content-type: $mm_type");
  header("Content-Disposition: attachment; filename=\"".$app_download_name."\"");
  header("Content-length: $fsize");
  header("Cache-control: private"); //use this to open files directly       
  while(ob_POST_level() > 0) {
    @ob_end_clean();
  }
  while(!feof($fd)) {
    $buffer = fread($fd, 2048);
    echo $buffer;
  }
}
fclose ($fd);
}
?>

(mf_downloads.js):

function downloadLink() {
  var id = window.location.search.replace("?", "").split("&")[0];
  id = id.split("=")[1];
  var url = ProcessLink.downloadHiddenPage;
  var form = jQuery('<form action="' + url + '" method="post">' + '<input type="text" name="app" value="' + id + '" hidden="hidden"/>' + '</form>');
  jQuery('body').append(form);
  form.submit();
} 
  • 写回答

1条回答 默认 最新

  • dporu02280 2016-03-13 15:40
    关注

    Your 'downloadFile' function in 'mfdm_frontend_functions.php' should end with wp_die() in order to return a proper response.

    wp_die(); // this is required to terminate immediately and return a proper response
    

    Upload a user-defined php.ini to your webroot containing the following line:

    default_charset = ""
    
    评论

报告相同问题?

悬赏问题

  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP