Trouble determining proper decoding of a REST response from an ArcGIS REST service using IHttpModule
- by Ryan Taylor
First a little background on what I am trying to achieve.
I have an application that is utilizing REST services served by ArcGIS Server and IIS7. The REST services return data in one of several different formats. I am requesting a JSON response. I want to be able to modify the response (remove or add parameters) before the response is sent to the client.
However, I am having difficulty converting the stream to a string that I can modify. To that end, I have implemented the following code in order to try to inspect the stream.
SecureModule.cs
using System;
using System.Web;
namespace SecureModuleTest
{
public class SecureModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(OnBeginRequest);
}
public void Dispose()
{
}
public void OnBeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication) sender;
HttpContext context = application.Context;
HttpRequest request = context.Request;
HttpResponse response = context.Response;
response.Filter = new ServicesFilter(response.Filter);
}
}
}
ServicesFilter.cs
using System;
using System.IO;
using System.Text;
namespace SecureModuleTest
{
class ServicesFilter : MemoryStream
{
private readonly Stream _outputStream;
private StringBuilder _content;
public ServicesFilter(Stream output)
{
_outputStream = output;
_content = new StringBuilder();
}
public override void Write(byte[] buffer, int offset, int count)
{
_content.Append(Encoding.UTF8.GetString(buffer, offset, count));
using (TextWriter textWriter = new StreamWriter(@"C:\temp\content.txt", true))
{
textWriter.WriteLine(String.Format("Buffer: {0}", _content.ToString()));
textWriter.WriteLine(String.Format("Length: {0}", buffer.Length));
textWriter.WriteLine(String.Format("Offset: {0}", offset));
textWriter.WriteLine(String.Format("Count: {0}", count));
textWriter.WriteLine("");
textWriter.Close();
}
// Modify response
_outputStream.Write(buffer, offset, count);
}
}
}
The module is installed in the /ArcGIS/rest/ virtual directory and is executed via the following GET request.
http://localhost/ArcGIS/rest/services/?f=json&pretty=true
The web page displays the expected response, however, the text file tells a very different (encoded?) story.
Expect Response
{"currentVersion" : "10.0",
"folders" : [],
"services" : [
]
}
Text File Contents
Buffer: ? ?`I?%&/m?{J?J??t??`$?@??????iG#)?*??eVe]f@????{???{???;?N'????\fdl??J??!????~|?"~?G?u]???'?)??G?????G??7N????W??{?????,??|?OR????q?
Length: 4096
Offset: 0
Count: 168
Buffer: ? ?`I?%&/m?{J?J??t??`$?@??????iG#)?*??eVe]f@????{???{???;?N'????\fdl??J??!????~|?"~?G?u]???'?)??G?????G??7N????W??{?????,??|?OR????q?K???!P
Length: 4096
Offset: 0
Count: 11
Interestingly, Fiddler depicts a similar picture.
Fiddler Request
GET http://localhost/ArcGIS/rest/services/?f=json&pretty=true HTTP/1.1
Host: localhost
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.70 Safari/533.4
Referer: http://localhost/ArcGIS/rest/services
Cache-Control: no-cache
Pragma: no-cache
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: a=mWz_JFOusuGPnS3w5xx1BSUuyKGB3YZo92Dy2SUntP2MFWa8MaVq6a4I_IYBLKuefXDZANQMeqvxdGBgQoqTKz__V5EQLHwxmKlUNsaK7do.
Fiddler Response - Before Clicking Decode
HTTP/1.1 200 OK
Content-Type: text/plain;charset=utf-8
Content-Encoding: gzip
ETag: 719143506
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Thu, 10 Jun 2010 01:08:43 GMT
Content-Length: 179
????????`I?%&/m?{J?J??t??`$?@??????iG#)?*??eVe]f@????{???{???;?N'????\fdl??J??!????~|?"~?G?u]???'?)??G?????G??7N????W??{?????,??|?OR????q?K???!
P???
Fiddler Response - After Clicking Decode
HTTP/1.1 200 OK
Content-Type: text/plain;charset=utf-8
ETag: 719143506
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Thu, 10 Jun 2010 01:08:43 GMT
Content-Length: 80
{"currentVersion" : "10.0",
"folders" : [],
"services" : [
]
}
I think that the problem may be a result of compression and/or chunking of data (this might be why I am receiving two calls to ServicesFilter.Write(...), however, I have not yet been able to solve the issue.
How might I decode, unzip, and otherwise convert the byte stream into the string I know it should be for modification by my filter?