随笔 - 6  文章 - 8 评论 - 13 
<2008年3月>
2425262728291
2345678
9101112131415
16171819202122
23242526272829
303112345

常用链接

留言簿(2)

随笔分类(4)

文章档案(8)

Symbian Resources

VC Resources

搜索

  •  

最新评论

阅读排行榜

评论排行榜

Google一下关于利用CHttpFile上传文件,没有找到好用的版本(PUT的版本相对很多,但由于安全问题,实用性不大).仓促中拼揍了一个DEMO.贴出来共勉:-)

DEMO1Dlg.h
 1// DEMO1Dlg.h : 头文件
 2//
 3
 4#pragma once
 5#include "afxwin.h"
 6#include "afxinet.h"
 7#include "MyEdit.h"
 8
 9
10// CDEMO1Dlg 对话框
11class CDEMO1Dlg : public CDialog
12{
13// 构造
14public:
15    CDEMO1Dlg(CWnd* pParent = NULL);    // 标准构造函数
16
17// 对话框数据
18    enum { IDD = IDD_DEMO1_DIALOG };
19
20    protected:
21    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
22
23
24// 实现
25protected:
26    HICON m_hIcon;
27
28    // 生成的消息映射函数
29    virtual BOOL OnInitDialog();
30    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
31    afx_msg void OnPaint();
32    afx_msg HCURSOR OnQueryDragIcon();
33    DECLARE_MESSAGE_MAP()
34protected:
35    CMyEdit m_File;
36public:
37    afx_msg void OnBnClickedBtnsend();
38
39//////////////////////////////////////////////////////////////////
40//File Store//////////////////////////////////////////////////////
41//////////////////////////////////////////////////////////////////
42protected:
43    CHttpConnection* m_pConnection;
44
45private:
46    CString MakeRequestHeaders(CString& strBoundary);
47    CString MakePreFileData(CString& strBoundary, CString& strFileName, int iRecordID);
48    CString MakePostFileData(CString& strBoundary);
49public:    
50    BOOL SendTrack();    
51}
;
52

DEMO1Dlg.cpp:

  1// DEMO1Dlg.cpp : 实现文件
  2//
  3
  4#include "stdafx.h"
  5#include "DEMO1.h"
  6#include "DEMO1Dlg.h"
  7
  8#ifdef _DEBUG
  9#define new DEBUG_NEW
 10#endif
 11
 12
 13// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
 14
 15class CAboutDlg : public CDialog
 16{
 17public:
 18    CAboutDlg();
 19
 20// 对话框数据
 21    enum { IDD = IDD_ABOUTBOX };
 22
 23    protected:
 24    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
 25
 26// 实现
 27protected:
 28    DECLARE_MESSAGE_MAP()
 29}
;
 30
 31CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
 32{
 33}

 34
 35void CAboutDlg::DoDataExchange(CDataExchange* pDX)
 36{
 37    CDialog::DoDataExchange(pDX);
 38}

 39
 40BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
 41END_MESSAGE_MAP()
 42
 43
 44// CDEMO1Dlg 对话框
 45
 46
 47
 48
 49CDEMO1Dlg::CDEMO1Dlg(CWnd* pParent /*=NULL*/)
 50    : CDialog(CDEMO1Dlg::IDD, pParent)
 51{
 52    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
 53}

 54
 55void CDEMO1Dlg::DoDataExchange(CDataExchange* pDX)
 56{
 57    CDialog::DoDataExchange(pDX);
 58    DDX_Control(pDX, IDC_FILE, m_File);
 59}

 60
 61BEGIN_MESSAGE_MAP(CDEMO1Dlg, CDialog)
 62    ON_WM_SYSCOMMAND()
 63    ON_WM_PAINT()
 64    ON_WM_QUERYDRAGICON()
 65    //}}AFX_MSG_MAP
 66    ON_BN_CLICKED(ID_BTNSEND, &CDEMO1Dlg::OnBnClickedBtnsend)
 67END_MESSAGE_MAP()
 68
 69
 70// CDEMO1Dlg 消息处理程序
 71
 72BOOL CDEMO1Dlg::OnInitDialog()
 73{
 74    CDialog::OnInitDialog();
 75
 76    // 将“关于”菜单项添加到系统菜单中。
 77
 78    // IDM_ABOUTBOX 必须在系统命令范围内。
 79    ASSERT((IDM_ABOUTBOX & 0xFFF0== IDM_ABOUTBOX);
 80    ASSERT(IDM_ABOUTBOX < 0xF000);
 81
 82    CMenu* pSysMenu = GetSystemMenu(FALSE);
 83    if (pSysMenu != NULL)
 84    {
 85        CString strAboutMenu;
 86        strAboutMenu.LoadString(IDS_ABOUTBOX);
 87        if (!strAboutMenu.IsEmpty())
 88        {
 89            pSysMenu->AppendMenu(MF_SEPARATOR);
 90            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
 91        }

 92    }

 93
 94    
 96
 97    // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
 98    //  执行此操作
 99    SetIcon(m_hIcon, TRUE);            // 设置大图标
100    SetIcon(m_hIcon, FALSE);        // 设置小图标
101
102    // TODO: 在此添加额外的初始化代码
103
104    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
105}

106
107void CDEMO1Dlg::OnSysCommand(UINT nID, LPARAM lParam)
108{
109    if ((nID & 0xFFF0== IDM_ABOUTBOX)
110    {
111        CAboutDlg dlgAbout;
112        dlgAbout.DoModal();
113    }

114    else
115    {
116        CDialog::OnSysCommand(nID, lParam);
117    }

118}

119
120// 如果向对话框添加最小化按钮,则需要下面的代码
121//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
122//  这将由框架自动完成。
123
124void CDEMO1Dlg::OnPaint()
125{
126    if (IsIconic())
127    {
128        CPaintDC dc(this); // 用于绘制的设备上下文
129
130        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
131
132        // 使图标在工作矩形中居中
133        int cxIcon = GetSystemMetrics(SM_CXICON);
134        int cyIcon = GetSystemMetrics(SM_CYICON);
135        CRect rect;
136        GetClientRect(&rect);
137        int x = (rect.Width() - cxIcon + 1/ 2;
138        int y = (rect.Height() - cyIcon + 1/ 2;
139
140        // 绘制图标
141        dc.DrawIcon(x, y, m_hIcon);
142    }

143    else
144    {
145        CDialog::OnPaint();
146    }

147}

148
149//当用户拖动最小化窗口时系统调用此函数取得光标显示。
150//
151HCURSOR CDEMO1Dlg::OnQueryDragIcon()
152{
153    return static_cast<HCURSOR>(m_hIcon);
154}

155
156void CDEMO1Dlg::OnBnClickedBtnsend()
157{
158    /*CString _mFilePath;
159    GetDlgItemText(IDC_FILE,_mFilePath);
160

163    SendTrack();
164}

165
166///////////////////////////////////////////////////////////////////
167//File Store
168///////////////////////////////////////////////////////////////////
169CString CDEMO1Dlg::MakeRequestHeaders(CString &strBoundary)
170{
171    CString strFormat;
172    CString strData;
173    
174    strFormat = _T("Content-Type: multipart/form-data; boundary=%s\r\n");
175    
176    strData.Format(strFormat, strBoundary);
177
178    return strData;
179}

180
181CString CDEMO1Dlg::MakePreFileData(CString &strBoundary, CString &strFileName, int iRecordID)
182{
183    ////////////////////////////////////////////////////////////////////////////////
184    //Content-Type:
185    //JPG image/pjpeg
186    //PNG image/x-png
187    //BMP image/bmp
188    //TIF image/tiff
189    //GIF image/gif
190    CString strFormat;
191    CString strData;
192
193    strFormat += _T("--%s");
194    strFormat += _T("\r\n");
195    strFormat += _T("Content-Disposition: form-data; name=\"recordid\"");
196    strFormat += _T("\r\n\r\n");
197    strFormat += _T("%i");
198    strFormat += _T("\r\n");
199    strFormat += _T("--%s");
200    strFormat += _T("\r\n");
201    strFormat += _T("Content-Disposition: form-data; name=\"trackdata\"; filename=\"%s\"");
202    strFormat += _T("\r\n");
203    strFormat += _T("Content-Type: image/pjpeg");
204    strFormat += _T("\r\n");
205    strFormat += _T("Content-Transfer-Encoding: binary");
206    strFormat += _T("\r\n\r\n");
207
208    strData.Format(strFormat, strBoundary, iRecordID, strBoundary, strFileName);
209
210    return strData;
211}

212
213CString CDEMO1Dlg::MakePostFileData(CString &strBoundary)
214{
215    CString strFormat;
216    CString strData;
217
218    strFormat = _T("\r\n");
219    strFormat += _T("--%s");
220    strFormat += _T("\r\n");
221    strFormat += _T("Content-Disposition: form-data; name=\"submitted\"");
222    strFormat += _T("\r\n\r\n");
223    strFormat += _T("hello");
224    strFormat += _T("\r\n");
225    strFormat += _T("--%s--");
226    strFormat += _T("\r\n");
227
228    strData.Format(strFormat, strBoundary, strBoundary);
229
230    return strData;
231}

232
233BOOL CDEMO1Dlg::SendTrack()
234{
235    CString _mFilePath;
236    GetDlgItemText(IDC_FILE,_mFilePath);
237 
238    int startp = _mFilePath.ReverseFind('\\');
239    int namelen = _mFilePath.GetLength()-startp-1;
240   
241    CString pcmname = _mFilePath.Mid(startp+1,namelen);
242 
243    CString defServerName ="uploada.mytest.com";
244    CString defObjectName ="/upload.aspx";
245 
246 
247    // USES_CONVERSION;
248    CInternetSession Session;
249    CHttpConnection *pHttpConnection = NULL;
250    INTERNET_PORT   nPort = 80;
251    CFile fTrack;
252    CHttpFile* pHTTP;
253    CString strHTTPBoundary;
254    CString strPreFileData;
255    CString strPostFileData;
256    DWORD dwTotalRequestLength;
257    DWORD dwChunkLength;
258    DWORD dwReadLength;
259    DWORD dwResponseLength;
260    TCHAR szError[MAX_PATH];
261    void* pBuffer;
262    LPSTR szResponse;
263    CString strResponse;
264    BOOL bSuccess = TRUE;
265 
266    CString strDebugMessage;
267    
268    if (FALSE == fTrack.Open(_mFilePath, CFile::modeRead | CFile::shareDenyWrite))
269    {
270      AfxMessageBox(_T("Unable to open the file."));
271      return FALSE;
272    }

273 
274    int iRecordID = 1;
275    strHTTPBoundary = _T("IllBeVerySurprisedIfThisTurnsUp");
276    strPreFileData = MakePreFileData(strHTTPBoundary, pcmname, iRecordID);
277    strPostFileData = MakePostFileData(strHTTPBoundary);
278 
279    AfxMessageBox(strPreFileData);
280    AfxMessageBox(strPostFileData);
281 
282    dwTotalRequestLength = strPreFileData.GetLength() + strPostFileData.GetLength() + fTrack.GetLength();
283 
284    dwChunkLength = 64 * 1024;
285 
286    pBuffer = malloc(dwChunkLength);
287 
288    if (NULL == pBuffer)
289    {
290    return FALSE;
291    }

292 
293     try
294     {
295      pHttpConnection = Session.GetHttpConnection(defServerName,nPort);
296      pHTTP = pHttpConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, defObjectName);
297      pHTTP->AddRequestHeaders(MakeRequestHeaders(strHTTPBoundary));
298      pHTTP->SendRequestEx(dwTotalRequestLength, HSR_SYNC | HSR_INITIATE);
299      
300    #ifdef _UNICODE
301      pHTTP->Write(W2A(strPreFileData), strPreFileData.GetLength());
302    #else
303      pHTTP->Write((LPSTR)(LPCSTR)strPreFileData, strPreFileData.GetLength());
304    #endif
305      
306      dwReadLength = -1;
307      while (0 != dwReadLength)
308      {
309           strDebugMessage.Format(_T("%u / %u\n"), fTrack.GetPosition(), fTrack.GetLength());
310           TRACE(strDebugMessage);
311           dwReadLength = fTrack.Read(pBuffer, dwChunkLength);
312           if (0 != dwReadLength)
313           {
314                pHTTP->Write(pBuffer, dwReadLength);
315           }

316      }

317      
318    #ifdef _UNICODE
319      pHTTP->Write(W2A(strPostFileData), strPostFileData.GetLength());
320    #else
321      pHTTP->Write((LPSTR)(LPCSTR)strPostFileData, strPostFileData.GetLength());
322    #endif
323      
324      pHTTP->EndRequest(HSR_SYNC);
325      
326      dwResponseLength = pHTTP->GetLength();
327      while (0 != dwResponseLength)
328      {
329       szResponse = (LPSTR)malloc(dwResponseLength + 1);
330       szResponse[dwResponseLength] = '\0';
331       pHTTP->Read(szResponse, dwResponseLength);
332       strResponse += szResponse;
333       free(szResponse);
334       dwResponseLength = pHTTP->GetLength();
335      }

336      
337      AfxMessageBox(strResponse);
338      
339     }
 
340     catch (CException* e)
341     {
342      e->GetErrorMessage(szError, MAX_PATH);
343      e->Delete();
344      AfxMessageBox(szError);
345      bSuccess = FALSE;
346     }

347 
348     pHTTP->Close();
349     delete pHTTP;
350     
351     fTrack.Close();
352     
353     if (NULL != pBuffer)
354     {
355      free(pBuffer);
356     }

357     return bSuccess;
358}


posted on 2007-05-07 18:07 Boon 阅读(4233) 评论(8)  编辑 收藏 引用 所属分类: VC Other

FeedBack:
# re: 利用Http 1.1 的POST协议上传文件 2007-05-11 14:39 kim
不错哦~ 辛苦了 ^^  回复  更多评论
  
# re: 利用Http 1.1 的POST协议上传文件 2007-05-11 14:47 kim
但是论安全性的话 毕竟未机密的post数据暴露在网络上是很容易被截取利用的。  回复  更多评论
  
# re: 利用Http 1.1 的POST协议上传文件 2007-08-14 10:19 肖雄
很历害,不过我这边网页,也就是WEB那边的代码是不是要跟
strFormat = _T("\r\n");
219 strFormat += _T("--%s");
220 strFormat += _T("\r\n");
221 strFormat += _T("Content-Disposition: form-data; name=\"submitted\"");
222 strFormat += _T("\r\n\r\n");
223 strFormat += _T("hello");
224 strFormat += _T("\r\n");
225 strFormat += _T("--%s--");
226 strFormat += _T("\r\n");
这里面的设置一样吗??
我的QQ是:249281362可以交流下吗??现在很急  回复  更多评论
  
# re: 利用Http 1.1 的POST协议上传文件 2008-03-25 15:56 jm
help hello jm  回复  更多评论
  
# re: 利用Http 1.1 的POST协议上传文件[未登录] 2008-10-20 16:26 kk
我用的使IIS 对于以下代码:
CString defServerName ="uploada.mytest.com";
CString defObjectName ="/upload.aspx";

我可不可以换成
CString defServerName ="192.168.*.*";
CString defObjectName ="/test";//test是我的虚拟目录
???????????????????????????????
???????

  回复  更多评论
  
# re: 利用Http 1.1 的POST协议上传文件 2008-11-12 11:12 老林
用本文试了下,成功上传文件,赞!!!  回复  更多评论
  
# re: 利用Http 1.1 的POST协议上传文件 2010-07-25 19:52 unknown
遇到HttpEndRequest always return failed, The error code is 12002, 參考了本文,修改了http footer部份, fix it successful.

Thanks very much.  回复  更多评论
  
# re: 利用Http 1.1 的POST协议上传文件 2013-05-14 10:27 gokey
@unknown
你好,请问你是怎么修改的,我也碰上这个问题了  回复  更多评论
  
只有注册用户登录后才能发表评论。