Question

I have to stream an ip camera inside a web application. Typically I do this by adding the url to an img tag. The problem this time is that the request requires digest authentication. Because of this, I want to create a proxy method to handle the authentication and stream out the data back to the client. I am currently trying to do this with an HttpHandler.

using System;
using System.Net;
using System.Web;

public class HelloWorldHandler : IHttpHandler
{
    #region IHttpHandler Members

    private const int BUFFERSIZE = 1048576;

    public bool IsReusable
    {
        get { return false; }
    }

    public void ProcessRequest(HttpContext context)
    {
        HttpWebRequest webRequest = null;

        #region Prepare the request object
        webRequest = (HttpWebRequest)WebRequest.Create("http://url/cgi/image.php?type=live");
        webRequest.Method = "GET";
        webRequest.ContentType = "multipart/x-mixed-replace; boundary=------MJPEG FAME--------";
        webRequest.Credentials = new NetworkCredential(username, password);
        #endregion Prepare the request object

        #region Cycle through and return output
        HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();

        // GETS STUCK HEAR FOR OBVIOUS REASONS.  NOT SURE HOW TO BUFFER A CHUNK, STREAM THE CHUNK AND REPEAT
        System.IO.Stream fileStream = webResponse.GetResponseStream();

        Byte[] buffer = new byte[1048576];
        int bytesRead = 1;
        context.Response.ContentType = "image/png";
        while (bytesRead > 0)
        {
            bytesRead = fileStream.Read(buffer, 0, BUFFERSIZE);
            if (bytesRead == BUFFERSIZE)
                context.Response.OutputStream.Write(buffer, 0, buffer.Length);
            else if (bytesRead > 0)
            {
                byte[] endBuffer = new byte[bytesRead];
                Array.Copy(buffer, endBuffer, bytesRead);
                context.Response.OutputStream.Write(endBuffer, 0, endBuffer.Length);
            }
        }

        fileStream.Dispose();
        webResponse.Close();
        #endregion Cycle through and return output
    }

    #endregion
}

If you look at my comments in the code, I have marked the obvious place where the code is failing. When I am getting the response stream, it will never end until an memory exception is thrown. This seems obvious enough but I am not sure how to actually handle the buffer issue. I think I need to be able to buffer a chunk, stream it, buffer anther and repeat.

For reference this an example of the headers when I make a direct connection through a browser.

REQUEST

GET http://url/cgi/image.php?type=live HTTP/1.1
Host: url
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Authorization: Digest something something something

RESPONSE

HTTP/1.1 200 OK
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Content-type: multipart/x-mixed-replace; boundary=------MJPEG FAME--------
Transfer-Encoding: chunked
Date: Mon, 04 Nov 2013 23:39:22 GMT
Server: lighttpd/1.4.28

Any advice would be greatly appreciated.

Thanks,

Chad

Was it helpful?

Solution

As @Aristos mentioned, the key was to set the context.Repsonse.Flush(). Though this part of the problem has been solved, I am now presented with another problem.

I have opened up another thread specific to that problem. https://stackoverflow.com/questions/19849148/is-it-possible-to-close-an-httpcontext-object-that-is-inside-an-httphandler-from

Thanks,

Chad

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top