• 利用Http 1.1 的POST协议上传文件


    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}

    (如需DEMO完整代码,向我索取.EMail:apexchu#hotmail.com)
  • 相关阅读:
    7.29 H5学习笔记
    8.1H5学习笔记
    8.4 H5知识点总结
    8.15 CSS知识点6
    8.12 CSS知识点5
    HTTP协议简析(二)
    php实现二分查找法
    http协议简析(一)
    telnet客户端模拟浏览器发送请求
    导入txt文件到SQL SERVER 2008
  • 原文地址:https://www.cnblogs.com/apexchu/p/740707.html
Copyright © 2020-2023  润新知