[WooCommerce] x-sendfile with php-fpm
-
A while ago I started thread here:
https://wordpress.org/support/topic/x-sendfile-with-php-fpm/It’s now closed but in case anyone has the same issue, here is the solution, pretty much along the lines suggested by support.
Below is a code snippet which I added into the customisations plugin, or you could add it to a child theme’s functions.php.
The problem arises with WooCommerce file downloads if you are running apache and php FPM. WooCommerce can’t detect X-Sendfile because FPM doesn’t have the required function.
So the following code copies the WC code with the X-Sendfile check removed./* force X-Sendfile despite php-fpm */
remove_action( 'woocommerce_download_file_xsendfile', array( WC_Download_Handler::class, 'download_file_xsendfile' ) );
// Hook your custom function into WooCommerce's download handler
add_action('woocommerce_download_file_xsendfile', [ spelfabet_download_handler::class, 'download_file_xsendfile'], 10, 2);
class spelfabet_download_handler{
public static function download_file_xsendfile( $file_path, $filename ) {
$parsed_file_path = WC_Download_Handler::parse_file_path( $file_path );
self::download_headers( $parsed_file_path['file_path'], $filename );
$filepath = apply_filters( 'woocommerce_download_file_xsendfile_file_path', $parsed_file_path['file_path'], $file_path, $filename, $parsed_file_path );
header( 'X-Sendfile: ' . $filepath );
exit;
}
private static function download_headers( $file_path, $filename, $download_range = array() ) {
self::check_server_config();
self::clean_buffers();
wc_nocache_headers();
header( 'X-Robots-Tag: noindex, nofollow', true );
header( 'Content-Type: ' . self::get_download_content_type( $file_path ) );
header( 'Content-Description: File Transfer' );
header( 'Content-Disposition: ' . self::get_content_disposition() . '; filename="' . $filename . '";' );
header( 'Content-Transfer-Encoding: binary' );
$file_size = @filesize( $file_path ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
if ( ! $file_size ) {
return;
}
if ( isset( $download_range['is_range_request'] ) && true === $download_range['is_range_request'] ) {
if ( false === $download_range['is_range_valid'] ) {
header( 'HTTP/1.1 416 Requested Range Not Satisfiable' );
header( 'Content-Range: bytes 0-' . ( $file_size - 1 ) . '/' . $file_size );
exit;
}
$start = $download_range['start'];
$end = $download_range['start'] + $download_range['length'] - 1;
$length = $download_range['length'];
header( 'HTTP/1.1 206 Partial Content' );
header( "Accept-Ranges: 0-$file_size" );
header( "Content-Range: bytes $start-$end/$file_size" );
header( "Content-Length: $length" );
} else {
header( 'Content-Length: ' . $file_size );
}
}
private static function check_server_config() {
wc_set_time_limit( 0 );
if ( function_exists( 'apache_setenv' ) ) {
@apache_setenv( 'no-gzip', 1 ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_apache_setenv
}
@ini_set( 'zlib.output_compression', 'Off' ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_ini_set
@session_write_close(); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.VIP.SessionFunctionsUsage.session_session_write_close
}
private static function clean_buffers() {
if ( ob_get_level() ) {
$levels = ob_get_level();
for ( $i = 0; $i < $levels; $i++ ) {
@ob_end_clean(); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
}
} else {
@ob_end_clean(); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
}
}
private static function get_download_content_type( $file_path ) {
$file_extension = strtolower( substr( strrchr( $file_path, '.' ), 1 ) );
$ctype = 'application/force-download';
foreach ( get_allowed_mime_types() as $mime => $type ) {
$mimes = explode( '|', $mime );
if ( in_array( $file_extension, $mimes, true ) ) {
$ctype = $type;
break;
}
}
return $ctype;
}
private static function get_content_disposition() : string {
$disposition = 'attachment';
if ( 'yes' === get_option( 'woocommerce_downloads_deliver_inline' ) ) {
$disposition = 'inline';
}
return $disposition;
}
}The page I need help with: [log in to see the link]
The topic ‘[WooCommerce] x-sendfile with php-fpm’ is closed to new replies.