HTTP Protocol violation (long)

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hello Folks,

I've been trying to connect to a secure server (basic authentication), and
while getting infamous errors I've decided to watch the messages passed
between them.

Here goes my initial request (i'm trying to use preAuthentication on the
HttpWebRequest but to no avail. My work around was to invoke a simple HTTP
Method to perform the authentication on the server):

HEAD /slide/files/ HTTP/1.1
Connection: Keep-Alive
Host: maisis10

The response:

HTTP/1.1 401 Unauthorized
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 01:00:00 GMT
WWW-Authenticate: Basic realm="Slide DAV Server"
Content-Type: text/html;charset=utf-8
Content-Length: 954
Date: Thu, 03 Feb 2005 11:29:55 GMT
Server: Apache-Coyote/1.1

I'm ok with this answer, the HttpWebRequest instance retries it
automatically with these sucessfull request and response:

HEAD /slide/files/ HTTP/1.1
Authorization: Basic cm9vdDpyb290
Host: localhost:8000

HTTP/1.1 200 OK
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 01:00:00 GMT
Set-Cookie: JSESSIONID=B0DB4BA0E1533B5BCF828DA80817058A; Path=/slide
ETag: ""
Content-Language:
Last-Modified: Thu, 25 Nov 2004 17:35:42 GMT
Content-Type:
Content-Length: 0
Date: Thu, 03 Feb 2005 11:29:55 GMT
Server: Apache-Coyote/1.1


Now, this is the tricky part. I do a PROPFIND command (it's a perfectly good
webdav command):

PROPFIND /slide/files HTTP/1.1
Content-Length: 98
Expect: 100-continue
Host: localhost:8000

<?xml version='1.0' encoding='utf-8' ?>
<D:propfind xmlns:D='DAV:'><D:allprop/></D:propfind>

The following response was, as expected an 401 Unauthorized. I don't know
why it didn't reuse the same credentials, but that's still ok with me. The
client should retry the propfind, now with the correct authentication header.
But, let's take a look at the request again, it has an Expect: 100-continue
header, witch, as the rfc2616 tells us at section 8.2.3, means that the
client is asking the server if he can proceed with the relay of the
content-body of the command. Problem his, the HttpWebRequest instance SENDS
THE BODY ANYWAY before the server response. Section 8.2.3 also says that the
client should not wait indefenitively for a HTTP CONTINUE response, but the
server immediatly respondes with the 401 unauthorized response! Here is the
response from the server:

HTTP/1.1 401 Unauthorized
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 01:00:00 GMT
WWW-Authenticate: Basic realm="Slide DAV Server"
Content-Type: text/html;charset=utf-8
Content-Length: 954
Date: Thu, 03 Feb 2005 11:29:55 GMT
Server: Apache-Coyote/1.1

<html><head><title>Apache Tomcat/5.0.28 - Error report</title><style><!--H1
{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;}
H2
{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;}
H3
{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;}
BODY
{font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B
{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P
{font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A
{color : black;}A.name {color : black;}HR {color : #525D76;}--></style>
</head><body><h1>HTTP Status 401 - </h1><HR size="1"
noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b>
<u></u></p><p><b>description</b> <u>This request requires HTTP authentication
().</u></p><HR size="1" noshade="noshade"><h3>Apache
Tomcat/5.0.28</h3></body></html>


Now, here goes my problem. The client, receiving the 401 error, resends the
propfind, now with the authentication header:

PROPFIND /slide/files HTTP/1.1
Authorization: Basic cm9vdDpyb290
Content-Length: 98
Expect: 100-continue
Host: localhost:8000

<?xml version='1.0' encoding='utf-8' ?>
<D:propfind xmlns:D='DAV:'><D:allprop/></D:propfind>

But the response is:

HTTP/1.1 505 HTTP Version Not Supported
Date: Thu, 03 Feb 2005 11:29:55 GMT
Server: Apache-Coyote/1.1
Connection: close

What's happening is that the body of first propfind try gets in the way of
the second propfind, so the server when reading the next HTTP command, thinks
the body of the first command is the start of the following command, with
obviously is not, responding with the 505 error.

This is documented in the tomcat bugzilla:
http://issues.apache.org/bugzilla/show_bug.cgi?id=31567

HttpWebResponse is not using 'expections' properly. We have tryed the COM+
counterpart for producing the same command and it works properly (he does not
send the EXPECT header).

Could someone at Microsoft exam my claims, and if possible correct it
according to the HTTP 1.1 specification?

By the way, if I set the HttpWebRequest to version 1.0, all goes well but I
want to have tecnological progress not the other way around!

Best regards,
Miguel Figueiredo
 
Miguel said:
Hello Folks,

I've been trying to connect to a secure server (basic
authentication), and while getting infamous errors I've decided to
watch the messages passed between them.

Here goes my initial request (i'm trying to use preAuthentication on
the HttpWebRequest but to no avail. My work around was to invoke a
simple HTTP Method to perform the authentication on the server):

HEAD /slide/files/ HTTP/1.1
Connection: Keep-Alive
Host: maisis10

The response:

HTTP/1.1 401 Unauthorized
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 01:00:00 GMT
WWW-Authenticate: Basic realm="Slide DAV Server"
Content-Type: text/html;charset=utf-8
Content-Length: 954
Date: Thu, 03 Feb 2005 11:29:55 GMT
Server: Apache-Coyote/1.1

I'm ok with this answer, the HttpWebRequest instance retries it
automatically with these sucessfull request and response:

HEAD /slide/files/ HTTP/1.1
Authorization: Basic cm9vdDpyb290
Host: localhost:8000

HTTP/1.1 200 OK
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 01:00:00 GMT
Set-Cookie: JSESSIONID=B0DB4BA0E1533B5BCF828DA80817058A; Path=/slide
ETag: ""
Content-Language:
Last-Modified: Thu, 25 Nov 2004 17:35:42 GMT
Content-Type:
Content-Length: 0
Date: Thu, 03 Feb 2005 11:29:55 GMT
Server: Apache-Coyote/1.1


Now, this is the tricky part. I do a PROPFIND command (it's a
perfectly good webdav command):

PROPFIND /slide/files HTTP/1.1
Content-Length: 98
Expect: 100-continue
Host: localhost:8000

<?xml version='1.0' encoding='utf-8' ?>
<D:propfind xmlns:D='DAV:'><D:allprop/></D:propfind>

The following response was, as expected an 401 Unauthorized. I don't
know why it didn't reuse the same credentials, but that's still ok
with me. The client should retry the propfind, now with the correct
authentication header. But, let's take a look at the request again,
it has an Expect: 100-continue header, witch, as the rfc2616 tells us
at section 8.2.3, means that the client is asking the server if he
can proceed with the relay of the content-body of the command.
Problem his, the HttpWebRequest instance SENDS THE BODY ANYWAY before
the server response. Section 8.2.3 also says that the client should
not wait indefenitively for a HTTP CONTINUE response, but the server
immediatly respondes with the 401 unauthorized response! Here is the
response from the server:

HTTP/1.1 401 Unauthorized
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 01:00:00 GMT
WWW-Authenticate: Basic realm="Slide DAV Server"
Content-Type: text/html;charset=utf-8
Content-Length: 954
Date: Thu, 03 Feb 2005 11:29:55 GMT
Server: Apache-Coyote/1.1

<html><head><title>Apache Tomcat/5.0.28 - Error
report</title><style><!--H1
{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525
D76;font-size:22px;} H2
{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525
D76;font-size:16px;} H3
{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525
D76;font-size:14px;} BODY
{font-family:Tahoma,Arial,sans-serif;color:black;background-color:whit
e;} B
{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525
D76;} P
{font-family:Tahoma,Arial,sans-serif;background:white;color:black;font
-size:12px;}A {color : black;}A.name {color : black;}HR {color :
#525D76;}--></style> </head><body><h1>HTTP Status 401 - </h1><HR
size="1" noshade="noshade"><p><b>type</b> Status
report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>This
request requires HTTP authentication ().</u></p><HR size="1"
noshade="noshade"><h3>Apache Tomcat/5.0.28</h3></body></html>


Now, here goes my problem. The client, receiving the 401 error,
resends the propfind, now with the authentication header:

PROPFIND /slide/files HTTP/1.1
Authorization: Basic cm9vdDpyb290
Content-Length: 98
Expect: 100-continue
Host: localhost:8000

<?xml version='1.0' encoding='utf-8' ?>
<D:propfind xmlns:D='DAV:'><D:allprop/></D:propfind>

But the response is:

HTTP/1.1 505 HTTP Version Not Supported
Date: Thu, 03 Feb 2005 11:29:55 GMT
Server: Apache-Coyote/1.1
Connection: close

What's happening is that the body of first propfind try gets in the
way of the second propfind, so the server when reading the next HTTP
command, thinks the body of the first command is the start of the
following command, with obviously is not, responding with the 505
error.

This is documented in the tomcat bugzilla:
http://issues.apache.org/bugzilla/show_bug.cgi?id=31567

HttpWebResponse is not using 'expections' properly. We have tryed the
COM+ counterpart for producing the same command and it works properly
(he does not send the EXPECT header).

Could someone at Microsoft exam my claims, and if possible correct it
according to the HTTP 1.1 specification?

By the way, if I set the HttpWebRequest to version 1.0, all goes well
but I want to have tecnological progress not the other way around!

Nice technical analysis. But you can suppress Expect headers using
ServicePointManager.Expect100Continue = false;
Now you can have your HTTP 1.1 cake and eat it ;-)

Cheers,
 
Many thanks!!

It is a solution that can be used in my problem. My MSDN isn't updated, so
it didn't find anything about that property in ServicePointManager.

Anyway, someone at Microsoft should solve this spec inconsistance, because
the problem won't go away even if we set Expect100Continue to false.

Best Regards,
Miguel Figueiredo
 
Back
Top