2010-07-13 1 views
4

ОбзорКак я могу изменить запрос POST с помощью пользовательского IHttpModule и фильтра HttpRequest?

Я хочу, чтобы иметь возможность изменять параметры запроса и контент 3-участник веб-службы (ArcGIS Server). Это будет использоваться для создания уровня безопасности, который существует между любым клиентским приложением и серверным приложением.

Я думаю, что я нашел решение, но в настоящее время я испытываю определенные трудности при реализации.

Потенциальное решение: Изменить запрос с фильтром пользовательского запроса

Для решения я реализовал пользовательский фильтр запроса свободно на основе sample shown on MSDN. Я «улучшил» код, чтобы я мог искать и заменять необходимый контент с помощью регулярных выражений. Это включает в себя:

  1. Преобразование содержимого (хранимого в массиве байтов) в строку.
  2. Поиск строки и выполнение любых необходимых изменений.
  3. Преобразование измененной строки в массив байтов и запись ее в буфер.

Пример приведен ниже:

public override int Read(byte[] buffer, int offset, int count) 
{ 
    int bytesRead = _stream.Read(buffer, offset, count); 

    string orgContent = Encoding.UTF8.GetString(buffer, offset, bytesRead); 
    string orgContentDecoded = HttpUtility.UrlDecode(orgContent); 

    string layersPattern = @"&layers=(show|hide|include|exclude):([0-9]+,?)+"; 
    Regex layersRegex = new Regex(layersPattern, RegexOptions.IgnoreCase); 

    string[] permittedLayers = new string[] { "0" , "1" }; 
    string replacementLayers = "&layers=show:" + String.Join(",", permittedLayers); 
    string newContentDecoded = layersRegex.Replace(orgContentDecoded, replacementLayers); 

    string newContent = newContentDecoded.Replace(",", "%2C").Replace(":", "%3A"); 

    byte[] newBuffer = Encoding.UTF8.GetBytes(newContent); 
    int newByteCountLength = Encoding.UTF8.GetByteCount(newContent); 

    Encoding.UTF8.GetBytes(newContent, 0, Encoding.UTF8.GetByteCount(newContent), buffer, 0); 

    return bytesRead; 
} 

Это, кажется, работает хорошо до тех пор, как модифицированная длина содержание не отличается от первоначальной длины содержимого. Например, если я заменю 1 на 2, все будет работать. Однако, если я заменил 1 на 10 (тем самым увеличив размер сообщения на 1), тогда я получаю сообщение об ошибке от ArcGIS Server, что формат не поддерживается.

Это принесло две проблемы в мое внимание:

  1. Текущая реализация не обрабатывает Chunked запросы. То есть, если запрос sie достаточно велик, Read может быть вызван несколько раз для одного запроса. Как следует обрабатывать в этом сценарии?
  2. В чем причина сообщения об ошибке? Является ли проблема связана с длиной содержимого, отличной от длины потока? Как правильно изменить содержимое, чтобы не изменять его длину?

Любые мысли?

ответ

4

Ответ на часть второй этого вопроса заключается в том, чтобы вернуть измененный размер содержимого, а не размер исходного потока. Вот!

// return bytesRead; 
return newByteCountLength; 
2

Этот вопрос и ваш ответ был очень полезным для меня, однако ответ не вся история, если вы пытаетесь вставить большие объемы данных в поток:

Возвращение измененного размера содержимого действует только в том случае, если данные, которые вы вставляете в поток, не будут принимать количество байтов, считанных в буфер, по значению count.Если вы попытаетесь вставить слишком много данных, вы либо обнаружите, что объект buffer недостаточно велик, чтобы хранить данные, которые вы вставляете, или что, записывая в буфер более count байт, вы переписываете некоторые данные в конце буфера, который должен был остаться один.

Если вам нужно вставить больше данных, чем может разместить текущий объект buffer, вам необходимо будет буферизовать данные в отдельном массиве байтов и скопировать его в куски по мере вызова вызовов stream.read.

0

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

https://github.com/snives/HttpModuleRewrite

Кроме того, для вопросов, связанных с устранением неполадок HttpModules для фильтрации этого поста был очень полезным Is it possible to modify the content of HttpRequest POST in an IIS HttpModule?

 Смежные вопросы

  • Нет связанных вопросов^_^