Как сжимать HTTP-запросы из WCF .NET на транспортном уровне? - PullRequest
7 голосов
/ 11 декабря 2010

Мне удалось включить входящее HTTP-сжатие в ASP.NET (т. Е. Сжатие HTTP запросов , а не только ответов), но сейчас я борюсь на стороне клиента (C # /Приложение .NET 4.0).

Я хотел бы:

  • добавить заголовок HTTP Content-Encoding: gzip
  • сжимать тело HTTP с помощью GZip

ко всем исходящим HTTP-запросам, отправляемым каналом WCF.

Решения, которые пока не работают :

  • с IClientMessageInspector Я могу сжатьсообщение, но оно не учитывает всего тела HTTP, поскольку конверт не сжат.
  • то же самое для пользовательского кодировщика сообщений, сжатие сообщения не конверт, не влияет на заголовки HTTP-запроса.

Есть идеи, как имитировать поведение IHttpModule (см. Первоначальный ответ) на стороне клиента?

Ответы [ 2 ]

5 голосов
/ 13 декабря 2010

Кодировщик сообщений, описанный здесь , должен выполнить эту работу.

Я проверил, используя образец, загруженный по ссылке, доступной в статье выше (проект InstallDrive \ WF_WCF_Samples \ WCF \ Extensibility \ MessageEncoder \ Compression из this ) и Fiddler.

Обратите внимание, что в образце MSDN есть ошибка, которую вам нужно будет исправить, чтобы она правильно работала.В классе GZipMessageEncoderFactory, метод CompressBuffer, следующую строку

ArraySegment<byte> byteArray = new ArraySegment<byte>(bufferedBytes, messageOffset, bufferedBytes.Length - messageOffset);

следует заменить на

ArraySegment<byte> byteArray = new ArraySegment<byte>(bufferedBytes, messageOffset, totalLength);

. После применения вышеуказанного исправления все тело сообщения будет сжато.

Чтобы проверить правильность сжатия, вы можете использовать опцию AutoDecode из Fiddler.Однако AutoDecode распаковывает сообщение только в том случае, если оно имеет заголовок HTTP Content-Encoding: gzip.

Добавление заголовков HTTP к вызовам сообщений WCF не является прямой задачей, поскольку WCF был спроектирован так, чтобы быть независимым от транспорта, и приложения WCF не должны обрабатывать элементы, специфичные для определенного метода транспорта.

Однако для целей этого приложения я смог сделать это, используя следующий фрагмент кода:

public string Echo(string input)
{
    using (OperationContextScope opScope = new OperationContextScope((IContextChannel)base.Channel))
    {
        HttpRequestMessageProperty reqProps = new HttpRequestMessageProperty();
        reqProps.Headers["Content-Encoding"] = "gzip";
        OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = reqProps;

        return base.Channel.Echo(input);
    }
}

Echo - это один из методов клиента из образца MSDN и внутри него.Я получаю доступ к текущему контексту операции, чтобы добавить HTTP-заголовок.

Пожалуйста, дайте мне знать, если вам нужна дополнительная помощь.

0 голосов
/ 24 мая 2013

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

...