Обзор
Я хочу иметь возможность изменять параметры запроса и контент для сторонних веб-сервисов (ArcGIS Server). Это будет использоваться для создания уровня безопасности, который существует между любым клиентским приложением и серверным приложением.
Я думаю, что нашел решение, но в настоящее время у меня есть некоторые трудности в реализации.
Потенциальное решение: изменить запрос с помощью пользовательского фильтра запросов
Для решения я реализовал пользовательский фильтр запросов, основанный на образце , показанном в MSDN . Я «усовершенствовал» код, чтобы я мог искать и заменять необходимый контент с помощью регулярных выражений. Это включает в себя:
- Преобразование содержимого (хранящегося в байтовом массиве) в строку.
- Поиск строки и выполнение любых необходимых изменений.
- Преобразование измененной строки в байтовый массив и запись его в буфер.
Пример показан ниже:
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, что формат не поддерживается.
Это привлекло мое внимание к двум проблемам:
- Текущая реализация не обрабатывает фрагментированные запросы. То есть, если запрос sie достаточно большой, Read может быть вызван несколько раз для одного запроса. Как следует обрабатывать фрагменты в этом сценарии?
- Что является основной причиной сообщения об ошибке? Проблема связана с длиной контента, отличной от длины потока? Как правильно изменить содержимое, чтобы изменение его длины не было проблемой?
Есть мысли?