Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

HttpWebRequest in Compact Framework fails on second request

51 views
Skip to first unread message

ajdavis

unread,
Jul 7, 2005, 2:41:03 PM7/7/05
to
Hello, folks. A strange error that I finally tracked down with the
Ethereal packet sniffer:

Using .NET Compact Framework 1.0.3111 and programming C# in Visual
Studio .NET 7.1.3088, I create an HttpWebRequest. The first time, the
ProtocolVersion is 1.1 and the Host is correctly set in the HTTP
header. The second & all subsequent times, the same code produces a
request with ProtocolVersion 1.0, and the Host string is empty. This
sort of HTTP request fails for most hosts.

I'd love it if a few people w/ different versions of Windows CE, Visual
Studio, .NETCF, etc. tried this out. Make a new Smart Device
Application project, in the next dialog select "Pocket PC" or "Windows
CE" and "Windows Application". Then in the autogenerated Form1.cs, add
"using System.Net;" at the top, and insert the following in the Form1
constructor, below InitializeComponent():

TextBox output = new TextBox();
output.Multiline = true; output.ScrollBars = ScrollBars.Both;
output.Size = new Size(180, 220); this.Controls.Add(output);

for (int i = 0; i < 2; i++)
{
HttpWebResponse response = null;
HttpWebRequest request = null;
try
{
Uri url = new Uri("http://foobar.com/");
request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Timeout = 10 * 1000; // milliseconds
request.Method = "GET";
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version11;

response = (HttpWebResponse)request.GetResponse();

output.Text += string.Format("Received response of {0} bytes\r\n",
response.ContentLength);
}
catch (Exception e)
{
output.Text += "Exception: " + e.ToString() + "\r\n";
}
finally
{
if (response != null) response.Close();
}

output.Text += "Version: " + request.ProtocolVersion.ToString() +
"\r\n";
output.Text += "Host: " + request.Headers.Get("Host") + "\r\n";
output.Text += "======\r\n";
}

On my setup, I get the following output:

Received response of 2146 bytes
Version: 1.1
Host: foobar.com
======
Exception: System.Net.WebException:The remote server returned an
error: (503) Server Unavailable.
Version: 1.0
Host:
======

Notice how the Version is 1.0 and Host is empty in the second, failed,
request. Weird, huh? I filed a bug with MS, ID FDBK31733.

Jesse.

ajdavis

unread,
Jul 27, 2005, 11:09:02 AM7/27/05
to
A friend helped me w/ the Ethereal packet-sniffer, & we've nailed down
the problem. My company uses the Squid transparent proxy, which
requires HTTP 1.1 requests but sends HTTP 1.0 responses. The .NETCF
pedantically refuses to send 1.1 requests to a host after it first gets
a 1.0 response from it. Here's what happens:

1) The .NET Compact Framework sends HTTP/1.0 requests, after the first
request, because Squid's response is HTTP/1.0, & the Framework decides
this server can only deal with HTTP/1.0. It correctly omits "Host"
from its 1.0 header. There's no way to force the Framework to include
the "Host" field, or to use an absolute Request-URI. There's also no
way to make Squid send HTTP/1.1 responses.

2) The most common way to use Squid is with DNAT (Destination Network
Address Translation), where the firewall rewrites the destination IP of
outgoing packets with the IP of the Squid proxy. (At my company, we do
this with an iptables command on the firewall.) So the destination IP
is lost, and Squid must have a Host entry, or an absolute Request-URI,
to determine the real destination.

3) The combination of these two properties means only the first
request to a given host can succeed. (I tested this, BTW: I can make
1 request to apple.com, 1 request to google.com, etc., in the lifetime
of 1 process.) Many HTTP implementations, like wget, include a Host
entry even in HTTP/1.0 requests, perhaps for this very situation. But
the Compact Framework doesn't.

The regular Framework succeeds these tests that the CF fails; I haven't
sniffed out the reason. I wish the CF allowed me to set the Host
field, or to force HTTP 1.1, or something more flexible than its
current implementation.

The workaround is to reimplement the required subset of HTTP 1.1 over
the provided Socket class, or to use SSL.

Alex Yakhnin

unread,
Jul 27, 2005, 12:33:25 PM7/27/05
to
Could you re-test it with CF v2 beta 2 and see if it works.
If it doesn's you should submit it into the lady bug.
http://lab.msdn.microsoft.com/productfeedback/
--
Alex Yakhnin, .NET CF MVP

"ajdavis" <jda...@wgen.net> wrote in message
news:1122476942.3...@g43g2000cwa.googlegroups.com...

0 new messages