tags:

views:

78

answers:

3

Is there any way to log (record) the time it takes to download a file from a web server via the browser? The file is written on the HDD and the environment is LAMP.

Thanks.

A: 

One way would be to proxy the download via a script (can be achieved easily with mod_rewrite). This means that you need to do all the work like mapping extensions into their corresponding mime-types (for the Content-Type header). Try downloading a file from your browser, and take a look at the headers it sends; you need to mimic those. You can use eg. web-sniffer.net to inspect the headers.

reko_t
To the author of question - now probably AWOL - this answer is also great because if you are planning to do this on multiple filetype's you'll have to check their mime-types and adapt accordingly.
Frankie
A: 

I don't think PHP would have access to this kind of information. I'm not sure if Apache will tell you either, or whether the method below will also time just until the file got dumped into the transmit buffer, but I would suggest you try this:

Define a custom log in which you include the "%D" directive, this gives you "The time taken to serve the request, in microseconds."

Wim
+1  A: 

Sure there is. You will have to either use mod_rewrite to let Apache know the file is to be served by PHP (ask for more instructions if this is your case) or just use a PHP script to fetch the file like this:

http://youserver.com/download.php?filename=mypicture.jpeg

And then you can can have download.php like this:

<?php
// gets the starting time
$time_start = microtime(true);

// WATCHOUT! THIS IS NOT SECURE! EXAMPLE ONLY.
#$filename = $_GET['filename'];

// gets the intro.mp3 file and outputs it to the user
$filename = "intro.mp3";
header('Content-type: audio/mpeg');
header('Content-Length: '.filesize($filename));
header('Content-Disposition: attachment; filename="intro.mp3"');
readfile($filename);

// gets the end time and duration
$time_end = microtime(true);

// write time to hdd, database, whatever
// ...
error_log("Processing time: ". sprintf("%.4f", ($time_end-$time_start))." seconds");
?>

Please do remember that the $filename = $_GET['filename'] is example only and should be properly escaped so that people can't hack into your server.

EDIT:
Altered to check if it really worked - Mark made me question it! ;) Needed minor tweaking (especially on microtime) but yes, it does work!

Frankie
Does this actually work? I thought that would just time it until it got to that point the script...why would it wait for the file to finish sending?
Mark
I had to do just some tweaking and the above code was proof of concept but yes, it does log the time used. PHP is synchronous and, therefore, has to wait for readfile() to go along with its life.
Frankie
PHP may be synchronous in that it waits until readfile() is done, but that doesn't tell you anything about the rest of the stack. Apache may very well (and most likely does) accept the complete file into the server's RAM memory, and send it out slowly until long after readfile(), and your script, have terminated...
Wim
@Wim well just try it... I don't really know how it behaves on PHP running as CGI. With PHP running as an Apache Module Apache and PHP are the same, meaning that PHP will keep timing Apache until it ends. My result was 32 seconds. On my watch I timed 32 seconds. It works.
Frankie
well, it actually work. or so it seems so far. i'll do some more testing and get back to you, but thanks anyway.
Alex
@Alex thank you for reporting back! ;)
Frankie