您还没有登陆到CGPAD.COM   现在登录   注册新用户
搜索 CGPAD.COM
 
 
 
 浏览论坛    搜索论坛    规章制度    帮助  
社区成员: 23570   主题总数: 1374   回复总数: 3307   帖子总数: 4681   论坛跳转:  
 
 
论坛 编程与开发 其他开发话题 (软件技术的领域实在太广。。。。。。) 本版斑竹:招募中...
 
发表新主题
帖子搜索:  
 
利用Http 1.1 的POST协议上传文件
查看:3266  |  回复:3  |  创建:2008-05-18 09:04:26
 
yuan (来生缘)
注册: 2008-05-06
积分: 3121 分
等级:
喜欢你,没道理!
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}




删除
 
编辑
 
标签:
 
附件:请登陆后查看附件内容!
 
声明:CGPAD文章版权属于作者,受法律保护。没有作者书面许可不得转载。
 
 <<上一页 1 下一页>>   

 注册: 2008-05-06
 积分: 3121 分
 等级:
 喜欢你,没道理!


  2008-05-18 09:05:33 #1
原文出处:http://www.cnitblog.com/apexchu/archive/2007/05/07/26710.html




 

 注册: 2008-04-24
 积分: 12335 分
 等级:
 尘世如潮人如水 只叹江湖几人回


  2008-06-05 00:09:59 #2

这里有一个非常棒的Library用于处理HTTP GET/POST请求: http://www.codeproject.com/KB/library/lyoulhttpclient.aspx

Introduction

This file contains classes which help to interact with a HTTP server. The codes contained in this file depends on the documentation of STLPort 4.6.1 (describing about exception safety).


How to use RyeolHttpClient

In your project, include the following files.

  • RyeolException.h
  • RyeolException.cpp
  • RyeolHttpClient.h
  • RyeolHttpClient.cpp
  • SafeInt.hpp

In your stdafx.h file, add the following line.

#include "RyeolHttpClient.h"

How to send a request using HTTP GET

CHttpClient supports RequestGet method which sends a request using HTTP GET.

// Retrieves the resource specified by the szUrl using HTTP GET request.
// szUrl            [in] A HTTP URL.
// bUseCache        [in] Specifies whether to use cache.
CHttpResponse * CHttpClient::RequestGet (PCSZ szUrl, BOOL bUseCache = FALSE) throw (Exception &) ;

The following code demonstrates the basic usage of the RequestGet method.

using namespace Ryeol ;

CHttpClient         objHttpReq ;
CHttpResponse *     pobjHttpRes = NULL ;

try {
    // Initialize the User Agent
    objHttpReq.SetInternet (_T ("My User Agent v1.0")) ;

    // Specifies whether to use UTF-8 encoding. (This uses ANSI encoding)
    // Default is FALSE
    objHttpReq.SetUseUtf8 (FALSE) ;

    // Specifies a code page for ANSI strings. (This uses Korean)
    // Default is CP_ACP
    objHttpReq.SetAnsiCodePage (949) ;

    // Add user's custom HTTP headers
    objHttpReq.AddHeader (_T ("Ryeol-Magic"), _T ("My Magic Header")) ;
    objHttpReq.AddHeader (_T ("User-Magic"), _T ("User's Magic Header")) ;

    // Add user's parameters
    objHttpReq.AddParam (_T ("where"), _T ("nexearch")) ;
    objHttpReq.AddParam (_T ("frm"), _T ("t1")) ;
    objHttpReq.AddParam (_T ("query"), _T ("%C3%D6%C1%F6%BF%EC"), CHttpClient::ParamEncodedValue) ;

    // Send a request
    pobjHttpRes = objHttpReq.RequestGet (_T ("http://search.naver.com/search.naver")) ;

    ...     // Place codes to handle the returned CHttpResponse object.

} catch (httpclientexception & e) {
    ...     // Place exception handling codes here.
}

How to send a request using HTTP POST

The HTTP POST method is used in two ways. One is to post simple text, the other is to upload file. To post simple text, CHttpClient provides BeginPost method.

// Starts a new HTTP POST request
// szUrl            [in] A HTTP URL.
// bUseCache        [in] Specifies whether to use cache.
void CHttpClient::BeginPost (PCSZ szUrl, BOOL bUseCache = FALSE) throw (Exception &) ;

The following code demonstrates the basic usage of the BeginPost method.

using namespace Ryeol ;

CHttpClient         objHttpReq ;
CHttpResponse *     pobjHttpRes = NULL ;

try {
    // Initialize the User Agent
    objHttpReq.SetInternet (_T ("My User Agent v1.0")) ;

    // Add user's custom HTTP headers
    objHttpReq.AddHeader (_T ("Ryeol-Magic"), _T ("My Magic Header")) ;
    objHttpReq.AddHeader (_T ("User-Magic"), _T ("User's Magic Header")) ;

    // Add user's parameter
    objHttpReq.AddParam (_T ("st"), _T ("kw")) ;
    objHttpReq.AddParam (_T ("target"), _T ("WinInet")) ;

    // Start a new request
    objHttpReq.BeginPost (_T ("http://www.codeproject.com/info/search.asp")) ;

    // Specifies the number of bytes to send when the Proceed method is called.
    const DWORD     cbProceed = 1024 ;  // 1K

    do {

        ...     // Place codes to report progress information to user.

    } while ( !(pobjHttpRes = objHttpReq.Proceed (cbProceed)) ) ;

    ...     // Place codes to handle the returned CHttpResponse object.

} catch (httpclientexception & e) {
    ...     // Place exception handling codes here.
}

To upload file, CHttpClient provides BeginUpload method.

// Starts a new UPLOAD request
// szUrl            [in] A HTTP URL.
// bUseCache        [in] Specifies whether to use cache.
void CHttpClient::BeginUpload (PCSZ szUrl, BOOL bUseCache = FALSE) throw (Exception &) ;

The following code demonstrates the basic usage of the BeginUpload method.

using namespace Ryeol ;

CHttpClient         objHttpReq ;
CHttpResponse *     pobjHttpRes = NULL ;

try {
    // Initialize the User Agent
    objHttpReq.SetInternet (_T ("My User Agent v1.0")) ;

    // Add user's custom HTTP headers
    objHttpReq.AddHeader (_T ("Ryeol-Magic"), _T ("My Magic Header")) ;
    objHttpReq.AddHeader (_T ("User-Magic"), _T ("User's Magic Header")) ;

    // Add user's parameters
    objHttpReq.AddParam (_T ("nohtml"), _T ("1")) ;
    objHttpReq.AddParam (_T ("title"), _T ("The K-NET photo")) ;
    objHttpReq.AddParam (_T ("content"), _T ("A photo of the K-NET")) ;

    // Specifies a file to upload
    objHttpReq.AddParam (_T ("ufile01"), _T ("D:\\My Photo\\K-NET\\photo1.jpg"), CHttpClient::ParamFile) ;

    // Start a new request
    objHttpReq.BeginUpload (_T ("http://club.hooriza.com/cmd/box.html?clubid=1&boxid=53&action=store&link=")) ;

    // Specifies the number of bytes to send when the Proceed method is called.
    const DWORD     cbProceed = 1024 ;  // 1K

    do {

        ...     // Place codes to report progress information to user.

    } while ( !(pobjHttpRes = objHttpReq.Proceed (cbProceed)) ) ;

    ...     // Place codes to handle the returned CHttpResponse object.

} catch (httpclientexception && e) {
    ...     // Place exception handling codes here.
}

How to handle the returned CHttpResponse object

When you send a request using CHttpClient, all method will return CHttpResponse object. CHttpResponse represents the response returned by a HTTP web server. CHttpResponse provides following methods.

// Returns the number of headers of which name is the szName
DWORD CHttpResponse::GetHeaderCount (PCSZ szName) throw (Exception &) ;

// Returns the header of which name is the szName
PCSZ CHttpResponse::GetHeader (PCSZ szName, DWORD nIdx = 0) throw (Exception &) ;

// Returns the HTTP status code returned by a HTTP server
DWORD CHttpResponse::GetStatus (void) throw (Exception &) ;

// Returns the HTTP status text returned by a HTTP server
PCSZ CHttpResponse::GetStatusText (void) throw (Exception &) ;

// Retrieves the length of the content returned by a HTTP server
BOOL CHttpResponse::GetContentLength (DWORD & cbContLen) throw (Exception &) ;

// Reads the content returned by a HTTP server
DWORD CHttpResponse::ReadContent (BYTE * pbyBuff, DWORD cbBuff) throw (Exception &) ;

The following code demonstrates the basic usage of the CHttpResponse object.

using namespace Ryeol ;

CHttpResponse *     pobjHttpRes = NULL ;

try {
    // Get the CHttpResponse object
    pobjHttpRes = ... ;

    // Reads the HTTP status code
    _tprintf (_T ("%u"), pobjHttpRes->GetStatus ()) ;
    // Reads the HTTP status text
    _tprintf (_T (" %s\n"), pobjHttpRes->GetStatusText ()) ;

    // Reads HTTP headers using an array of header names
    static LPCTSTR      szHeaders[] = 
    { _T ("Server"), _T ("Date"), _T ("X-Powered-By"), _T ("Content-Length"), _T ("Set-Cookie")
    , _T ("Expires"), _T ("Cache-control"), _T ("Connection"), _T ("Transfer-Encoding")
    , _T ("Content-Type") } ;

    LPCTSTR     szHeader ;
    for (size_t i = 0; i < sizeof (szHeaders) / sizeof (LPCTSTR); i++) {
        if ( szHeader = pobjHttpRes->GetHeader (szHeaders[i]) )
            _tprintf (_T ("%s: %s\n"), szHeaders[i], szHeader) ;
        else
            // If the header is not found..
            _tprintf (_T ("'%s' header does not exist..\r\n"), szHeaders[i]) ;
    }

    _tprintf (_T ("\r\n")) ;

    // Checks whether the returned stream is a text
    BOOL        bIsText = FALSE ;
    if ( szHeader = pobjHttpRes->GetHeader (_T ("Content-Type")) )
        bIsText = (0 == ::_tcsncicmp (szHeader, _T ("text/"), 5)) ;

    // Reads the length of the stream
    DWORD       dwContSize ;
    // If the length is not specified
    if ( !pobjHttpRes->GetContentLength (dwContSize) )
        dwContSize = 0 ;

    const DWORD     cbBuff = 1024 * 10 ;
    BYTE            byBuff[cbBuff] ;
    DWORD           dwRead ;
    size_t          cbTotal = 0 ;

    // Reads the data stream returned by the HTTP server.
    while ( dwRead = pobjHttpRes->ReadContent (byBuff, cbBuff - 1) ) {
        cbTotal += dwRead ;

        if ( bIsText ) {
            byBuff[dwRead] = '\0' ;
            printf ("%s", reinterpret_cast<LPCSTR> (byBuff)) ;
        }
    }

    if ( !bIsText )
        _tprintf (_T ("%u bytes skipped..\n"), cbTotal) ;

} catch (httpclientexception & e) {
    ...     // Place exception handling codes here.
}

delete pobjHttpRes ;
pobjHttpRes = NULL ;

How to handle exception

When an error occurred, httpclientexception object is thrown.

class httpclientexception {
public:
    // Returns the last error code. The error codes is defined in RyeolHttpClient.h
    DWORD LastError (void) const throw () ;

    // Returns the last error message.
    LPCTSTR errmsg (void) const throw () ;

    // Returns the last win32 error code retrieved by using ::GetLastError when an error occurred.
    DWORD Win32LastError (void) const throw () ;
} ;

Before throwing an exception, most methods restore their internal states. (all or nothing like transaction) But if you call BeginPost or BeginUpload method, the POST context is automatically canceled. You should write the following try-catch block to handle the exception.

using namespace Ryeol ;

try {

    ...     // Place codes which throw a httpclientexception exception

} catch (httpclientexception & e) {
    _tprintf (_T ("An error has been occured\n")) ;
    _tprintf (_T ("ErrCode: 0x%x\n"), e.LastError ()) ;
    _tprintf (_T ("ErrMsg: %s\n"), e.errmsg ()) ;
    if ( e.Win32LastError () != NO_ERROR ) {
        TCHAR       szErrMsg[512] ;
        GetWinInetErrMsg (szErrMsg, 512, e.Win32LastError ()) ;

        _tprintf (_T ("Win32ErrCode: 0x%x\n"), e.Win32LastError ()) ;
        _tprintf (_T ("Win32ErrMsg: %s\n"), szErrMsg) ;
    }
}

How to show progress information to user

If you call BeginPost or BeginUpload method, you can retrieve progress information using Query method.

// Queries progress information of the current POST context
// objPostStat      [out] A CHttpPostStat object.
void CHttpClient::Query (CHttpPostStat & objPostStat) throw () ;

CHttpPostStat represents progress information of the current POST context. The following code demonstrates the basic usage of the CHttpPostStat object.

using namespace Ryeol ;

CHttpClient         objHttpReq ;
CHttpResponse *     pobjHttpRes = NULL ;
size_t              cbProceed = 1024 ;  // 1k

try {
    ... ;   // Intialize the CHttpClient object

    // Starts a new POST request
    objHttpReq.BeginPost (...) or objHttpReq.BeginUpload (...) ;

    // Displays progress information
    CHttpPostStat       objPostStat ;

    do {
        // Retrieves progress information
        objHttpReq.Query (objPostStat) ;

        _tprintf (_T ("\nPost in progress... %2u/%2u\n")
            , objPostStat.PostedCount ()            // The number of posted parameters
            , objPostStat.TotalCount ()) ;          // The total number of parameters

        _tprintf (_T ("%s: %10u/%10u %10u/%10u %10u/%10u\n")
            , objPostStat.CurrParam ()              // The name of the current parameter
            , objPostStat.CurrParamPostedByte ()    // The number of posted bytes of the current parameter
            , objPostStat.CurrParamTotalByte ()     // The total number of bytes of the current parameter
            , objPostStat.PostedByte ()             // The number of posted bytes of the request
            , objPostStat.TotalByte ()              // The total number of bytes of the request
            , objPostStat.ActualPostedByte ()       // The actual number of posted bytes of the request
            , objPostStat.ActualTotalByte ()) ;     // The actual total number of bytes of the request

        // If the current parameter is a file parameter, displays the file path
        if ( objPostStat.CurrParamIsFile () )
            _tprintf (_T ("-->%s\n")
                , objPostStat.CurrFile ()) ;

        // Sends the number of bytes specified by cbProceed to the server
    } while ( !(pobjHttpRes = objHttpReq.Proceed (cbProceed)) ) ;

    ... ;   // Handles the returned CHttpResponse object

} catch (httpclientexception & e) {
    ...     // Place exception handling codes here.
}





 

 注册: 2008-04-24
 积分: 12335 分
 等级:
 尘世如潮人如水 只叹江湖几人回


  2008-06-05 21:55:24 #3
FMF上传作品的时候就是用RyeolHttpClient来处理的,它支持UTF8,所以中文也能很好的搞定。用起来很方便,主要是因为作者写了很详细的instruction。




 
 <<上一页 1 下一页>>   
 
 
版权所有 © 2005-2008 CGPAD.COM,湘ICP备07500998号,兼容浏览器:IE6IE7FireFoxOperaSafariChrome
Total Requests: 5275898, Total Visits: 3085105, Processing Time: 43ms,