Using wininet to upload files to the HTTP server over the last two weeks, we have finally achieved a satisfactory conclusion. there are two main formats for uploading over HTTP: put over HTTP and post over HTTP.
Let's talk about the put protocol. The so-called put, as the name suggests, is to put the file "to the server. this process does not involve the HTTP and mime encapsulation of files (post Protocol needs to be done), so it is relatively simple. however, considering security issues, the server generally does not develop the put permission. Therefore, this method is not widely used. Let's look at the code: cinternetsession internetsession ("My session"); // defines the session.
Chttpconnection * httpconnection = internetsession. gethttpconnection (strserverip, intserverport); // get the link
Chttpfile * httpfile = httpconnection-> openrequest (chttpconnection: http_verb_put, strremotefile, null, 0, null, null, internet_flag_dont_cache); // send a request
... Httpfile-> sendrequestex (& Bufferin, null, hsr_initiate, 0); pay attention to the chttpconnection: http_verb_put In the last sentence, indicating that the program will use the http put protocol to upload files. let's look at the post protocol. If this article only involves the text, it is relatively simple. You can directly post it without constructing a form. however, once a file needs to be uploaded, two layers of HTTP and mime encapsulation are required. encapsulation requires some understanding of the HTTP header and mime identifier, Which is disgusting =, =. note that when sendrequestex is passed, the parameter is the number of bytes of the file. The number of bytes should be the total number of bytes of the file to be uploaded, the HTTP header, and the MIME header! Otherwise, even if no error occurs on the client side, the server will not get the correct result! Let's take a look at the code: cinternetsession internetsession ("My session"); // defines the session
Chttpconnection * httpconnection = internetsession. gethttpconnection (strserverip, intserverport); // get the link
Chttpfile * httpfile = httpconnection-> openrequest (chttpconnection: http_verb_post, strremotefile, null, 0, null, null, internet_flag_dont_cache); // send a request
...
Httpfile-> sendrequestex (dwtotalrequestlength, hsr_sync | hsr_initiate); let's talk about it. The post protocol has been searched by Baidu for a long time, and a similar program has been found .. later, I found a solution. After I read a masterpiece from a foreign language forum on Google, I finally figured it out ~ It seems that you still need to read more articles in the future. The source code is attached: Put Protocol: uploadfile (void)
{
}
Uploadfile ::~ Uploadfile (void)
{
}
Bool uploadfile: usehttpsendreqex (chttpfile * httpfile, DWORD dwpostsize, cstring strlocalfile)
{
Try
{
DWORD dwread, dwret;
Byte * buffer;
Trace ("local file: % s/n", strlocalfile );
File * flocal;
If (flocal = fopen (strlocalfile, "rb") = NULL)
{
Trace ("can't open the file: % s, maybe it doesn't exist! /N ", strlocalfile );
Return false;
}
Fseek (flocal, 0l, seek_end );
Dwread = ftell (flocal );
Rewind (flocal );
Buffer = (byte *) malloc (dwread );
If (! Buffer ){
Trace ("not enough memory! /N ");
Return false;
}
Trace ("length of file: % d/N", dwread );
Dwread = fread (buffer, 1, dwread, flocal );
Dwpostsize = dwread;
Internet_buffers Bufferin;
DWORD dwbyteswritten;
Bool Bret;
Bufferin. dwstructsize = sizeof (internet_buffers); // must be set or error will occur
Bufferin. Next = NULL;
Bufferin. lpcszheader = NULL;
Bufferin. dwheaderslength = 0;
Bufferin. dwheaderstotal = 0;
Bufferin. lpvbuffer = NULL;
Bufferin. dwbufferlength = 0;
Bufferin. dwbuffertotal = dwpostsize; // This is the only member used other than dwstructsize
Bufferin. dwoffsetlow = 0;
Bufferin. dwoffsethigh = 0;
Httpfile-> sendrequestex (& Bufferin, null, hsr_initiate, 0 );
// Httpfile-> sendrequestex (dwpostsize );
Httpfile-> write (buffer, dwpostsize );
If (! Httpfile-> endrequest (0, 0 ))
{
Trace ("error on httpendrequest % lu/N", getlasterror ());
Return false;
}
Fclose (flocal );
Free (buffer );
Return true;
}
Catch (cinternetexception * PEX)
{
// Catch errors from wininet
}
Return false;
}
Bool uploadfile: Upload (cstring strlocalfile, cstring strserverip, cstring strserverport, cstring strremotefile)
{
Try
{
DWORD dwpostsize = 0;
Internet_port intserverport = atoi (strserverport );
Cinternetsession internetsession ("My session ");
Chttpconnection * httpconnection = internetsession. gethttpconnection (strserverip, intserverport );
If (httpconnection = NULL)
{
Trace ("failed to connect/N ");
Return false;
}
Chttpfile * httpfile = httpconnection-> openrequest (chttpconnection: http_verb_put, strremotefile, null, 0, null, null, internet_flag_dont_cache );
// Chttpfile * httpfile = httpconnection-> openrequest (chttpconnection: http_verb_put, strremotefile );
If (httpfile = NULL)
{
Trace ("failed to open request handle/N ");
Return false;
}
If (usehttpsendreqex (httpfile, dwpostsize, strlocalfile ))
{
Trace ("/nsend finished./N ");
Httpfile-> close ();
Httpconnection-> close ();
Internetsession. Close ();
Return true;
}
Httpfile-> close ();
Httpconnection-> close ();
Internetsession. Close ();
}
Catch (cinternetexception * PEX)
{
// Catch errors from wininet
}
Return false;
}
Post Protocol: bool cvoicexctrl: uploadpcm ()
{
Tchar tempfilepath [max_path];
Tempfilepath [0] = 0;
Getenvironmentvariable (_ T ("ProgramFiles"), tempfilepath, max_path );
If (tempfilepath [0] = 0)
{
Strcpy (tempfilepath, "C: // Program Files ");
}
Strncat (tempfilepath, "// voicex // upload. PCM", max_path );
Monwave. Save (tempfilepath );
Int startp = m_standardwavurl.reversefind ('/');
Int namelen = m_standardwavurl.getlength ()-startp-1;
Cstring pcmname = m_standardwavurl.mid (startp + 1, namelen );
Cstring defservername = "www.bingoenglish.com ";
Cstring defobjectname = "/upload. jsp ";
// Uses_conversion;
Cinternetsession session;
Chttpconnection * phttpconnection = NULL; internet_port nport = 8090; cfile ftrack;
Chttpfile * phttp;
Cstring strhttpboundary;
Cstring strprefiledata;
Cstring strpostfiledata;
DWORD dwtotalrequestlength;
DWORD dwchunklength;
DWORD dwreadlength;
DWORD dwresponselength;
Tchar szerror [max_path];
Void * pbuffer;
Lpstr szresponse;
Cstring strresponse;
Bool bsuccess = true;
Cstring strdebugmessage;
If (false = ftrack. Open (tempfilepath, cfile: moderead | cfile: sharedenywrite ))
{
Afxmessagebox (_ T ("unable to open the file ."));
Return false;
}
Cstring strfilename = "Upload. PCM ";
Int irecordid = 1; strhttpboundary = _ T ("illbeverysurprisedifthisturnsup ");
Strprefiledata = makeprefiledata (strhttpboundary, pcmname, irecordid );
Strpostfiledata = makepostfiledata (strhttpboundary );
Afxmessagebox (strprefiledata );
Afxmessagebox (strpostfiledata );
Dwtotalrequestlength = strprefiledata. getlength () + strpostfiledata. getlength () + ftrack. getlength ();
Dwchunklength = 64*1024;
Pbuffer = malloc (dwchunklength );
If (null = pbuffer)
{
Return false;
}
Try
{
Phttpconnection = session. gethttpconnection (defservername, nport); phttp = phttpconnection-> openrequest (chttpconnection: http_verb_post, _ T ("/upload. jsp "));
Phttp-> addrequestheaders (makerequestheaders (strhttpboundary ));
Phttp-> sendrequestex (dwtotalrequestlength, hsr_sync | hsr_initiate );
# Ifdef _ Unicode
Phttp-> write (w2a (strprefiledata), strprefiledata. getlength ());
# Else
Phttp-> write (lpstr) (lpcstr) strprefiledata, strprefiledata. getlength ());
# Endif
Dwreadlength =-1;
While (0! = Dwreadlength)
{
Strdebugmessage. Format (_ T ("% u/N"), ftrack. getposition (), ftrack. getlength ());
Trace (strdebugmessage );
Dwreadlength = ftrack. Read (pbuffer, dwchunklength );
If (0! = Dwreadlength)
{
Phttp-> write (pbuffer, dwreadlength );
}
}
# Ifdef _ Unicode
Phttp-> write (w2a (strpostfiledata), strpostfiledata. getlength ());
# Else
Phttp-> write (lpstr) (lpcstr) strpostfiledata, strpostfiledata. getlength ());
# Endif
Phttp-> endrequest (hsr_sync );
Dwresponselength = phttp-> getlength ();
While (0! = Dwresponselength)
{
Szresponse = (lpstr) malloc (dwresponselength + 1 );
Szresponse [dwresponselength] = '/0 ';
Phttp-> Read (szresponse, dwresponselength );
Strresponse + = szresponse;
Free (szresponse );
Dwresponselength = phttp-> getlength ();
}
Afxmessagebox (strresponse );
}
Catch (cexception * E)
{
E-> geterrormessage (szerror, max_path );
E-> Delete ();
Afxmessagebox (szerror );
Bsuccess = false;
}
Phttp-> close ();
Delete phttp;
Ftrack. Close ();
If (null! = Pbuffer)
{
Free (pbuffer );
}
Return bsuccess ;}
Cstring cvoicexctrl: makerequestheaders (cstring & strboundary)
{Cstring strformat;
Cstring strdata; strformat = _ T ("Content-Type: multipart/form-data; boundary = % S/R/N"); strdata. format (strformat, strboundary); Return strdata;} cstring cvoicexctrl: makeprefiledata (cstring & strboundary, cstring & strfilename, int irecordid)
{Cstring strformat;
Cstring strdata; strformat + = _ T ("-- % s ");
Strformat + = _ T ("/R/N ");
Strformat + = _ T ("content-Disposition: Form-data; name =/" recordid /"");
Strformat + = _ T ("/R/n/R/N ");
Strformat + = _ T ("% I ");
Strformat + = _ T ("/R/N ");
Strformat + = _ T ("-- % s ");
Strformat + = _ T ("/R/N ");
Strformat + = _ T ("content-Disposition: Form-data; name =/" trackdata/"; filename =/" % S /"");
Strformat + = _ T ("/R/N ");
Strformat + = _ T ("Content-Type: Audio/WAV ");
Strformat + = _ T ("/R/N ");
Strformat + = _ T ("content-transfer-encoding: Binary ");
Strformat + = _ T ("/R/n/R/N"); strdata. format (strformat, strboundary, irecordid, strboundary, strfilename); Return strdata;} cstring cvoicexctrl: makepostfiledata (cstring & strboundary)
{Cstring strformat;
Cstring strdata; strformat = _ T ("/R/N ");
Strformat + = _ T ("-- % s ");
Strformat + = _ T ("/R/N ");
Strformat + = _ T ("content-Disposition: Form-data; name =/" submitted /"");
Strformat + = _ T ("/R/n/R/N ");
Strformat + = _ T ("hello ");
Strformat + = _ T ("/R/N ");
Strformat + = _ T ("-- % s --");
Strformat + = _ T ("/R/N"); strdata. Format (strformat, strboundary, strboundary); Return strdata ;}