static function SendFile($file_path, $args = array())
 {
     global $wpdb;
     $defaults = array('bandwidth' => 0, 'etag' => null, 'force_download' => WPFB_Core::$settings->force_download, 'cache_max_age' => 0, 'md5_hash' => null, 'filename' => null);
     extract(wp_parse_args($args, $defaults), EXTR_SKIP);
     @ini_set('max_execution_time', '0');
     @set_time_limit(0);
     @error_reporting(0);
     while (@ob_end_clean()) {
     }
     $no_cache = WPFB_Core::$settings->http_nocache && $cache_max_age != 0;
     @ini_set("zlib.output_compression", "Off");
     // remove some headers
     if (function_exists('header_remove')) {
         header_remove();
     } else {
         header("Expires: ");
         header("X-Pingback: ");
     }
     if (!@file_exists($file_path) || !is_file($file_path)) {
         header('HTTP/1.x 404 Not Found');
         wp_die('File ' . basename($file_path) . ' not found!');
     }
     wpfb_loadclass('FileUtils');
     $size = WPFB_FileUtils::GetFileSize($file_path);
     $time = filemtime($file_path);
     $file_type = WPFB_Download::GetFileType($file_path);
     if (empty($etag)) {
         $etag = md5("{$size}|{$time}|{$file_type}");
     } else {
         $etag = trim($etag, '"');
     }
     // set basic headers
     if ($no_cache) {
         header("Cache-Control: no-cache, must-revalidate, max-age=0");
         header("Pragma: no-cache");
         header("Expires: Wed, 11 Jan 1984 05:00:00 GMT");
     } elseif ($cache_max_age > 0) {
         header("Cache-Control: must-revalidate, max-age={$cache_max_age}");
     } elseif ($cache_max_age == -1) {
         header("Cache-Control: public");
     }
     //header("Connection: close");
     //header("Keep-Alive: timeout=5, max=100");
     //header("Connection: Keep-Alive");
     header("Content-Type: " . $file_type . (strpos($file_type, 'text/') !== false ? '; charset=' : ''));
     // charset fix
     header("Last-Modified: " . gmdate("D, d M Y H:i:s", $no_cache ? time() : $time) . " GMT");
     if (!empty($md5_hash) && $md5_hash[0] != '#') {
         // check if fake md5
         $pmd5 = @pack('H32', $md5_hash);
         if (!empty($pmd5)) {
             header("Content-MD5: " . @base64_encode($pmd5));
         }
     }
     if (!$no_cache) {
         header("ETag: \"{$etag}\"");
         $if_mod_since = !empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false;
         $if_none_match = !empty($_SERVER['HTTP_IF_NONE_MATCH']) ? $etag == trim($_SERVER['HTTP_IF_NONE_MATCH'], '"') : false;
         if ($if_mod_since || $if_none_match) {
             $not_modified = true;
             if ($not_modified && $if_mod_since) {
                 $not_modified = @strtotime($if_mod_since) >= $time;
             }
             if ($not_modified && $if_none_match) {
                 $not_modified = $if_none_match == $etag;
             }
             if ($not_modified) {
                 header("Content-Length: " . $size);
                 header("HTTP/1.x 304 Not Modified");
                 exit;
             }
         }
     }
     if (!($fh = @fopen($file_path, 'rb'))) {
         wp_die(__('Could not read file!', 'wp-filebase'));
     }
     list($begin, $end) = self::ParseRangeHeader($size);
     if ($begin > 0 || $end < $size - 1) {
         header('HTTP/1.0 206 Partial Content');
         header("Content-Range: bytes {$begin}-{$end}/{$size}");
     } else {
         header('HTTP/1.0 200 OK');
     }
     $length = $end - $begin + 1;
     WPFB_Download::AddTraffic($length);
     if (self::ShouldSendRangeHeader($file_path, $file_type)) {
         header("Accept-Ranges: bytes");
     }
     $request_file_name = basename(urldecode(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)));
     $filename_set = !empty($filename);
     if (!$filename_set) {
         $filename = basename($file_path);
     }
     // content headers
     if ($force_download) {
         header("Content-Disposition: attachment; filename=\"{$filename}\"");
         header("Content-Description: File Transfer");
     } elseif ($filename != $request_file_name) {
         header("Content-Disposition: inline; filename=\"{$filename}\"");
     }
     header("Content-Length: " . $length);
     // clean up things that are not needed for download
     @session_write_close();
     // disable blocking of multiple downloads at the same time
     // close db connection
     if (method_exists($wpdb, 'close')) {
         $wpdb->close();
     } elseif (function_exists('mysql_close')) {
         if (!empty($wpdb->dbh) && is_resource($wpdb->dbh)) {
             @mysql_close($wpdb->dbh);
         } else {
             @mysql_close();
         }
     }
     @ob_flush();
     @flush();
     // ready to send the file!
     if ($begin > 0) {
         fseek($fh, $begin, 0);
     }
     if (WPFB_Core::$settings->use_fpassthru) {
         fpassthru($fh);
     } else {
         $bandwidth = empty($bandwidth) ? 0 : (double) $bandwidth;
         if ($bandwidth <= 0) {
             $bandwidth = 1024 * 1024;
         }
         $buffer_size = (int) (1024 * min($bandwidth, 64));
         // convert kib/s => bytes/ms
         $bandwidth *= 1024 / 1000;
         $cur = $begin;
         while (!@feof($fh) && $cur <= $end && @connection_status() == 0) {
             $nbytes = min($buffer_size, $end - $cur + 1);
             $ts = microtime(true);
             print @fread($fh, $nbytes);
             @ob_flush();
             @flush();
             $dt = (microtime(true) - $ts) * 1000;
             // dt = time delta in ms
             $st = $nbytes / $bandwidth - $dt;
             if ($st > 0) {
                 usleep($st * 1000);
             }
             $cur += $nbytes;
         }
     }
     @fclose($fh);
     return true;
 }
Example #2
0
 static function GetRemoteFileInfo($url, $follow_redirects = 5)
 {
     wpfb_loadclass('Download');
     if (parse_url($url, PHP_URL_SCHEME) === 'file' && is_readable($url)) {
         return array('name' => basename($url), 'size' => filesize($url), 'type' => WPFB_Download::GetFileType($url), 'time' => filemtime($url));
     }
     $info = array();
     $path = parse_url($url, PHP_URL_PATH);
     require_once ABSPATH . WPINC . "/http.php";
     $response = wp_remote_head($url, array_merge(array('timeout' => 10)));
     if (is_wp_error($response)) {
         return $response;
     }
     $headers = wp_remote_retrieve_headers($response);
     if (empty($headers)) {
         return new WP_Error('get_remote_file_info', 'Headers not set!');
     }
     if ($response['response']['code'] >= 300 && $response['response']['code'] <= 399) {
         if (empty($headers['location'])) {
             return new WP_Error('get_remote_file_info', "HTTP {$response['code']} but no location header!");
         }
         if ($follow_redirects > 0) {
             return self::GetRemoteFileInfo($headers['location'], $follow_redirects - 1);
         }
         $info['location'] = $headers['location'];
     }
     $info['size'] = isset($headers['content-length']) ? $headers['content-length'] : -1;
     $info['type'] = isset($headers['content-type']) ? strtolower($headers['content-type']) : null;
     if (($p = strpos($info['type'], ';')) > 0) {
         $info['type'] = substr($info['type'], 0, $p);
     }
     $info['time'] = isset($headers['last-modified']) ? @strtotime($headers['last-modified']) : 0;
     $info['etag'] = isset($headers['etag']) ? trim($headers['etag'], '"') : '';
     $info['_response'] = $response;
     // check for filename header
     if (!empty($headers['content-disposition'])) {
         $matches = array();
         if (preg_match('/filename="?([^"]+)"?/', $headers['content-disposition'], $matches) == 1) {
             $info['name'] = $matches[1];
         }
     }
     if (empty($info['name'])) {
         $info['name'] = basename($path);
     }
     // compare extension type with http header content-type, if they are different deterime proper extension from http content-type
     $exType = WPFB_Download::GetFileType($info['name']);
     if ($exType != $info['type'] && ($e = WPFB_Download::FileType2Ext($info['type'])) != null) {
         $info['name'] .= '.' . $e;
     }
     return $info;
 }
Example #3
0
 static function GetRemoteFileInfo($url)
 {
     wpfb_loadclass('Download');
     if (parse_url($url, PHP_URL_SCHEME) === 'file' && is_readable($url)) {
         return array('name' => basename($url), 'size' => filesize($url), 'type' => WPFB_Download::GetFileType($url), 'time' => filemtime($url));
     }
     $info = array();
     $path = parse_url($url, PHP_URL_PATH);
     $headers = self::HttpGetHeaders($url);
     if (empty($headers)) {
         return null;
     }
     $info['size'] = isset($headers['content-length']) ? $headers['content-length'] : -1;
     $info['type'] = isset($headers['content-type']) ? strtolower($headers['content-type']) : null;
     $info['time'] = isset($headers['last-modified']) ? @strtotime($headers['last-modified']) : 0;
     // check for filename header
     if (!empty($headers['content-disposition'])) {
         $matches = array();
         if (preg_match('/filename="(.+)"/', $headers['content-disposition'], $matches) == 1) {
             $info['name'] = $matches[1];
         }
     }
     if (empty($info['name'])) {
         $info['name'] = basename($path);
     }
     // compare extension type with http header content-type, if they are different deterime proper extension from http content-type
     $exType = WPFB_Download::GetFileType($info['name']);
     if ($exType != $info['type'] && ($e = WPFB_Download::FileType2Ext($info['type'])) != null) {
         $info['name'] .= '.' . $e;
     }
     return $info;
 }
Example #4
0
 static function GetRemoteFileInfo($url)
 {
     wpfb_loadclass('Download');
     if (parse_url($url, PHP_URL_SCHEME) === 'file' && is_readable($url)) {
         return array('name' => basename($url), 'size' => filesize($url), 'type' => WPFB_Download::GetFileType($url), 'time' => filemtime($url));
     }
     $info = array();
     $path = parse_url($url, PHP_URL_PATH);
     require_once ABSPATH . WPINC . "/http.php";
     $response = wp_remote_head($url, array('timeout' => 10));
     if (is_wp_error($response)) {
         return $response;
     }
     $headers = wp_remote_retrieve_headers($response);
     if (empty($headers)) {
         return new WP_Error('get_remote_file_info', 'Headers not set!');
     }
     $info['size'] = isset($headers['content-length']) ? $headers['content-length'] : -1;
     $info['type'] = isset($headers['content-type']) ? strtolower($headers['content-type']) : null;
     $info['time'] = isset($headers['last-modified']) ? @strtotime($headers['last-modified']) : 0;
     // check for filename header
     if (!empty($headers['content-disposition'])) {
         $matches = array();
         if (preg_match('/filename="(.+)"/', $headers['content-disposition'], $matches) == 1) {
             $info['name'] = $matches[1];
         }
     }
     if (empty($info['name'])) {
         $info['name'] = basename($path);
     }
     // compare extension type with http header content-type, if they are different deterime proper extension from http content-type
     $exType = WPFB_Download::GetFileType($info['name']);
     if ($exType != $info['type'] && ($e = WPFB_Download::FileType2Ext($info['type'])) != null) {
         $info['name'] .= '.' . $e;
     }
     return $info;
 }