public static bool RequestAcceptsGZip(HttpRequest request)
{
return (!String.IsNullOrEmpty(request.Headers["Accept-encoding"]) && (request.Headers["Accept-encoding"].IndexOf("gzip") != -1));
}
public static void RespondBuffered(HttpRequest request, HttpResponse response, Stream s, int bufferSize)
{
try
{
if (bufferSize < 1) bufferSize = 1024 * 1024; // Default buffer size: 1MB byte[] buffer = new byte[bufferSize]; int byteCountBuffer = 0; int byteCountZipped = 0; long readPosition = 0; long writePosition = 0; response.Buffer = false; response.BufferOutput = false; if (response.ContentType.IndexOf("video") > -1)
{
try
{
response.Headers.Remove("Content-disposition");
}
catch (Exception)
{
}
}
response.AddHeader("Accept-Ranges", "bytes");
MemoryStream zippedStream = null;
Stream zipStream = null;
bool useGZip = false;
string contentType = response.ContentType.Split(new char[] { ';' })[0].ToLower();
if (_contentTypesToGZip.Contains(contentType) && RequestAcceptsGZip(request))
{
useGZip = true;
}
if (useGZip)
{
ResponseAddGZip(response);
zippedStream = new MemoryStream();
zipStream = new GZipStream(zippedStream, CompressionMode.Compress, true);
}
if (useGZip)
{
// with gzip the exact content length is unknown
while ((byteCountBuffer = s.Read(buffer, 0, buffer.Length)) > 0)
{
zipStream.Write(buffer, 0, byteCountBuffer);
zipStream.Flush();
if (response.OutputStream.CanWrite && response.IsClientConnected)
{
writePosition = zippedStream.Position;
zippedStream.Position = readPosition;
while ((byteCountZipped = zippedStream.Read(buffer, 0, buffer.Length)) > 0)
{
response.OutputStream.Write(buffer, 0, byteCountZipped);
response.OutputStream.Flush();
readPosition += byteCountZipped;
}
zippedStream.Position = writePosition;
}
else
{
break;
}
}
zipStream.Close(); // Close the zip stream
zippedStream.Position = readPosition; // We left the zipped stream OPEN, see new GZipStream(..., true)
while ((byteCountZipped = zippedStream.Read(buffer, 0, buffer.Length)) > 0) // Read the last 11 bytes that indicate the gzip stream is closed
{
response.OutputStream.Write(buffer, 0, byteCountZipped);
response.OutputStream.Flush();
}
}
else
{
bool useRange = false;
Int64 rangeStart = 0;
Int64 rangeEnd = s.Length - 1;
if (request.Headers["Range"] != null)
{
string rangeHeader = request.Headers["Range"];
// multiple byte ranges not supported
if (!rangeHeader.Contains(","))
{
//LogHelper.LogInformation("ContentRanges", "RangeRequest", request.ServerVariables["ALL_RAW"]);
string[] parts = rangeHeader.Split(new char[] { '=', '-' });
if (parts.Length >= 2)
{
Int64.TryParse(parts[1], out rangeStart);
if (parts.Length > 2 && parts[2] != "")
{
Int64.TryParse(parts[2], out rangeEnd);
}
else
{
rangeEnd = s.Length - 1;
}
if (rangeEnd > rangeStart)
{
useRange = true;
response.StatusCode = 206; // Partial request
try
{
string contentRangeHeader = String.Format("bytes {0}-{1}/{2}", rangeStart, rangeEnd, s.Length);
response.Headers.Add("Content-Range", contentRangeHeader);
}
catch (Exception e)
{
DCMSEventLogHelper.LogException(CMSContext.CurrentSiteID, "ContentRanges", e);
}
}
}
}
}
long responseLength = 0;
try
{
responseLength = s.Length;
if (useRange)
{
responseLength = (rangeEnd - rangeStart);
}
}
catch (NotSupportedException) { }
if (responseLength != 0)
{
try
{
response.AppendHeader("Content-Length", responseLength.ToString());
response.AppendHeader("Accept-Ranges", String.Format("{0}-{1}", 0, s.Length - 1));
}
catch (HttpException) { }
}
if (!useRange)
{
while ((byteCountBuffer = s.Read(buffer, 0, buffer.Length)) > 0)
{
if (response.OutputStream.CanWrite && response.IsClientConnected)
{
response.OutputStream.Write(buffer, 0, byteCountBuffer);
response.OutputStream.Flush();
}
else
{
break;
}
}
}
else
{
s.Position = rangeStart;
while ((byteCountBuffer = s.Read(buffer, 0, buffer.Length)) > 0)
{
if (response.OutputStream.CanWrite && response.IsClientConnected)
{
if (s.Position + byteCountBuffer > rangeEnd)
{
byteCountBuffer = (int)(buffer.Length + rangeEnd - s.Position);
}
response.OutputStream.Write(buffer, 0, byteCountBuffer);
response.OutputStream.Flush();
}
else
{
break;
}
if (s.Position > rangeEnd)
{
break;
}
}
}
}
}
catch (Exception e)
{
if (e is HttpException)
{
// Ignore
}
else
{
//LogHelper.LogException(CMSContext.CurrentSiteID, "ContentRanges", e);
}
}
finally
{
// Make sure the input stream is disposed early
s.Dispose();
if (response.IsClientConnected && response.OutputStream != null)
{
if (response.OutputStream.CanWrite)
{
response.OutputStream.Flush();
}
response.OutputStream.Close();
}
}
}
public static void RespondBufferedBytes(HttpRequest request, HttpResponse response, byte[] content)
{
RespondBufferedBytes(request, response, content, -1);
}
public static void RespondBufferedBytes(HttpRequest request, HttpResponse response, byte[] content, int bufferSize)
{
using (MemoryStream ms = new MemoryStream(content))
{
RespondBuffered(request, response, ms, bufferSize);
}
}
public static void RespondBufferedFile(HttpRequest request, HttpResponse response, string fileName)
{
RespondBufferedFile(request, response, fileName, -1);
}
public static void RespondBufferedFile(HttpRequest request, HttpResponse response, string fileName, int bufferSize)
{
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
RespondBuffered(request, response, fs, bufferSize);
}
}
public static void RespondBufferedString(HttpRequest request, HttpResponse response, string content)
{
RespondBufferedString(request, response, content, -1);
}
public static void RespondBufferedString(HttpRequest request, HttpResponse response, string content, int bufferSize)
{
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(content)))
{
RespondBuffered(request, response, ms, bufferSize);
}
}
public static void ResponseAddGZip(HttpResponse response)
{
response.AppendHeader("Content-encoding", "gzip");
response.Cache.VaryByHeaders["Accept-encoding"] = true;
}
11100cookie-checkC# Implementing Accept-Ranges