开发者

How to pass through http call with HTTP Handler

Background:

We are using the Facebook API and receive back URLs for profile image thumbnails. Unfortunately the protocol is restricted to just HTTP and it doesn't support HTTPS. The page on our site that hosts the thumbnails is always delivered via HTTPS, and if we use HTTP for the thumbnails the user will receive security warnings from their browser.

Solution:

Build an HTTP Handler that "passes through" the image from the Facebook URL, but allow the handler to be called via HTTPS. Before I started coding I thought I could something like this:

Response.OutputStream = WebRequest.Create(FacebookUrlForThumbnail)

but I ended up having to save the image to an object in memory than write the image to the Response.OutputStream using the image save function.

Current Code:

Public Class FBImageHttpHandler
    Implements System.Web.IHttpHandler

    Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        Dim profilePath As String = context.Request.QueryString("profilepath")
        Dim request As WebRequest = Nothing
        Dim image As System.Drawing.Bitmap = Nothing
        Dim errorMessage As String
        Dim profileDomain As开发者_Go百科 String

        Try
            profileDomain = "http://[Facebook-Image-Domain].com/"

            If profilePath.ToLower.EndsWith(".jpg") = True Then
                request = WebRequest.Create(profileDomain & profilePath)

                If (request.GetResponse().ContentLength > 0) Then
                    context.Response.ContentType = "image/jpeg"

                    image = New System.Drawing.Bitmap(request.GetResponse().GetResponseStream())
                    image.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
                End If
            End If
        Catch ex As Exception
            ' Ignore Error
            ' Log Error - Removed Logging Code   
        Finally
            If request IsNot Nothing Then
                request = Nothing
            End If

            If image IsNot Nothing Then
                image.Dispose()
                image = Nothing
            End If
        End Try
    End Sub

    ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property

End Class

This seems inefficient but I can't find a way of using the HTTP Handler as I orginally intended. Is there way of accomplishing the goal without creating the image memory and just "passing through" the call?


There is no point in creating a Bitmap just to save it to a different stream.

Instead, you should copy the GetResponseStream() directly to context.Response.OutputStream.

In .Net 4.0, you can do this using Stream.CopyTo; in earlier versions, you'll need to copy it by hand.

For improved performance, disable buffering so that the client can start receiving content immediately.

Also, you should set your Content-Type and caching headers from the headers received in the HttpWebResponse.


What you describe as "passing through" (and your example) is commonly refered to as a 'reverse proxy' solution, and I see no problem with it in principle.

You could look at existing solutions. There are a few code examples on the web (much like your own) http://www.codeproject.com/KB/IP/reverseproxy.aspx

A quick google search suggest that if you're just 'forwarding' the requests, it may be possible to do this at the IIS level, requiring you to write little to no code to (I have not tried this out myself) http://blogs.iis.net/carlosag/archive/2010/04/01/setting-up-a-reverse-proxy-using-iis-url-rewrite-and-arr.aspx

Also consider caching the images, if you are worried about performance.


I would guess that you could skip the image part, and just proxy the stream in binary format. That is likely as good as it will get, you'll always have to use some amount of memory as a buffer, read a chunk, write a chunk.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜