J
Jason Collins
There seems to be an inconsistency (bug?) in the way the Set-Cookie header
is handled by the WebHeaderCollection. That is, the values of Set-Cookie,
when an Expires is specified, contain the "," character. This seems to be
incorrectly parsed during GetValues().
A simple example shows it best (there are 2 .aspx pages and an output):
AddHeaders.aspx:
<%@ Page language="c#" %>
<html>
<body>
<script language=C# runat=server>
private void Page_Load(object sender, System.EventArgs e)
{
Response.AddHeader("No-comma", "value1");
Response.AddHeader("No-comma", "value2");
Response.AddHeader("Comma", "a,b");
Response.AddHeader("Comma", "c,d");
HttpCookie c1 = new HttpCookie("n1", "v1");
c1.Expires = DateTime.Now.AddHours(4);
Response.Cookies.Add(c1);
HttpCookie c2 = new HttpCookie("n2", "v2");
c2.Expires = DateTime.Now.AddHours(4);
Response.Cookies.Add(c2);
}
</script>
</body>
</html>
GetHeaders.aspx:
<%@ Page language="c#" %>
<HTML>
<body>
<asp:Label id="Label1" runat="server">Label</asp:Label>
<script language="C#" runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
// make a resquest for the other page (AddHeaders.aspx)
System.Net.HttpWebRequest proxyRequest = (System.Net.HttpWebRequest)
System.Net.WebRequest.Create("http://localhost/WebRequestTest/AddHeaders.asp
x");
System.Net.HttpWebResponse proxyResponse = (System.Net.HttpWebResponse)
proxyRequest.GetResponse();
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (string key in proxyResponse.Headers.Keys)
{
string[] values = proxyResponse.Headers.GetValues(key);
for (int i=0; i<values.Length; i++)
sb.AppendFormat("header {0}={1}<br>", key, values);
}
Label1.Text = sb.ToString();
}
</script>
</body>
</HTML>
This yields the output:
header Server=Microsoft-IIS/5.1
header Date=Mon, 10 May 2004 16:29:06 GMT
header X-AspNet-Version=1.1.4322
header No-comma=value1
header No-comma=value2
header Comma=a,b
header Comma=c,d
header Set-Cookie=ASP.NET_SessionId=pyum1s45wwc5wdzhndrzyeqh; path=/
header Set-Cookie=n1=v1; expires=Mon
header Set-Cookie=10-May-2004 20:29:06 GMT; path=/
header Set-Cookie=n2=v2; expires=Mon
header Set-Cookie=10-May-2004 20:29:06 GMT; path=/
header Cache-Control=private
header Content-Type=text/html; charset=utf-8
header Content-Length=42
Note how the Set-Cookie multi-value headers have been incorrectly broken up.
They should look like this:
header Set-Cookie=n1=v1; expires=Mon, 10-May-2004 20:29:06 GMT; path=/
header Set-Cookie=n2=v2; expires=Mon, 10-May-2004 20:29:06 GMT; path=/
I know that I can use the CookieContainer to correctly parse out these
values, but I'd rather not (for efficiency); I just want to deal with raw
headers.
Is this a bug, or am I using the framework (1.1) incorrectly?
j
is handled by the WebHeaderCollection. That is, the values of Set-Cookie,
when an Expires is specified, contain the "," character. This seems to be
incorrectly parsed during GetValues().
A simple example shows it best (there are 2 .aspx pages and an output):
AddHeaders.aspx:
<%@ Page language="c#" %>
<html>
<body>
<script language=C# runat=server>
private void Page_Load(object sender, System.EventArgs e)
{
Response.AddHeader("No-comma", "value1");
Response.AddHeader("No-comma", "value2");
Response.AddHeader("Comma", "a,b");
Response.AddHeader("Comma", "c,d");
HttpCookie c1 = new HttpCookie("n1", "v1");
c1.Expires = DateTime.Now.AddHours(4);
Response.Cookies.Add(c1);
HttpCookie c2 = new HttpCookie("n2", "v2");
c2.Expires = DateTime.Now.AddHours(4);
Response.Cookies.Add(c2);
}
</script>
</body>
</html>
GetHeaders.aspx:
<%@ Page language="c#" %>
<HTML>
<body>
<asp:Label id="Label1" runat="server">Label</asp:Label>
<script language="C#" runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
// make a resquest for the other page (AddHeaders.aspx)
System.Net.HttpWebRequest proxyRequest = (System.Net.HttpWebRequest)
System.Net.WebRequest.Create("http://localhost/WebRequestTest/AddHeaders.asp
x");
System.Net.HttpWebResponse proxyResponse = (System.Net.HttpWebResponse)
proxyRequest.GetResponse();
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (string key in proxyResponse.Headers.Keys)
{
string[] values = proxyResponse.Headers.GetValues(key);
for (int i=0; i<values.Length; i++)
sb.AppendFormat("header {0}={1}<br>", key, values);
}
Label1.Text = sb.ToString();
}
</script>
</body>
</HTML>
This yields the output:
header Server=Microsoft-IIS/5.1
header Date=Mon, 10 May 2004 16:29:06 GMT
header X-AspNet-Version=1.1.4322
header No-comma=value1
header No-comma=value2
header Comma=a,b
header Comma=c,d
header Set-Cookie=ASP.NET_SessionId=pyum1s45wwc5wdzhndrzyeqh; path=/
header Set-Cookie=n1=v1; expires=Mon
header Set-Cookie=10-May-2004 20:29:06 GMT; path=/
header Set-Cookie=n2=v2; expires=Mon
header Set-Cookie=10-May-2004 20:29:06 GMT; path=/
header Cache-Control=private
header Content-Type=text/html; charset=utf-8
header Content-Length=42
Note how the Set-Cookie multi-value headers have been incorrectly broken up.
They should look like this:
header Set-Cookie=n1=v1; expires=Mon, 10-May-2004 20:29:06 GMT; path=/
header Set-Cookie=n2=v2; expires=Mon, 10-May-2004 20:29:06 GMT; path=/
I know that I can use the CookieContainer to correctly parse out these
values, but I'd rather not (for efficiency); I just want to deal with raw
headers.
Is this a bug, or am I using the framework (1.1) incorrectly?
j