Truncated MP3s

One of my hosting clients — who is on a dedicated server — recently reported a strange problem: Some readers of their site were getting truncated downloads on MP3 files. Eventually we nailed the problem down to users of FireFox on Windows and Mac. FireFox for Linux was fine, and other browsers were fine as well.

After a testing splurge and much hunch following, we were able to eliminate upload methods, MP3 encoding tools, and MIME types as potential culprits. But neither I nor the data center are having any luck figuring out what actually is causing it. Google ain’t helping. Here are two links to bit-identical files on two different Linux servers:

One version on Birdhouse
Another version on Newwest

In both cases, the file is 5497828 bytes, permissions are the same, the MIME type is the same (and correct), and the file command reports:

StupidMistakes.mp3: MP3 file with ID3 version 2.2.0 tag

Both were put in place with wget from the same source. But if you’re using FF Win or Mac, the second link will appear to work, but give you only a few seconds of audio.

Theories welcome.

Music: Captain Beefheart :: Magic Be

7 Replies to “Truncated MP3s”

  1. I took this opportunity to play with the LiveHTTPHeaders Firefox plugin. I don’t know if it will help, but here’s what I found:

    From BirdHouse:

    http://birdhouse.org/StupidMistakes.mp3

    GET /StupidMistakes.mp3 HTTP/1.1

    Host: birdhouse.org

    User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4

    Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 300
    Connection: keep-alive
    Referer: http://www.blog.birdhouse.org/
    Cookie: PHPSESSID=497cd37080007846e4c5b4ba15233084
    HTTP/1.x 200 OK
    Date: Sat, 17 Jun 2006 14:38:35 GMT
    Server: Apache/1.3.34 (Unix) DAV/1.0.3 mod_auth_passthrough/1.8 mod_log_bytes/1.2 mod_bwlimited/1.4 PHP/4.4.1 FrontPage/5.0.2.2635 mod_ssl/2.8.25 OpenSSL/0.9.7a
    Last-Modified: Thu, 01 Jun 2006 08:51:12 GMT
    Etag: “7312016-53e3e4-447eaa80”
    Accept-Ranges: bytes
    Content-Length: 5497828
    Keep-Alive: timeout=15, max=100
    Connection: Keep-Alive
    Content-Type: audio/mpeg

    And, from Newwest:

    http://newwest.net/MP3s/StupidMistakes.mp3

    GET /MP3s/StupidMistakes.mp3 HTTP/1.1

    Host: newwest.net

    User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4

    Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 300
    Connection: keep-alive
    Referer: http://www.blog.birdhouse.org/
    HTTP/1.x 200 OK
    Date: Sat, 17 Jun 2006 14:39:48 GMT
    Last-Modified: Thu, 01 Jun 2006 08:51:12 GMT
    Etag: “1ac00c-53e3e4-c51fa000”
    Accept-Ranges: bytes
    Vary: Accept-Encoding,User-Agent
    Content-Encoding: gzip
    Keep-Alive: timeout=15, max=100
    Connection: Keep-Alive
    Transfer-Encoding: chunked
    Content-Type: audio/mpeg

    Maybe firefox is not handling the chunked transfer-encoding correctly? Or, maybe Firefox IS handling it correctly, and the other browsers are not…

  2. Hey Gilbert –

    Great tip on the livehttpheaders extension. I had been using the simpler one built into the web developer’s extension, but this is far more detailed.

    I also had noticed the difference in the chunked vs gzipped encoding, and will be looking into that. Thanks!

  3. Scot,

    Try turning off gzip compression for mp3 files on the newwest.net server. It’s pointless anyway. Google seems to think that the following line should do the trick :
    SetEnvIfNoCase Request_URI \.mp3$ no-gzip dont-vary

    Explanation: I just made a few tests, watching the traffic with Ethereal and disk activity with Filemon. The problem is clearly caused by the QuickTime plug-in (or the way FF talks to it), since :
    – right-click/”save as” saves a perfectly good MP3 file;
    – clear the FF cache then left-click the link: the QT plug-in takes over and plays only a few seconds of the MP3; but you can notice (if your connection is not too fast) that even after QT has stopped playing, FF is still “Transferring data” for a few seconds : indeed a perfect copy of the MP3, *gzipped*, lands in the FF cache.
    – when the QT plug-in is visible, refresh the page : this causes a conditional GET by FF, answered with a 304 Not Modified by the server. And yet QT still stops after a few seconds ! The MP3 comes from the FF cache (which we already determined to be correct) in this case so the server clearly is not the culprit (notably, this rules out the possibility that the “chunked” transfer-encoding caused the problem). No, but FF did save the MP3 as gzipped in its cache… it looks like the QT plug-in is not able to fully handle gzipped content. Sounds like this bug in the Acrobat plug-in : https://bugzilla.mozilla.org/show_bug.cgi?id=224296

    Hope this helps,
    –Jonathan

  4. I tried the second link using Win XP and Firefox 1.5.0.4 and let it play in browser instead of right clicking to download as I usually might, and the song played completely. Beautiful song.

  5. Jonathan, you’re brilliant! The SetEnv directive solved the problem. Currently set in .htaccess for the directory; we’ll talk about setting it server-wide.

    Many, many thanks. I owe you a bottle of wine.

  6. I know this is an old post, but we had a similar problem and this post helped us out.

    One small difference though (which might help others). Because we are serving files via PHP which pulls BLOBs from a MySQL database, we also had to set the correct Content-Length HTTP header as well.

    So it seems the requirements for playing MP3s in Firefox using the Quicktime plugin are:

    * Turn off compression – in PHP we turned off mod_deflate for the PHP file using: apache_setenv(‘no-gzip’, ‘1’);

    * Make sure the correct Content-Length header is set – when serving BLOBs from a MySQL database this can be achieved using mysql function SELECT OCTET_LENGTH(`blob_column`) AS `filesize`) or by doing a strlen() on the variable holding the data in PHP.

  7. in apache httpd.conf set:

    Header unset Content-Length

    compressing content messes up content length headers, so delete them and DEFLATE/GZIP will rewrite them correctly.

Leave a Reply

Your email address will not be published.