I recently encountered a problem with Microsoft’s ACT (part of Visual Studio 2003) when testing a web service by emulating a browser-based client. For posterity’s sake, here’s an overview of the problem and, more importantly, the solution.
Background
Using Application Center Test (ACT) to help automate performance testing designed to compare the performance of a web service running on ASP .NET 1.1 with ASP .NET 2.0.
Problem
Originally .NET 2.0 seemed to be performing many times better than .NET 1.1, but it was soon discovered that when running .NET 2.0, ATC was receiving a lot of 302 errors on 2.0 which it wasn’t on 1.0. On further investigation the Web Service wasn’t actually making all the correct database calls and on installing HTTP Monitor, it became apparent that the login wasn’t working. When I recorded the test using Internet Explorer 7, the HTTP requests worked as expected, however when ATC repeated them it was not returning the ASP.NET_SessionID.
Cause
In .NET 2.0 Microsoft introduced a new cookie property as a security measure: HttpOnly. This was appended to the cookie, which apparently confused Application Center Test. Normaly the cookie is only sent to clients that can understand it, but ACT was pretending to be IE7 so it was sent the new property with the cookie. As it couldn’t understand it, it seemingly discarded the whole cookie meaning the SessionID wasn’t sent back on future requests. As a result, every time ACT tried to fetch a URI, it was getting a 302, redirecting it to the login page because the server didn’t know it had logged in.
Solution
In Global.asax, overwrite the Session_Start method as follows.
<script runat="server">
void Session_Start(object sender, EventArgs e) {
if(Response.Cookies.Count > 0)
foreach(string s in Response.Cookies.AllKeys)
if(s == System.Web.Security.FormsAuthentication.FormsCookieName ||
s.ToLower().Equals("asp.net_sessionid") )
Response.Cookies[s].HttpOnly = false;
}
</script>
As it turns out though, the specific web service I was dealing with did not use the SessionID to track sessions and used another cookie variable instead. To deal with this, I also added the following code to remove the HttpOnly attribute from all cookies (NB this could be considered a security risk as all cookies will be exposed to client-side scripts, however in this instance it was utilised only for internal testing ):
void Application_EndRequest(object sender, EventArgs e) {
if (Response.Cookies.Count > 0) {
foreach (string s in Response.Cookies.AllKeys) {
Response.Cookies[s].HttpOnly = false;
}
}
}
I spend a lot of time configuring web.config with httpCookies and requireSSL properties. But nothing worked. Thanks a lot for this blog article. This worked perfectly.