Discussion:
WinInet SendRequest Problem
(too old to reply)
Bryan Wilcox
2004-09-01 16:13:14 UTC
Permalink
Hello,
We are using MFC wrapped WinInet functions on CInternetSession,
CHttpConnection, and CHttpFile to add the ability to communicate to a
server on the Internet from within our C++ PC applications. We have
run into the problem that I have seen described where CHttpFile's
SendRequest will block for a very long time if the server is
non-responsive. I found this article in MSDN:

http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q224/3/18.ASP&NoWebContent=1

describing how to get around this problem by putting the blocking
calls into a thread and add a "time-out" there. The issue that I have
run into is that the article says you must "call InternetCloseHandle
to release the blocking WinInet function" which in MFC terms means
that you must call close on the CInternetSession object (at least to
my limited understanding of all this). This will allow the
SendRequest to return and allow the worker thread to be able to
terminate. However, the creates another issue. Our application has
the capability to connect through a proxy server. We share the same
CInternetSession object && CHttpConnection object across multiple
calls from within the same application. We get the user's Proxy
username / password once using the ErrorDlg on CHttpFile. This seems
to somehow get automagically cached in WinInet (I am assuming in the
CInternetSession object) so that future SendRequests don't require a
UI to get the user's password. Hence the problem. If I have to
"Close" the Session to allow my worker thread to be able to timed out
or be aborted, that means if we do a subsequent call, we would have to
open a new CInternetSession. This seems like it would require a user
to reauthenticate themselves to the proxy server, which to me seems
annoying.

The high level goals of what I am trying to accomplish are to allow
the user to be able to cancel a communication to the Internet if the
server is non-responsive, but be able to make additional
communications with the Internet from within the same application
while only having to authenticate with the proxy server once. I have
similar concerns about people who use dial-up, does closing this
CInternetSession object kill the dial-up connection. We,
unfortunately, don't have a simple way to test dial-up connections in
our office.

Am I missing something here? Any help would be appreciated.

Thanks,
Bryan
Paul Baker [MVP, Windows - SDK]
2004-09-01 23:24:44 UTC
Permalink
If you wish to cancel a non-responsive HTTP request, you should just be able
to close the HINTERNET to the response you created using HttpOpenRequest to
force HttpSendRequest. The error code is usually
ERROR_INTERNET_OPERATION_CANCELLED, but I don't think this can be relied
upon in older versions of WinInet.

Then the HINTERNET to the HTTP connection would still be open and, if I
understand your description of the problem correctly, it would still cache
the proxy authorization.

Also, once you get the proxy authentication using ErrorDlg, you should be
able to cache it yourself if you need to. You can get/set the proxy user
name/password using InternetQueryOption and InternetSetOption.

Paul
Post by Bryan Wilcox
Hello,
We are using MFC wrapped WinInet functions on CInternetSession,
CHttpConnection, and CHttpFile to add the ability to communicate to a
server on the Internet from within our C++ PC applications. We have
run into the problem that I have seen described where CHttpFile's
SendRequest will block for a very long time if the server is
http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q224/3/18.ASP&NoWebContent=1
Post by Bryan Wilcox
describing how to get around this problem by putting the blocking
calls into a thread and add a "time-out" there. The issue that I have
run into is that the article says you must "call InternetCloseHandle
to release the blocking WinInet function" which in MFC terms means
that you must call close on the CInternetSession object (at least to
my limited understanding of all this). This will allow the
SendRequest to return and allow the worker thread to be able to
terminate. However, the creates another issue. Our application has
the capability to connect through a proxy server. We share the same
CInternetSession object && CHttpConnection object across multiple
calls from within the same application. We get the user's Proxy
username / password once using the ErrorDlg on CHttpFile. This seems
to somehow get automagically cached in WinInet (I am assuming in the
CInternetSession object) so that future SendRequests don't require a
UI to get the user's password. Hence the problem. If I have to
"Close" the Session to allow my worker thread to be able to timed out
or be aborted, that means if we do a subsequent call, we would have to
open a new CInternetSession. This seems like it would require a user
to reauthenticate themselves to the proxy server, which to me seems
annoying.
The high level goals of what I am trying to accomplish are to allow
the user to be able to cancel a communication to the Internet if the
server is non-responsive, but be able to make additional
communications with the Internet from within the same application
while only having to authenticate with the proxy server once. I have
similar concerns about people who use dial-up, does closing this
CInternetSession object kill the dial-up connection. We,
unfortunately, don't have a simple way to test dial-up connections in
our office.
Am I missing something here? Any help would be appreciated.
Thanks,
Bryan
Bryan Wilcox
2004-09-02 14:08:38 UTC
Permalink
Paul,
Thanks for the response. So, by calling InternetCloseHandle on
the CHttpFile object returned from CHttpConnection's OpenRequest using
the CInternetFile (base class of CHttpFile's) Close function, I should
be able to unblock the SendRequest call while still leaving open my
CHttpConnection?
I am also confused as to where the Proxy authentication is stored.
Is it on a per CInternetSession or a per process basis. Some testing
I did seemed to indicate the latter, but I never found any sort of
documentation that directly stated one way or the other.
Also, I tried using the InternetQueryOption to get the
INTERNET_OPTION_PROXY_PASSWORD && INTERNET_OPTION_PROXY_USERNAME and
it kept returning 0 for me. And I know that I was doing the call
correctly because I could retrieve other values like,
INTERNET_OPTION_USER_AGENT. I read somewhere on MSDN that there was a
bug in InternetQueryOption for the Proxy username and password (KB
article 324898). If there is a work-around for this problem that I am
not aware of, please let me know. I am using IE 6.0 with the latest
service pack on a Windows 2000 PC. I am not aware of what sort of
Proxy authentication our work server uses, but I know I have to enter
my username/password when I acess any website outside our firewall.

I appreciate your feedback.

Thanks,
Bryan
Post by Paul Baker [MVP, Windows - SDK]
If you wish to cancel a non-responsive HTTP request, you should just be able
to close the HINTERNET to the response you created using HttpOpenRequest to
force HttpSendRequest. The error code is usually
ERROR_INTERNET_OPERATION_CANCELLED, but I don't think this can be relied
upon in older versions of WinInet.
Then the HINTERNET to the HTTP connection would still be open and, if I
understand your description of the problem correctly, it would still cache
the proxy authorization.
Also, once you get the proxy authentication using ErrorDlg, you should be
able to cache it yourself if you need to. You can get/set the proxy user
name/password using InternetQueryOption and InternetSetOption.
Paul
Post by Bryan Wilcox
Hello,
We are using MFC wrapped WinInet functions on CInternetSession,
CHttpConnection, and CHttpFile to add the ability to communicate to a
server on the Internet from within our C++ PC applications. We have
run into the problem that I have seen described where CHttpFile's
SendRequest will block for a very long time if the server is
http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q224/3/18.ASP&NoWebContent=1
Post by Bryan Wilcox
describing how to get around this problem by putting the blocking
calls into a thread and add a "time-out" there. The issue that I have
run into is that the article says you must "call InternetCloseHandle
to release the blocking WinInet function" which in MFC terms means
that you must call close on the CInternetSession object (at least to
my limited understanding of all this). This will allow the
SendRequest to return and allow the worker thread to be able to
terminate. However, the creates another issue. Our application has
the capability to connect through a proxy server. We share the same
CInternetSession object && CHttpConnection object across multiple
calls from within the same application. We get the user's Proxy
username / password once using the ErrorDlg on CHttpFile. This seems
to somehow get automagically cached in WinInet (I am assuming in the
CInternetSession object) so that future SendRequests don't require a
UI to get the user's password. Hence the problem. If I have to
"Close" the Session to allow my worker thread to be able to timed out
or be aborted, that means if we do a subsequent call, we would have to
open a new CInternetSession. This seems like it would require a user
to reauthenticate themselves to the proxy server, which to me seems
annoying.
The high level goals of what I am trying to accomplish are to allow
the user to be able to cancel a communication to the Internet if the
server is non-responsive, but be able to make additional
communications with the Internet from within the same application
while only having to authenticate with the proxy server once. I have
similar concerns about people who use dial-up, does closing this
CInternetSession object kill the dial-up connection. We,
unfortunately, don't have a simple way to test dial-up connections in
our office.
Am I missing something here? Any help would be appreciated.
Thanks,
Bryan
Paul Baker [MVP, Windows - SDK]
2004-09-02 14:28:49 UTC
Permalink
Bryan,

I know something about WinInet and almost nothing about MFC. You *did* post
to a WinInet group! So I may not be able to help you much further, but I
will try. I'd rather tell you I don't know than make up something.

What you suggest doing with MFC does sound like the equivalent of what I
suggested with WinInet.

I do not know where the proxy authentication is cached. Did you check MSDN
documentation?

I have used InternetQueryOption and InternetSetOption myself with success,
but never tried those values. All I can suggest is to keep trying what you
are already doing, researching the KB and asking others their experience. I
would also, though, check the error code using GetLastError. This might give
you a big clue.

Paul
Post by Bryan Wilcox
Paul,
Thanks for the response. So, by calling InternetCloseHandle on
the CHttpFile object returned from CHttpConnection's OpenRequest using
the CInternetFile (base class of CHttpFile's) Close function, I should
be able to unblock the SendRequest call while still leaving open my
CHttpConnection?
I am also confused as to where the Proxy authentication is stored.
Is it on a per CInternetSession or a per process basis. Some testing
I did seemed to indicate the latter, but I never found any sort of
documentation that directly stated one way or the other.
Also, I tried using the InternetQueryOption to get the
INTERNET_OPTION_PROXY_PASSWORD && INTERNET_OPTION_PROXY_USERNAME and
it kept returning 0 for me. And I know that I was doing the call
correctly because I could retrieve other values like,
INTERNET_OPTION_USER_AGENT. I read somewhere on MSDN that there was a
bug in InternetQueryOption for the Proxy username and password (KB
article 324898). If there is a work-around for this problem that I am
not aware of, please let me know. I am using IE 6.0 with the latest
service pack on a Windows 2000 PC. I am not aware of what sort of
Proxy authentication our work server uses, but I know I have to enter
my username/password when I acess any website outside our firewall.
I appreciate your feedback.
Thanks,
Bryan
Post by Paul Baker [MVP, Windows - SDK]
If you wish to cancel a non-responsive HTTP request, you should just be able
to close the HINTERNET to the response you created using HttpOpenRequest to
force HttpSendRequest. The error code is usually
ERROR_INTERNET_OPERATION_CANCELLED, but I don't think this can be relied
upon in older versions of WinInet.
Then the HINTERNET to the HTTP connection would still be open and, if I
understand your description of the problem correctly, it would still cache
the proxy authorization.
Also, once you get the proxy authentication using ErrorDlg, you should be
able to cache it yourself if you need to. You can get/set the proxy user
name/password using InternetQueryOption and InternetSetOption.
Paul
Post by Bryan Wilcox
Hello,
We are using MFC wrapped WinInet functions on CInternetSession,
CHttpConnection, and CHttpFile to add the ability to communicate to a
server on the Internet from within our C++ PC applications. We have
run into the problem that I have seen described where CHttpFile's
SendRequest will block for a very long time if the server is
http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q224/3/18.ASP&NoWebContent=1
Post by Bryan Wilcox
Post by Paul Baker [MVP, Windows - SDK]
Post by Bryan Wilcox
describing how to get around this problem by putting the blocking
calls into a thread and add a "time-out" there. The issue that I have
run into is that the article says you must "call InternetCloseHandle
to release the blocking WinInet function" which in MFC terms means
that you must call close on the CInternetSession object (at least to
my limited understanding of all this). This will allow the
SendRequest to return and allow the worker thread to be able to
terminate. However, the creates another issue. Our application has
the capability to connect through a proxy server. We share the same
CInternetSession object && CHttpConnection object across multiple
calls from within the same application. We get the user's Proxy
username / password once using the ErrorDlg on CHttpFile. This seems
to somehow get automagically cached in WinInet (I am assuming in the
CInternetSession object) so that future SendRequests don't require a
UI to get the user's password. Hence the problem. If I have to
"Close" the Session to allow my worker thread to be able to timed out
or be aborted, that means if we do a subsequent call, we would have to
open a new CInternetSession. This seems like it would require a user
to reauthenticate themselves to the proxy server, which to me seems
annoying.
The high level goals of what I am trying to accomplish are to allow
the user to be able to cancel a communication to the Internet if the
server is non-responsive, but be able to make additional
communications with the Internet from within the same application
while only having to authenticate with the proxy server once. I have
similar concerns about people who use dial-up, does closing this
CInternetSession object kill the dial-up connection. We,
unfortunately, don't have a simple way to test dial-up connections in
our office.
Am I missing something here? Any help would be appreciated.
Thanks,
Bryan
Brian Combs
2004-09-03 15:27:46 UTC
Permalink
This post might be inappropriate. Click to display it.
Loading...