// Copyright 2005, 2006 - Morten Nielsen (www.iter.dk)
//
// This file is part of SharpMap.
// SharpMap is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// SharpMap is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public License
// along with SharpMap; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
using System.Drawing.Imaging;
using System.IO;
using System.Web;
using Image = System.Drawing.Image;
namespace SharpMap.Web
{
///
/// HttpHandler class for web applications
///
public class HttpHandler : IHttpHandler
{
#region IHttpHandler Members
///
/// Enable Http pooling
///
public bool IsReusable
{
get { return true; }
}
///
/// Returns the requested image in an http imagestream
///
/// HttpContext
public void ProcessRequest(HttpContext context)
{
var imgID = context.Request.QueryString["ID"];
var cached = context.Cache[imgID];
if (cached == null)
{
context.Response.Clear();
context.Response.ContentType = "text/plain";
context.Response.Write("Invalid Image requested");
context.Response.Flush();
context.ApplicationInstance.CompleteRequest();
return;
}
if (cached is byte[])
{
/*
context.Response.ContentType = "image/png";
var buffer = (byte[])cached;
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
*/
WriteResponseInChunks((byte[])cached, context.Response);
context.ApplicationInstance.CompleteRequest();
return;
}
//FObermaier:
// Do we really need to check this, InsertIntoCache does the transformation to
// an array of bytes.
if (cached is Image)
{
//context.Response.ContentType = "image/png";
var b = (Image) cached;
// send the image to the viewer
using (var ms = new MemoryStream())
{
b.Save(ms, ImageFormat.Png);
//Don't tidy up we might need it again. If we want to tidy up we need to update the cached object to the
//the buffer created below. Don't know if that works
//// tidy up
//b.Dispose();
WriteResponseInChunks(ms.ToArray(), context.Response);
context.ApplicationInstance.CompleteRequest();
return;
//var buffer = ms.ToArray();
//context.Response.OutputStream.Write(buffer, 0, buffer.Length);
}
}
}
#endregion
///
/// The size of the chunks written to response.
///
private const int ChunkSize = 2 * 8192;
///
/// Method to write an array of bytes in chunks to a http response
///
///
/// The code was adopted from http://support.microsoft.com/kb/812406/en-us
///
/// The array of bytes
/// The response
private static void WriteResponseInChunks(byte[] buffer, HttpResponse response)
{
try
{
response.ClearContent();
response.ContentType = "image/png";
using (var ms = new MemoryStream(buffer))
{
var dataToRead = buffer.Length;
while (dataToRead > 0)
{
if (response.IsClientConnected)
{
{
var tmpBuffer = new byte[ChunkSize];
var length = ms.Read(tmpBuffer, 0, tmpBuffer.Length);
response.OutputStream.Write(tmpBuffer, 0, length);
response.Flush();
dataToRead -= length;
}
}
else
{
dataToRead = -1;
}
}
}
}
catch (Exception ex)
{
response.ClearContent();
response.ContentType = "text/plain";
response.Write(string.Format("Error : {0}", ex.Message));
response.Write(string.Format("Source : {0}", ex.Message));
response.Write(string.Format("StackTrace: {0}", ex.StackTrace));
}
finally
{
response.Flush();
response.SuppressContent = true;
}
}
}
}