A long time ago, I used VC to build an HTTP/https-based project. At that time, I made all kinds of problems in developing HTTP/HTTPS programs with wininet very clear. Since there was no summary at the time, so now there are the same problem, and you have to re-query the information, but fortunately the code is there. Some questions can be found in the Code.
Later, due to work changes, I left the original company. That part of the code is gone now. So we have to start from scratch.
Now we have another HTTP project to summarize some problems and save time for similar problems in the future.
1. Several wininet functions.
Urldownloadtofile: you can download the file from the URL of an object. The difference can be that there are only two URLs and the file storage path. This function encapsulates HTTP, FTP, and gppher functions, which can be downloaded as long as the URL is correct.
Urldownloadtofile is split into three functions: internetopen, internetopenurl, and internetreadfile. internetopenurl is also an encapsulated function, regardless of the specific Protocol content. Internetopenurl returns an hinternet handle, which is used as an input parameter of httpqueryinfo to obtain relevant information, such as the file length and file modification date. This handle serves as an input parameter for internetreadfile. internetreadfile downloads the file to an applied buffer.
For the HTTP protocol, internetopenurl can be divided into internetconnect, httpopenrequest, and httpsendrequest. Internetconnect is responsible for connecting to the server. httpopenrequest creates a request handle and stores parameters in the handle. Httpsendrequest sends the request parameters to the HTTP server.
Several problems that may occur and are depressing.
1. httpopenrequest
In httpopenrequest, if the code is written as follows, there will be no problems.
Hinternet hrequest = httpopenrequest (hconnect,
"Get ",
Pszloctionfilepath,
Http_version,
Null,
(Const char **) P,
0,
1 );
The second-to-last parameter: In DWORD dwflags, which is described on msdn: dwflags Internet flag values. can be any of the following values :......
It seems that if it is 0, there should be no problem. But here is my problem.
If the parameter is 0, httpqueryinfo fails to access the same URL for the second time (different URLs do not have problems), and getlasterror () is 12150: Header not found. In this case, if the IE option is enabled, General-> Delete-> delete files. That's all. I used a program to delete all the files in the buffer zone. It is useless. You have to manually click Delete files. The cause of this problem has not been found. If anyone has encountered the same problem, please let me know.
The last and third parameters are written as follows:
Char szhead [] = "accept: */R/n/R/N ";
Char ** P = new char * [2]; * P = szhead; * (p + 1) = NULL;
The last and third parameters are: (const char **) P, so there is no error in writing.
If it is written as (const char **) & szhead, the program will not report an error, but the debug debugging will produce first-chance exception in httpandftptest.exe (kernel32.dll): 0xc0000005: access violation. the warning is that a one-dimensional array is forced into a two-dimensional array, and its second array does not end with '/0.
2. Error 122
122: The data area passed to a system call is too small. Error reported after httpopenrequest. The cause is not found. However, the program does not have errors or warnings.
3. Time spent in each process
Internetopen, internetconnect, httpopenrequest, and httpqueryinfo basically do not take time. Httpsendrequest and internetreadfile consume most of the download time.
4. Write the program corresponding to the IE request
Http://www.abc.com/123/edf.asp? Key = login & login = 2 & Password = 1
Corresponding ie request
// Connect to the server
Hinternet hconnect = internetconnect (hsession,
Servername,
Internet_default_http_port,
Null,
Null,
Internet_service_http,
0,
1 );
Servername is www.abc.com
// Create a request
Hinternet hrequest = httpopenrequest (hconnect,
Method,
Formaction,
Http_version,
Null,
(Const char **) & accept,
0,
1 );
The method is "get"
Formaction:/123/EDF. asp
Bool bseccuss = httpsendrequest (hrequest, HDRs, strlen (HDRs), frmdata, strlen (frmdata ))
Frmdata is key = login & login = 2 & Password = 1.
5. Delete ie cache Functions
Void clearinternetcache ()
{
DWORD dwneeded = 0;
Findfirsturlcacheentry (null, null, & dwneeded );
If (getlasterror () = error_insufficient_buffer)
{
Unsigned char * buffer = new unsigned char [dwneeded];
Try
{
Lpinternet_cache_entry_info lpicei =
Reinterpret_cast <lpinternet_cache_entry_info> (buffer );
Handle hfind = findfirsturlcacheentry (null, lpicei, & dwneeded );
Deleteurlcacheentry (lpicei-> lpszsourceurlname );
Bool no_more_files = false;
While (! No_more_files)
{
If (findnexturlcacheentry (hfind, lpicei, & dwneeded ))
{
Deleteurlcacheentry (lpicei-> lpszsourceurlname );
}
Else switch (getlasterror ())
{
Case error_insufficient_buffer:
{
Delete [] buffer;
Buffer = new unsigned char [dwneeded];
Lpicei = reinterpret_cast <lpinternet_cache_entry_info> (buffer );
Break;
}
Default:
{
No_more_files = true;
Break;
}
}
}
Findcloseurlcache (hfind );
}
Catch (...)
{
Delete [] buffer;
}
Delete [] buffer;
}
}
6. HTTP and HTTPS requests
In the third parameter of internetconnect, change internet_default_http_port to internet_default_https_port.
The seventh parameter of httpopenrequest has an internet_flag_secure option.
Another code that automatically installs the certificate has been used before and cannot be found yet.
7. Better internetopen Method
DWORD dwflags = 1;
Internetgetconnectedstate (& dwflags, 0 );
If (! (Dwflags & internet_connection_proxy ))
* Hsession = internetopena ("myagent", internet_open_type_preconfig_with_no_autoproxy, null, null, 0 );
Else
* Hsession = internetopena ("myagent", internet_open_type_preconfig, null, null, 0 );
If (* hsession)
Return true;
Else
Return false;
8. Functions for downloading files
Uint internetgetfile (hinternet in hconnect, // handle from internetopen ()
Lpcstr szfilename)
{
File * pfile;
If (! (Pfile = fopen (szfilename, "WB ")))
{
Return internet_error_fileopen;
}
Void * sztemp [2, 16384];
DWORD dwsize;
While (true)
{
// Keep coping in 16 KB chunks, while file has any data left.
// Note: bigger buffer will greatly improve performance.
If (! Internetreadfile (hconnect, sztemp, 16384, & dwsize ))
{
Fclose (pfile );
Return internet_error_readfile;
}
If (! Dwsize)
Break; // condition of dwsize = 0 indicate EOF. Stop.
Else
Fwrite (sztemp, sizeof (char), dwsize, pfile );
} // Do
Fflush (pfile );
Fclose (pfile );
Return 0;
}
9. Set Internet session
To set Internet session and other parameters, you can call internetsetoption.