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

The server committed a protocol violation

347 views
Skip to first unread message

Kris Mattheus

unread,
Jul 12, 2006, 8:24:51 AM7/12/06
to
A little background:

I've been using web services successfully for a while now. My web server is a Windows CE 4.2 device
and my client is a windows C# application created with Visual Studio 2003. My web server has both
NTLM and Basic authentication. By providing the Credentials for my web service call, my
application can access the web service without any problems.

The problem:

I recently created a new application with Visual Studio 2005 using the same logic. However, when I
try to call the web service, I get a WebException with following message:

"The server committed a protocol violation. Section=ResponseStatusLine"

As soon as I disable the authentication on the web server, the web service call executes without
problems.

To pin-point my problem, I've created a simple test application which merely requests a web page
from the CE device. This test application gives the same error. Here's the code:

HttpWebRequest myWebRequest = WebRequest.Create("http://150.158.204.40/DMS/Installation Manual.htm")
as HttpWebRequest;
NetworkCredential networkCredential = new NetworkCredential("Test", "service");
myWebRequest.Credentials = networkCredential;
try
{
WebResponse myWebResponse = myWebRequest.GetResponse();
MessageBox.Show(myWebResponse.ContentLength.ToString());
}
catch (WebException wex)
{
Trace.WriteLine(string.Format("Caught Exception: {0}", wex.Message));
Trace.WriteLine(string.Format("Stack: {0}", wex.StackTrace));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

I've enabled Network Tracing for this test application and I got following output (using Basic
authentication):

System.Net Verbose: 0 : [4952] WebRequest::Create(http://150.158.204.40/DMS/Installation Manual.htm)
System.Net Verbose: 0 : [4952]
HttpWebRequest#63840421::HttpWebRequest(http://150.158.204.40/DMS/Installation Manual.htm#1606441202)
System.Net Verbose: 0 : [4952] Exiting HttpWebRequest#63840421::HttpWebRequest()
System.Net Verbose: 0 : [4952] Exiting WebRequest::Create() -> HttpWebRequest#63840421
System.Net Verbose: 0 : [4952] HttpWebRequest#63840421::GetResponse()
System.Net Information: 0 : [4952] Associating HttpWebRequest#63840421 with ServicePoint#54246671
System.Net Information: 0 : [4952] Associating Connection#25181126 with HttpWebRequest#63840421
System.Net Information: 0 : [4952] Associating HttpWebRequest#63840421 with ConnectStream#59408853
System.Net Information: 0 : [4952] HttpWebRequest#63840421 - Request: GET
/DMS/Installation%20Manual.htm HTTP/1.1

System.Net Information: 0 : [4952] ConnectStream#59408853 - Sending headers
{
Host: 150.158.204.40
Connection: Keep-Alive
}.
System.Net Information: 0 : [4952] Connection#25181126 - Received status line: Version=1.0,
StatusCode=401, StatusDescription=Unauthorized.
System.Net Information: 0 : [4952] Connection#25181126 - Received headers
{
Date: Tue, 11 Jul 2006 20:55:59 GMT
Connection: keep-alive
Server: Microsoft-WinCE/4.20
WWW-Authenticate: NTLM,Basic realm="Microsoft-WinCE"
Content-Type: text/html
Content-Length: 81
}.
System.Net Information: 0 : [4952] ConnectStream#56152722::ConnectStream(Buffered 81 bytes.)
System.Net Information: 0 : [4952] Associating HttpWebRequest#63840421 with ConnectStream#56152722
System.Net Information: 0 : [4952] Associating HttpWebRequest#63840421 with HttpWebResponse#43844556
System.Net Warning: 0 : [4952] HttpWebRequest#63840421::() - Resubmitting request.
System.Net Information: 0 : [4952] Associating HttpWebRequest#63840421 with ServicePoint#54246671
System.Net Information: 0 : [4952] Associating Connection#25181126 with HttpWebRequest#63840421
System.Net Information: 0 : [4952] Associating HttpWebRequest#63840421 with ConnectStream#26847985
System.Net Information: 0 : [4952] HttpWebRequest#63840421 - Request: GET
/DMS/Installation%20Manual.htm HTTP/1.1

System.Net Information: 0 : [4952] ConnectStream#26847985 - Sending headers
{
Authorization: Basic UEZFOnZpc2lvbg==
Host: 150.158.204.40
Connection: Keep-Alive
}.
System.Net Error: 0 : [4952] Exception in the HttpWebRequest#63840421:: - The server committed a
protocol violation. Section=ResponseStatusLine
System.Net Error: 0 : [4952] Exception in the HttpWebRequest#63840421::EndGetResponse - The server
committed a protocol violation. Section=ResponseStatusLine
A first chance exception of type 'System.Net.WebException' occurred in System.dll

When I look with Ethereal, I get following stream:

Request ->
GET /DMS/Installation%20Manual.htm HTTP/1.1
Host: 150.158.204.40
Connection: Keep-Alive

Response ->
HTTP/1.0 401 Unauthorized
Date: Tue, 11 Jul 2006 20:55:59 GMT
Connection: keep-alive
Server: Microsoft-WinCE/4.20
WWW-Authenticate: NTLM
WWW-Authenticate: Basic realm="Microsoft-WinCE"
Content-Type: text/html
Content-Length: 81

Request ->
GET /DMS/Installation%20Manual.htm HTTP/1.1
Authorization: Basic UEZFOnZpc2lvbg==
Host: 150.158.204.40
Connection: Keep-Alive

Response ->
<B>Access denied.</B><P>Client does not have access to the resource on the serverHTTP/1.0 200 OK
Date: Tue, 11 Jul 2006 20:55:59 GMT
Connection: keep-alive
Server: Microsoft-WinCE/4.20
Last-Modified: Mon, 10 Jul 2006 12:23:36 GMT
ETag: "0149baa1ba4c61:820:7"
Content-Type: text/html
Content-Length: 37462

<html>
<head>
<meta http-equiv="Content-Language" content="nl-be">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Installation Manual</title>
</head>
<body>
...

As you can see in the HTTP stream captured with Ethereal, the first request fails with an error,
because no Authentication is used. The application then tries again with an Authorization string in
the header. This request succeeds and the CE device start sending the HTML content. However, the
.NET framework seems to ignore this content and throws the WebException instead.

Note that I've already tried to add the "useUnsafeHeaderParsing" in the config file, but without
success.

Does anyone have an idea what could be causing this problem?
Or how I can further debug this problem?

I've you need more tracing, please let me now.

Regards
Kris

John Spaith [MS]

unread,
Jul 13, 2006, 4:05:56 PM7/13/06
to
Hmm - this is very odd and is the first I've ever heard of this problem.
Your capture is quite helpful though

> Request ->
> GET /DMS/Installation%20Manual.htm HTTP/1.1

> [snip...]


>
> Response ->
> HTTP/1.0 401 Unauthorized

> [snip...]


> Content-Type: text/html
> Content-Length: 81
>
> Request ->
> GET /DMS/Installation%20Manual.htm HTTP/1.1
> Authorization: Basic UEZFOnZpc2lvbg==

> [snip...]
>
> Response ->
> [here's problem!]<B>Access denied.</B><P>Client does not have access to

> the resource on the serverHTTP/1.0 200 OK
> Date: Tue, 11 Jul 2006 20:55:59 GMT
> Connection: keep-alive

It looks like what's happening is that the client is not reading the
content-length: 81 <B> Access denied</B> from the first request, but is
instead sending a new request right away. When it calls recv() again the
first bytes it gets back are not the "200 OK" I get because I like your
password but instead the old crusty data.

I'm not at all familiar with the .Net stuff so I don't know what they're
doing or if you could do something differently, like req.RecvBody()? You
may have to try one of their newsgroups (feel free to cross-post your new
thrd to this one though because I'm extremely curious as to what's happening
here). One potential gotcha here is that the web server does one send() for
HTTP headers and then another send() for the body, whereas IIS may optimize
this into one send() for both headers+body for a small body request like
this.

--
John Spaith
Development Lead, Windows CE
Microsoft Corporation

Check out the CE Networking Team Blog at http://blogs.msdn.com/cenet/.

This posting is provided "AS IS" with no warranties, and confers no rights.
You assume all risk for your use. © 2006 Microsoft Corporation. All rights
reserved.

"Kris Mattheus" <KM...@baarco.com> wrote in message
news:%23ECnt4a...@TK2MSFTNGP04.phx.gbl...

Kris Mattheus

unread,
Jul 14, 2006, 8:00:31 AM7/14/06
to
Thanks for your reply, John

I also think it has to do with the body of the previous request that comes in after the new request.
When I compile this code with Visual Studio 2003, I get following sequence in Ethereal:

-> Request
GET /DMS/Installation%20Manual.htm HTTP/1.1

Connection: Keep-Alive
Host: 150.158.204.40

-> Response
HTTP/1.0 401 Unauthorized
Date: Fri, 14 Jul 2006 15:54:41 GMT
Connection: keep-alive
Server: Microsoft-WinCE/4.20


WWW-Authenticate: Basic realm="Microsoft-WinCE"
Content-Type: text/html
Content-Length: 81

<B>Access denied.</B><P>Client does not have access to the resource on the server

[! the next request is done after the body has come in]


-> Request
GET /DMS/Installation%20Manual.htm HTTP/1.1

Authorization: Basic UEZFOnZpc2lvbg==
Connection: Keep-Alive
Host: 150.158.204.40

-> Response
HTTP/1.0 200 OK
Date: Fri, 14 Jul 2006 15:54:41 GMT


Connection: keep-alive
Server: Microsoft-WinCE/4.20
Last-Modified: Mon, 10 Jul 2006 12:23:36 GMT

ETag: "0149baa1ba4c61:820:b"
Content-Type: text/html
Content-Length: 37462

<html>
<head>
...

As you can see, the next request is done after the body of the failing response has come in. So, the
second response only contains the "200 OK" message. It's like the 2.0 .NET framework not longer
waits for the body to come in and immediately sends the next request as soon as the header arrived.

I've also tested with IIS 5.0 as web server. In this case the header and body are indeed contained
in one send(), as you mentioned. However, there another difference as well: After the response has
come in from the web server, the session is closed by the web server. So, for the next request the
client creates a new session. In the CE web server all traffic is done over the same session.

Thanks
Kris

PS: I've already posted my original message to two .NET framework threads, but until now without
results.

John Spaith [MS]

unread,
Jul 14, 2006, 12:06:12 PM7/14/06
to
Hey Kris - sorry you're seeing this and I wish there was more I could to
help here. But from the web server's perspective, it looks like we're doing
everything right -- when I send a content-length the client needs to suck in
that much data before it can keep reading. As far as CE HTTPD doing a
keep-alive, I'm not aware of anything in the spec that would need us to
close the connection on a Basic request. It may be that we're an HTTP 1.0
server doing a keep-alive (technically that's a 1.1 feauter), but almost
every 1.0 server in the world supports keep-alives also.

You may try re-posting to the .Net groups with this additional information
(you can throw my name around if you want, but as a small fry I don't think
it'll impress any .Net people :() or going through support -
http://support.microsoft.com/.

--
John Spaith
Development Lead, Windows CE
Microsoft Corporation

Check out the CE Networking Team Blog at http://blogs.msdn.com/cenet/.

This posting is provided "AS IS" with no warranties, and confers no rights.
You assume all risk for your use. © 2006 Microsoft Corporation. All rights
reserved.

"Kris Mattheus" <KM...@baarco.com> wrote in message

news:ebjEc0zp...@TK2MSFTNGP03.phx.gbl...

0 new messages