1

I am trying to add stats to Google Analytics regarding direct accesses of mp3 files (eg by iTunes) on this server. I want to run this PHP function and deliver the file as though there had been no redirection.

The mod_rewrite piece of this seems to be functioning fine. My onsite download scripts and streaming player can access mp3 files without triggering the rule.

RewriteCond %{HTTP_REFERER} !^http://(www\.)?mysite\.com [NC]
RewriteRule ^audio/episodes/([^/\.]+).mp3$ /audio/episodes/google_analytics_mp3.php?mp3=$1&redirected=1 [L,QSA]

However my initial attempt at delivering mp3 after PHP script runs does not deliver file for direct accesses. Just a white screen in a browser and an error in iTunes.

if ($id = intval($_REQUEST['mp3'])) {
    $e = new Episode;
    list($ep) = $e->retrieve("id = $id");   
    if ($ep) { 
        ga_send_pageview(basename($ep->audio_link), $ep->google_title()); 
        if ($_GET['redirected'] == 1) {
            $fileLocation = '/'.$ep->audio_link;
            header("Location: $fileLocation"); 
            exit();
        }
    }
}

Also tried sending header('Content-Type: audio/mpeg'); before the location header. Same result.

My second attempt makes browser download file as attachment which will not work for programs like iTunes and is not desired result.

if ($_GET['redirected'] == 1) {
    $fileName = basename($ep->audio_link); 
    $fileLocation = $_SERVER['DOCUMENT_ROOT'].'/audio/episodes/'.$filename;
    header("Content-Transfer-Encoding: binary"); 
    header("Content-Type: audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3");
    header('Content-length: ' . filesize($fileLocation));
    header('Content-Disposition: attachment; filename="'.$fileName.'"');
    header('X-Pad: avoid browser bug');
    header('Cache-Control: no-cache');
    readfile($fileLocation);
    exit();
}

Update: Per Martin's suggestion also tried this second approach but with disposition set to inline header('Content-Disposition: inline; filename="'.$fileName.'"'); but Chrome just shows white screen. If I disable rule to remove script from equation Chrome will show native mp3 player and play file.

How can I simply allow the normal access to mp3 file after PHP script runs?

jerrygarciuh
  • 21,158
  • 26
  • 82
  • 139
  • Utilize a cookie. – Daniel W. Dec 13 '16 at 16:51
  • try `Content-Disposition: inline` to load the Mp3 into the browser or into iTunes directly rather than forcing it as a download. – Martin Dec 13 '16 at 16:51
  • @Martin to which approach? With location header or second approach ? – jerrygarciuh Dec 13 '16 at 16:53
  • I was understanding that ITunes was calling your script but not able to load your mp3? I was offering the idea that as the data is set as an attachment this would clash with what ITunes expects? – Martin Dec 13 '16 at 16:59
  • Gotcha. I tried just now changing attachment to inline ` header('Content-Disposition: attachment; filename="'.$fileName.'"');` and browser has same response to direct access- white screen. Once rule is disabled taking script out of middle mp3 shows in Chrome's native player. – jerrygarciuh Dec 13 '16 at 17:05
  • Yes, no errors are being logged from this. Digging more, going to add some output to dump what script is seeing... – jerrygarciuh Dec 13 '16 at 17:18
  • I take it that solved it. Awesome :) – Martin Dec 13 '16 at 17:20

1 Answers1

1

I have previously had issues with Content-length: , you can try commenting out this line. I think the filesystem filesize reader is different from the browser filesize quantifier so the browser expects (and gets) 99% of the file which is obviously then incomplete so then it can't output the file as it perceives it as incomplete data.

File System File Size as read !== browser file size 

However I'm not certain why this is so .

Martin
  • 22,212
  • 11
  • 70
  • 132
  • @jerrygarciuh edit as an additional : [filesize inconsistency](http://stackoverflow.com/a/2429162/3536236) – Martin Dec 13 '16 at 17:25