So I asked a question a while back about securing downloads using C# (http://stackoverflow.com/questions/2178984/securing-large-downloads-using-c-and-iis-7) and I got some great advice on how to do it (involving reading the file into memory and then writing it to the user). The only problem is, now that I'm trying to implement some basic logging, I'm hitting a brick wall. Here's the code to stream a file:
public void StreamFile(string file_path)
{
DateTime start;
TimeSpan ts;
FileStream fstream;
string filename = Path.GetFileName(file_path);
byte[] buffer = new byte[STREAM_BUFFER_SIZE];
int count = 1, total = 0, seconds;
// Open the file to read
fstream = new FileStream("D:\\" + file_path, FileMode.Open, FileAccess.Read);
// Set up the response headers
Response.AddHeader("Content-Length", fstream.Length.ToString());
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
Response.ContentType = "application/octet-stream";
// If the user agent is Internet Explorer, we add one last header
if (Request.UserAgent.Contains("MSIE"))
Response.AddHeader("Content-Transfer-Encoding", "binary");
// Start counting the time
start = DateTime.Now;
// Now, until the client disconnects, we stream the file
while (Response.IsClientConnected)
{
// Read the file into the buffer
count = fstream.Read(buffer, 0, buffer.Length);
// If the buffer is empty, break out of the loop. We're done!
if (count == 0)
break;
// Write to the output stream and push it to the user
Response.OutputStream.Write(buffer, 0, count);
Response.Flush();
// Increment the total as well, this way we can know how much we've streamed
total += count;
}
// The transfer is done! Close the connection.
Response.Close();
// Count the number of seconds
ts = DateTime.Now - start;
seconds = ts.Seconds + (60 * ts.Minutes) + (60 * 60 * ts.Hours); // Also, is there a better way to do this? This is laaaaaame!
// Finally, log the transfer
Logging.AddLog(Request["user"], file_path, total, count == 0, seconds);
}
Ok, so the problem is, the log entries that this is creating say that the file completed in the number of seconds it took to read the file into memory, not for the user to download it. I assumend that Response.ClientConnected would take care of that, but apparently not. So the time to download the file as reported by the logs is 0-1 seconds, and even when I stop a download part way through, the logs say it provided the whole thing.
Anyone done anything like this before, or any ideas how I can get the REAL numbers behind the transfer? Having this information is a huge priority, unfortunately, or I'd just shrug it off and remove those two values from the logging altogether.