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

wininet and http versions

144 views
Skip to first unread message

Luke Amery

unread,
Jun 28, 2004, 12:32:11 AM6/28/04
to
Hi all,

I have an application that I have developed.

It uses wininet.

I have been testing it in various scenarios.

I have just hit a serious issue with the design - well at least with respect
to the interfacing with wininet.

The application synchronises a database over the internet.

I have carefully constructed the message processing code on either side to
never use much RAM but to send the entire message in one http transaction
(the process feeds data into temp tables on each side of the connection so
RAM and disk usage is balanced by the database).

I do this by making a query into the database, and taking the results of
this query (the data that needs to be synchronised) and compressing it and
sending to the server using http1.1 transfer chunked encoding over an ssl
connection.

That works perfectly.

Until I found that wininet does not infact obey the http version argument it
takes, but rather uses the settings EnableHttp1_1 and ProxyHttp1.1 in the
registry under the Software\Microsoft\Windows\CurrentVersion\Internet
Settings key

this is absolutely terrible because if these settings in fact result in the
http version being 1.0 for the http transaction the server will see no
content length in the post header and will then not read any posted data at
all (more specifically Request.BinaryRead will not read a single byte in ASP
or ReadClient in ISAPI will also read no content).

To be even more specific all the server APIs of IIS don't support reading
post content that has been chunked encoded if the http version of the
request is not HTTP/1.1.

I can't see why the http version should be ignored especially when the
request is over ssl to a server I control - http 1.0 should never enter the
equation, and I have no way to control this behavior.

flicking the registry seems like a horrible error prone (current version
specific) idea that could be disasterous and perhaps not even possibly in
some more tightly controlled environments where users don't have permission
over such things.

I looked into WinHttp - it rules out many of the platforms we are supporting
and has some rather extreme difficult requirements in detecting the user's
proxy server.

can somebody please help me? what do I do?


Stephen Sulzer

unread,
Jun 28, 2004, 1:49:31 AM6/28/04
to
(The EnableHttp1_1 and ProxyHttp1.1 registry settings correspond to the "Use
HTTP 1.1" and "Use HTTP 1.1 through proxy connections", respectively, in
Internet Explorer's "Advanced" configuration settings.)

Are you sure that if EnableHttp1_1 is zero, WinInet will ignore/override the
lpszVersion parameter of the HttpOpenRequest API, and send the request with
an "HTTP/1.0" version header? Did you confirm that this is happening?

My understanding is that if EnableHttp1_1 is true, then WinInet will send
the request as "HTTP/1.1" even if the application specifies "HTTP/1.0" for
the lpszVersion parameter. But if EnableHttp1_1 is zero, then WinInet will
use the lpszVersion given by the application (so that the application can
send the request as HTTP/1.1 even if EnableHttp1_1 is zero).

Also, how are you sending the request data in the HTTP/1.1 chunked format
using WinInet? WinInet will not chunk the request; it only supports
receiving chunked responses. Is your application formatting the request data
into chunks itself?


Stephen


Luke Amery

unread,
Jun 28, 2004, 2:35:03 AM6/28/04
to
Hi Stephen,

I didn't test the case of EnableHttp1_1 being 0. I have done all my testing
around ProxyHttp1.1 as that is where I noticed the problem first.

If ProxyHttp1.1 is 0 you have no control of http version when passing
through a proxy. If you do, please correct me and all my problems are
solved.

So you may be right, the EnableHttp1_1 thing may not be an issue for me at
all.

However, the ProxyHttp1.1 sure is at the moment.

The point is that I am using ssl in the request - so the proxy can do
nothing but make a http tunnel, so http versioning should be right out the
window at that point. The programmer should be in control. And I am not.

Yes, I am doing the compression and chunking of the upload myself and
writing it directly through InternetWriteFile.

This is all within HTTP spec, the only reason it is not in common use is
because there is no easy way for a http client to determine if the server
supports the full 1.1 functionality, however, in my case I know.

And I have to use that functionality, because calculating the size of the
post before sending it would be a very bad way to go.

"Stephen Sulzer" <sasulzer_at_seanet.com> wrote in message
news:10dvcck...@corp.supernews.com...

Luke Amery

unread,
Jun 28, 2004, 3:54:02 AM6/28/04
to
I have concluded that you do have control in the case where EnableHttp1_1 is
turned on. Thanks for pointing that out Stephen.

Which means it works perfectly in this case when not going through a proxy
server.

However, having ProxyEnable1.1 off and going through a proxy server is bad
news. You lose control of the request and in my case WinInet makes the wrong
decision.

I did all my testing through a proxy playing with ProxyEnable1.1 initially
which lead me to the flawed conclusion that EnableHttp1_1 was also faulty.

But it is not, only ProxyEnable1.1 is broken.

"Stephen Sulzer" <sasulzer_at_seanet.com> wrote in message
news:10dvcck...@corp.supernews.com...

Stephen Sulzer

unread,
Jun 28, 2004, 6:09:33 AM6/28/04
to
You are correct: if ProxyHttp1.1 is zero in the registry, and the request is
going via a proxy server, then WinInet will force the HTTP version in the
request to be "HTTP/1.0". That is unfortunate--although I don't know if this
is by-design or a bug.

I tried to find a relatively straightforward way to override this behavior
in WinInet, but was unsuccessful. I thought that there might be a way to
"fix" the request after WinInet overrides the version to "HTTP/1.0" but
before it transmits the request over the network. There are a couple
callbacks that are sent to the application (if it has registered a status
callback function) during this timeframe, so I know when it could be done.
However, I don't know how to modify the Request-Line. You cannot use
HttpAddRequestHeaders to modify the components of the Request-Line.

Perhaps the simplest and safest thing to do is not bother chunking the
request in the case where the ProxyHttp1.1 key is zero and the request is
going via a proxy server. This of course requires that you know in advance
the size of the request message.

The registry "flicker" hack that you mentioned is probably workable. If the
ProxyHttp1.1 registry value is zero, then change it to 1, call
InternetSetOption(NULL, INTERNET_OPTION_PROXY_SETTINGS_CHANGED, NULL, 0) to
force WinInet to load the new registry setting, send the request, and then
undo the registry change. This workaround hack is the simplest to implement,
although it would not work if the user does not have write access to the
HKEY_CURRENT_USER registry hive.

A more extreme workaround (still using WinInet; although I think it would be
quite tricky to implement) would be to talk to the proxy server directly.
That is, instead of telling WinInet that you want to send a request to your
target server (with WinInet routing the request via the proxy), send the
request to the proxy as though it were the target server. This would avoid
the logic in WinInet that overrides the HTTP version string. This workaround
would require that the application first send a CONNECT request to the proxy
to establish the SSL tunnel, then send the real request. I can discuss this
workaround a bit more if you are interested; however, I have never tried
this myself, so it could end up being a waste of time.

Another radical workaround to consider is to ditch WinInet for something
else. You said WinHTTP is not feasible primarily due to limited platform
support (presumably you need to support Windows 98/ME and/or NT4?). What
about using C# and the .NET Framework? The .NET framework supports Windows
98 and NT4. Of course this workaround might not be feasible for a number of
reasons.

Stephen


"Luke Amery" <luke...@hotmail.com> wrote in message
news:#xoJwVOX...@tk2msftngp13.phx.gbl...

Luke Amery

unread,
Jun 28, 2004, 7:30:06 PM6/28/04
to
thanks for your help Stephen,

I decided on an even simpler alternative:

1. I detect if the request is going to be mucked up by WinInet by reading
the registry and proxy settings.

2. I detect if the registry setting is changeable by the user

3. if the registry setting is changeable I popup a dialog box explaining the
situation and giving the user a chance to change the setting right there, if
the user does not have permission I popup a dialog box explaining that an
administrator must change your Internet settings.

It is a horrible solution and if enough people complain I will implement the
non chunking solution to avoid the issue in the proxy case, but it is
definitely not ideal.

I am actually now just concerned about the fact that these settings are
actually controllable through Active Directory and that the poor user is
going to be hassled by my warning dialogs every "Active Directory Refresh
Period" as the settings are propagated back to the user's machine.

"Stephen Sulzer" <sasulzer_at_seanet.com> wrote in message

news:10dvrj2...@corp.supernews.com...

0 new messages