public void ReplyWithFileContent(string path)
{
//Deal with BL-3153, where the file was still open in another thread
FileStream fs;
if(!RobustFile.Exists(path))
{
//for audio, at least, this is not really an error. We constantly are asking if audio already exists for the current segment
//enhance: maybe audio should go through a different path, e.g. "/bloom/audio/somefile.wav"
//then this path COULD write and error
//Logger.WriteError("Server could not find" + path);
_actualContext.Response.StatusCode = 404;
return;
}
try
{
fs = RobustFile.OpenRead(path);
}
catch(Exception error)
{
Logger.WriteError("Server could not read " + path, error);
_actualContext.Response.StatusCode = 500;
return;
}
using(fs)
{
_actualContext.Response.ContentLength64 = fs.Length;
_actualContext.Response.AppendHeader("PathOnDisk", HttpUtility.UrlEncode(path));
//helps with debugging what file is being chosen
// A HEAD request (rather than a GET or POST request) is a request for just headers, and nothing can be written
// to the OutputStream. It is normally used to check if the contents of the file have changed without taking the
// time and bandwidth needed to download the full contents of the file. The 2 pieces of information being returned
// are the Content-Length and Last-Modified headers. The requestor can use this information to determine if the
// contents of the file have changed, and if they have changed the requestor can then decide if the file needs to
// be reloaded. It is useful when debugging with tools which automatically reload the page when something changes.
if(_actualContext.Request.HttpMethod == "HEAD")
{
var lastModified = RobustFile.GetLastWriteTimeUtc(path).ToString("R");
// Originally we were returning the Last-Modified header with every response, but we discovered that this was
// causing Geckofx to cache the contents of the files. This made debugging difficult because, even if the file
// changed, Geckofx would use the cached file rather than requesting the updated file from the localhost.
_actualContext.Response.AppendHeader("Last-Modified", lastModified);
}
else
{
var buffer = new byte[1024*512]; //512KB
int read;
while((read = fs.Read(buffer, 0, buffer.Length)) > 0)
_actualContext.Response.OutputStream.Write(buffer, 0, read);
}
}
_actualContext.Response.OutputStream.Close();
HaveOutput = true;
}