Overview
I want to be able to modify request parameters and content to 3rd party web services (ArcGIS Server). This will be used to create a security layer that exists between any client application and the server application.
I think that I have found a solution but I am current having some difficulties in the implementation.
Potential Solution: Modify Request with a Custom Request Filter
For the solution I implemented a custom request filter loosely based on the sample shown on MSDN. I have 'enhanced' the code so that I can search and replace the necessary content using regular expressions. This involves:
An example is shown below:
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;
}
This seems to work well so long as the modified content length is not different than the original content length. For instance, if I replace a 1 with a 2 everything works. However, if I replace a 1 with a 10 (thereby increasing the message size by 1) then I receive an error from ArcGIS Server that the format is unsupported.
This has brought two concerns to my attention:
Any thoughts?
The answer to part two of this question is to return the modified content size, not the size of the original stream. Behold!
// return bytesRead;
return newByteCountLength;