• Resolved Marcus Karlos

    (@power2009)


    Hello.

    When transferring files using modes like “X-Sendfile, X-Lighttpd-Sendfile, or X-Accel-Redirect,” the file size isn’t included because the size parameter is not passed in the template function. Consequently, users downloading files are unaware of the final size of the download.

    /**
     * Download a file using X-Sendfile, X-Lighttpd-Sendfile, or X-Accel-Redirect if available.
     *
     * @param string $file_path File path.
     * @param string $filename  File name.
     */
    public static function download_file_xsendfile( $file_path, $filename ) {
        $parsed_file_path = self::parse_file_path( $file_path );
    
        /**
         * Fallback on force download method for remote files. This is because:
         * 1. xsendfile needs proxy configuration to work for remote files, which cannot be assumed to be available on most hosts.
         * 2. Force download method is more secure than redirect method if allow_url_fopen is enabled in php.ini.
         */
        if ( $parsed_file_path['remote_file'] && ! apply_filters( 'woocommerce_use_xsendfile_for_remote', false ) ) {
            do_action( 'woocommerce_download_file_force', $file_path, $filename );
            return;
        }
    
        if ( function_exists( 'apache_get_modules' ) && in_array( 'mod_xsendfile', apache_get_modules(), true ) ) {
            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;
        } elseif ( stristr( getenv( 'SERVER_SOFTWARE' ), 'lighttpd' ) ) {
            self::download_headers( $parsed_file_path['file_path'], $filename );
            $filepath = apply_filters( 'woocommerce_download_file_xsendfile_lighttpd_file_path', $parsed_file_path['file_path'], $file_path, $filename, $parsed_file_path );
            header( 'X-Lighttpd-Sendfile: ' . $filepath );
            exit;
        } elseif ( stristr( getenv( 'SERVER_SOFTWARE' ), 'nginx' ) || stristr( getenv( 'SERVER_SOFTWARE' ), 'cherokee' ) ) {
            self::download_headers( $parsed_file_path['file_path'], $filename );
            $xsendfile_path = trim( preg_replace( '^' . str_replace( '\\', '/', getcwd() ) . '', '', $parsed_file_path['file_path'] ), '/' );
            $xsendfile_path = apply_filters( 'woocommerce_download_file_xsendfile_x_accel_redirect_file_path', $xsendfile_path, $file_path, $filename, $parsed_file_path );
            header( "X-Accel-Redirect: /$xsendfile_path" );
            exit;
        }
    
        // Fallback.
        wc_get_logger()->warning(
            sprintf(
                /* translators: %1$s contains the filepath of the digital asset. */
                __( '%1$s could not be served using the X-Accel-Redirect/X-Sendfile method. A Force Download will be used instead.', 'woocommerce' ),
                $file_path
            )
        );
        self::download_file_force( $file_path, $filename );
    }

    Additionally, the function lacks the ability to convey the file size when a file is downloaded, leaving users unaware of the final download size.

    // Absent: header( 'HTTP/1.1 206 Partial Content' );
    // Absent: header( "Accept-Ranges: 0-$file_size" );
    // Absent: header( "Content-Range: bytes $start-$end/$file_size" );
    header( "Content-Length: $file_size" );

    Maybe u have a hook?? I try do that on server side but without success((

Viewing 9 replies - 1 through 9 (of 9 total)
  • Plugin Support RK a11n

    (@riaanknoetze)

    Hi @power2009

    At the moment, there are no other filters to add additional headers to the file download methods. That said, here are some thoughts on how to proceed:

    • Unhook download_file_xsendfile from woocommerce_download_file_xsendfile and then add your own custom function with the added headers. The default priority is set at 10, so you’ll want to make sure your’s is at a higher priority.
    • You could add filters to the existing WooCommerce core code by doing a pull-request. There are filters available on the $filepath but nothing as yet on the header . Our developers would need to evaluate suitability though.

    Hope it helps!

    Thread Starter Marcus Karlos

    (@power2009)

    So i will try do that a now

    Solution

    // Remove the built-in function download_file_xsendfile from the hook
    remove_action( ‘woocommerce_download_file_xsendfile’, array( ‘WC_Download_Handler’, ‘download_file_xsendfile’ ), 10 );

    // Add your custom function with additional headers
    add_action( ‘woocommerce_download_file_xsendfile’, ‘trys_download_file_xsendfile’, 20, 2 );

    /**

    • Custom function to download a file using X-Sendfile, X-Lighttpd-Sendfile, or X-Accel-Redirect if available.
      *
    • @param string $file_path File path.
    • @param string $filename File name.
      */
      function trys_download_file_xsendfile( $file_path, $filename ) {
      // Parse the file path
      $parsed_file_path = WC_Download_Handler::parse_file_path( $file_path ); // Fallback to force download method for remote files if WooCommerce setting disallows xsendfile for remote files
      if ( $parsed_file_path[‘remote_file’] && ! apply_filters( ‘woocommerce_use_xsendfile_for_remote’, false ) ) {
      do_action( ‘woocommerce_download_file_force’, $file_path, $filename );
      return;
      } // Check for mod_xsendfile support on Apache
      if ( function_exists( ‘apache_get_modules’ ) && in_array( ‘mod_xsendfile’, apache_get_modules(), true ) ) {
      WC_Download_Handler::download_headers( $parsed_file_path[‘file_path’], $filename ); // Set headers // Set X-Sendfile for Apache $filepath = apply_filters( 'woocommerce_download_file_xsendfile_file_path', $parsed_file_path['file_path'], $file_path, $filename, $parsed_file_path ); header( 'X-Sendfile: ' . $filepath ); header( 'Content-Length: ' . filesize( $parsed_file_path['file_path'] ) ); // Add Content-Length exit; } elseif ( stristr( getenv( ‘SERVER_SOFTWARE’ ), ‘lighttpd’ ) ) {
      WC_Download_Handler::download_headers( $parsed_file_path[‘file_path’], $filename ); // Set headers // Set X-Lighttpd-Sendfile for Lighttpd $filepath = apply_filters( 'woocommerce_download_file_xsendfile_lighttpd_file_path', $parsed_file_path['file_path'], $file_path, $filename, $parsed_file_path ); header( 'X-Lighttpd-Sendfile: ' . $filepath ); header( 'Content-Length: ' . filesize( $parsed_file_path['file_path'] ) ); // Add Content-Length exit; } elseif ( stristr( getenv( ‘SERVER_SOFTWARE’ ), ‘nginx’ ) || stristr( getenv( ‘SERVER_SOFTWARE’ ), ‘cherokee’ ) ) {
      WC_Download_Handler::download_headers( $parsed_file_path[‘file_path’], $filename ); // Set headers // Set X-Accel-Redirect for Nginx or Cherokee $xsendfile_path = trim( preg_replace( '^' . str_replace( '\\', '/', getcwd() ) . '', '', $parsed_file_path['file_path'] ), '/' ); $xsendfile_path = apply_filters( 'woocommerce_download_file_xsendfile_x_accel_redirect_file_path', $xsendfile_path, $file_path, $filename, $parsed_file_path ); header( "X-Accel-Redirect: /$xsendfile_path" ); header( 'Content-Length: ' . filesize( $parsed_file_path['file_path'] ) ); // Add Content-Length exit; } // Fallback if X-Sendfile or X-Accel-Redirect methods are not supported
      wc_get_logger()->warning(
      sprintf(
      /* translators: %1$s contains the filepath of the digital asset. */
      __( ‘%1$s could not be served using the X-Accel-Redirect/X-Sendfile method. A Force Download will be used instead.’, ‘woocommerce’ ),
      $file_path
      )
      );
      WC_Download_Handler::download_file_force( $file_path, $filename ); // Force download
      }
    Plugin Support omarfpg a11n

    (@omarfpg)

    Hi @power2009,

    Thanks for the update on your solution, which follows Riaan’s guidance. Have you had a chance to implement it and test it already? Is everything good?

    Is there anything else we can help you with today?

    Thanks!
    -OP

    Thread Starter Marcus Karlos

    (@power2009)

    No.. Files no get Content-Length i dont know why..

    Plugin Support omarfpg a11n

    (@omarfpg)

    Hi @power2009,

    I’m sorry to learn you’re still having problems with this one. I’m afraid that customization is outside of our support scope, though.

    If you still need help with this one it’s best to ask for insight related to it on either the?WooCommerce Advanced Facebook group?or the?WooCommerce Community Slack. Many of our developers hang out there and will be able to offer insights into your question. You can also seek help from the following:

    I wish I could help more, but hopefully, this gets you going in the right direction to get some further insight/information.

    Thanks!
    -OP

    Thread Starter Marcus Karlos

    (@power2009)

    Bug Report: Apache2 + X-Sendfile Not Working with Content-Length

    Issue Description: When using Apache2 with X-Sendfile, files are not being delivered correctly when the Content-Length header is specified. I am planning to try a solution using Nginx to send files with Content-Length, but I’m unsure if it will help resolve the issue.

    Steps Taken to Address the Issue:

    1. Apache2 + X-Sendfile Setup: Configured settings for file delivery via X-Sendfile.
    2. Content-Length Issue: Observed that files fail to deliver properly when the Content-Length header is set.
    3. Consideration of Nginx: Exploring the possibility of switching to Nginx and utilizing its solution for delivering files along with the Content-Length header.

    Current Status: Uncertain if transitioning to Nginx will effectively resolve the file delivery issue when specifying the Content-Length header. Further testing is planned to evaluate the effectiveness of this approach.

    Please understand that investigations are ongoing, and I am focused on finding the optimal solution for this particular issue.

    Plugin Support Shameem R. a11n

    (@shameemreza)

    Hi @power2009

    I recommend that you create an enhancement request in our GitHub repo here. This way, our developer can review it and offer more insights.

    Additionally, it’s best to ask for insight related to those on either the WooCommerce Advanced Facebook group or the WooCommerce Community Slack. Many of our developers hang out there and will be able to offer insights into your question.

    I wish I could help more, but hopefully, this gets you going in the right direction to get some further insight.

    Thread Starter Marcus Karlos

    (@power2009)

    How i can to that PM? Support team?

    Plugin Support Zubair Zahid (woo-hc)

    (@doublezed2)

    Hello Marcus Rob

    Thank you for your reply.

    May I know what you are referring to here?
    Creating an enhancement request in our GitHub repo or getting in touch with Facebook and Slack?

    I will be happy to assist you further. ??

    Best regards.

Viewing 9 replies - 1 through 9 (of 9 total)
  • The topic ‘How add Content-Length to X-Sendfile / X-Accel-Redirect’ is closed to new replies.