利用winInet实现文件上传到HTTP服务器

利用winInet实现文件上传到HTTP服务器
 最近两个星期主要搞这个东东,到今天总算比较圆满的搞定了. 用http协议上传主要有两种形式: 第一是用http的put协议,第二是用http的post协议.
  
    先说说put协议, 所谓put,顾名思义,就是把文件"放"到server端. 这个过程不涉及文件的http和mime封装(post协议需要做), 因而比较简单.但是考虑到安全问题,一般服务器不会开发put权限,因此这种方法的用途并不广泛
废话不多说,来看看代码:
   
    CInternetSession internetSession("my session"); //定义session
    CHttpConnection* httpConnection = internetSession.GetHttpConnection(strServerIP,intServerPort);                        //获得链接
CHttpFile* httpFile = httpConnection->OpenRequest(CHttpConnection::HTTP_VERB_PUT,strRemoteFile,NULL,0,NULL,NULL,INTERNET_FLAG_DONT_CACHE);                                  //发送请求
 ...
httpFile->SendRequestEx(&BufferIn,NULL,HSR_INITIATE,0);
     注意倒数第二句的CHttpConnection::HTTP_VERB_PUT, 表示程序将采用http的put协议上传文件.
 
     再看post协议,这个东东如果只涉及文本还是比较简单的,可以直接post过去,不用构造表单. 但是一旦需要上传文件, 就需要用http和mime的两层封装了. 封装需要对http头和mime标识做一些了解,很恶心=,=. 最需要注意的一点, 在最后SendRequestEx的时候, 传递的参数是文件的字节数,这个字节数应该是所要上传的文件和http头以及mime头的字节总数! 否则即使CLIENT端不出错, server也得不到正确结果的!
  
     也来看看代码吧:
  CInternetSession internetSession("my session"); //定义session
  CHttpConnection* httpConnection=internetSession.GetHttpConnection(strServerIP,intServerPort);                        //获得链接
CHttpFile* httpFile = httpConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST,strRemoteFile,NULL,0,NULL,NULL,INTERNET_FLAG_DONT_CACHE);                                  //发送请求
 ...
httpFile->SendRequestEx(dwTotalRequestLength, HSR_SYNC | HSR_INITIATE);
 
     随便说说,post协议俺用baidu搜了许久,找到了一个类似的程序,研究了许久搞不定.. 后来目有办法, google一个外文论坛, 拜读了某牛人的大作后,终于弄清楚了~ 看来以后还是要多啃鸟文啊..
 
 
     附上源代码:
 
put协议:
UpLoadFile::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,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协议:
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/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/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 / %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;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值