Как пройти через HTTP-вызов с помощью HTTP-обработчика - PullRequest
2 голосов
/ 05 января 2011

Справочная информация:

Мы используем API Facebook и получаем обратные URL-адреса для миниатюр изображений профиля. К сожалению, протокол ограничен только HTTP и не поддерживает HTTPS. Страница на нашем сайте, на которой размещены миниатюры, всегда доставляется по HTTPS, и если мы используем HTTP для миниатюр, пользователь получит предупреждения безопасности от своего браузера.

Решение:

Создание обработчика HTTP, который «пропускает» изображение из URL-адреса Facebook, но позволяет вызывать обработчик через HTTPS. До того, как я начал кодировать, я думал, что смогу что-то вроде этого:

Response.OutputStream = WebRequest.Create(FacebookUrlForThumbnail)

но в итоге мне пришлось сохранить изображение в объекте в памяти, а не записать изображение в Response.OutputStream с помощью функции сохранения изображения.

Текущий код:

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 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

Это кажется неэффективным, но я не могу найти способ использовать обработчик HTTP, как я изначально предполагал. Есть ли способ достичь цели, не создавая память изображения и просто «проходя» вызов?

Ответы [ 3 ]

2 голосов
/ 05 января 2011

Нет смысла создавать Bitmap только для того, чтобы сохранить его в другом потоке.

Вместо этого вам следует скопировать GetResponseStream() непосредственно в context.Response.OutputStream.

В .Net 4.0 вы можете сделать это, используя Stream.CopyTo;в более ранних версиях вам нужно будет скопировать его вручную.

Для повышения производительности отключите буферизацию, чтобы клиент мог сразу начать получать контент.

Кроме того, вы должны установить Content-Type и кэширование заголовков из заголовков, полученных в HttpWebResponse.

1 голос
/ 05 января 2011

То, что вы описываете как «прохождение» (и ваш пример), обычно называют решением «обратного прокси», и я не вижу никаких проблем с ним в принципе.

Вы можете посмотреть на существующие решения.В Интернете есть несколько примеров кода (очень похожих на ваш собственный) http://www.codeproject.com/KB/IP/reverseproxy.aspx

Быстрый поиск в Google показывает, что, если вы просто «пересылаете» запросы, это можно сделать наУровень IIS, требующий от вас писать мало или совсем не писать код (я сам не пробовал) http://blogs.iis.net/carlosag/archive/2010/04/01/setting-up-a-reverse-proxy-using-iis-url-rewrite-and-arr.aspx

Также рассмотрите возможность кэширования изображений, если вы беспокоитесь о производительности.

0 голосов
/ 05 января 2011

Я думаю, вы можете пропустить часть изображения и просто проксировать поток в двоичном формате. Это, вероятно, так же хорошо, как и получится, вам всегда придется использовать некоторый объем памяти в качестве буфера, читать чанк, писать чанк.

...