您的位置:首页 > 理论基础 > 计算机网络

使用HTTP/HTTPS向服务器上传、下载文件

2012-11-13 20:52 876 查看
这两天做了使用HTTPS协议上传、下载文件的项目,终于折腾通了。在此贴上代码,便于自己学习,也许还能帮助遇到类似问题 的人。

//1、HTTP/HTTPS下载文件

bool Download(LPCTSTR strFileURLInServer, //待下载文件的URL

              LPCTSTR strFileLocalFullPath)//存放到本地的路径

{

    ASSERT(strFileURLInServer != "");

    ASSERT(strFileLocalFullPath != "");

    CInternetSession session;

    CHttpConnection* pHttpConnection = NULL;

    CHttpFile* pHttpFile = NULL;

    CString strServer, strObject;

    INTERNET_PORT wPort;

    DWORD dwType, dwFlags;

    const int nTimeOut = 2000;

    session.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, nTimeOut); //重试之间的等待延时

    session.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 1);   //重试次数

    char* pszBuffer = NULL;  

    AfxParseURL(strFileURLInServer, dwType, strServer, strObject, wPort);

    dwFlags = 0;

    if (dwType == AFX_INET_SERVICE_HTTPS)

    {

        dwFlags = INTERNET_FLAG_SECURE |  

            INTERNET_FLAG_EXISTING_CONNECT |  

            INTERNET_FLAG_RELOAD |  

            INTERNET_FLAG_NO_CACHE_WRITE |  

            INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |  

            INTERNET_FLAG_IGNORE_CERT_CN_INVALID;  

    }

    try

    {       

        pHttpConnection = session.GetHttpConnection(strServer, wPort);

        pHttpFile = pHttpConnection->OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject,

            NULL, 1, NULL, NULL, dwFlags);   

        if (dwType == AFX_INET_SERVICE_HTTPS)

        {

            //忽略证书

            pHttpFile->QueryOption(INTERNET_OPTION_SECURITY_FLAGS, dwFlags);  

            dwFlags |= (SECURITY_FLAG_IGNORE_CERT_CN_INVALID |

                SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |

                SECURITY_FLAG_IGNORE_UNKNOWN_CA  |

                SECURITY_FLAG_IGNORE_WRONG_USAGE |

                SECURITY_FLAG_IGNORE_REVOCATION);

            //set web server option   

            BOOL s = pHttpFile->SetOption(INTERNET_OPTION_SECURITY_FLAGS, dwFlags); 

        }

        if(pHttpFile->SendRequest() == FALSE)

            return false;

        DWORD dwStateCode;

        pHttpFile->QueryInfoStatusCode(dwStateCode);

        if(dwStateCode == HTTP_STATUS_OK)

        {

            HANDLE hFile = CreateFile(strFileLocalFullPath, GENERIC_WRITE,

                FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,

                NULL);  //创建本地文件

            if(hFile == INVALID_HANDLE_VALUE)

            {

                pHttpFile->Close();

                pHttpConnection->Close();

                session.Close();

                return false;

            }

            char szInfoBuffer[1000];  //返回消息

            DWORD dwFileSize = 0;   //文件长度

            DWORD dwInfoBufferSize = sizeof(szInfoBuffer);

            BOOL bResult = FALSE;

            bResult = pHttpFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH,

                (void*)szInfoBuffer,&dwInfoBufferSize,NULL);
            dwFileSize = atoi(szInfoBuffer);

            const int BUFFER_LENGTH = 1024 * 10;

            pszBuffer = new char[BUFFER_LENGTH];  //读取文件的缓冲

            DWORD dwWrite, dwTotalWrite;

            dwWrite = dwTotalWrite = 0;

            UINT nRead = pHttpFile->Read(pszBuffer, BUFFER_LENGTH); //读取服务器上数据

            while(nRead > 0)

            {

                WriteFile(hFile, pszBuffer, nRead, &dwWrite, NULL);  //写到本地文件

                dwTotalWrite += dwWrite;

                nRead = pHttpFile->Read(pszBuffer, BUFFER_LENGTH);

            }

            delete[]pszBuffer;

            pszBuffer = NULL;

            CloseHandle(hFile);

        }

        else

        {

            delete[]pszBuffer;

            pszBuffer = NULL;

            if(pHttpFile != NULL)

            {

                pHttpFile->Close();

                delete pHttpFile;

                pHttpFile = NULL;

            }

            if(pHttpConnection != NULL)

            {

                pHttpConnection->Close();

                delete pHttpConnection;

                pHttpConnection = NULL;

            }

            session.Close();

            return false;

        }

    }

    catch(...)

    {

        delete[]pszBuffer;

        pszBuffer = NULL;

        if(pHttpFile != NULL)

        {

            pHttpFile->Close();

            delete pHttpFile;

            pHttpFile = NULL;

        }

        if(pHttpConnection != NULL)

        {

            pHttpConnection->Close();

            delete pHttpConnection;

            pHttpConnection = NULL;

        }

        session.Close();

        return false;

    }

    if(pHttpFile != NULL)

        pHttpFile->Close();

    if(pHttpConnection != NULL)

        pHttpConnection->Close();

    session.Close();

    return true;

}

//2、HTTP/HTTPS上传文件UploadFile();

CString 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 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=\"fuck\"");    

    strFormat += _T("\r\n\r\n");   

    strFormat += _T("jump");   

    strFormat += _T("\r\n");   

    strFormat += _T("--%s");

    strFormat += _T("\r\n");

    strFormat += _T("Content-Disposition: form-data; name=\"fileupload\"; filename=\"%s\"");//文件地址信息    

    strFormat += _T("\r\n");

    strFormat += _T("Content-Type: application/octet-stream");

    strFormat += _T("\r\n\r\n");

    //strData.Format(strFormat,  strBoundary,  strFileName);

    strData.Format(strFormat,  strBoundary,strBoundary,  strFileName);

    return strData;   

}

CString MakePostFileData(CString &strBoundary)//发送请求包    

{

    CString strFormat;   

    CString strData;   

    strFormat = _T("\r\n\r\n");

    strFormat += _T("--%s--");   

    strFormat += _T("\r\n");   

    strData.
4000
Format(strFormat, strBoundary, strBoundary);   

    return strData;   



BOOL UploadFile(LPCTSTR fileUrl, LPCTSTR file)

{

    CInternetSession Session;   

    CHttpConnection *pHttpConnection = NULL;   

    INTERNET_PORT   nPort;   

    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 localFile;   

    DWORD dwServiceType, dwFlags;

    localFile = file;//要传的本地文件地址    

    int startp = localFile.ReverseFind('\\');   

    int namelen = localFile.GetLength()-startp-1;   

    CString pcmname = localFile;  

    CString defServerName;//服务器名    

    CString defObjectName;//保存的地址

    CString serverPath = fileUrl;

    AfxParseURL(serverPath, dwServiceType, defServerName, defObjectName, nPort);

    dwFlags = 0;

    if (dwServiceType == AFX_INET_SERVICE_HTTPS)

    {

        dwFlags = INTERNET_FLAG_SECURE |  

            INTERNET_FLAG_EXISTING_CONNECT |  

            INTERNET_FLAG_RELOAD |  

            INTERNET_FLAG_NO_CACHE_WRITE |  

            INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |  

            INTERNET_FLAG_IGNORE_CERT_CN_INVALID;  

    }

    CString strDebugMessage;   

    if(FALSE == fTrack.Open(localFile, CFile::modeRead | CFile::shareDenyWrite))//读出文件     

    {

        return FALSE;   

    }   

    int iRecordID = 1;   

    strHTTPBoundary = _T("-------------2389jhrwfjsjd9823");//定义边界值    

    strPreFileData = MakePreFileData(strHTTPBoundary, pcmname, iRecordID);   

    strPostFileData = MakePostFileData(strHTTPBoundary);   

    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, defObjectName, 

            NULL, 1, NULL, NULL, dwFlags);   

        if (dwServiceType == AFX_INET_SERVICE_HTTPS)

        {

        //忽略证书

            pHTTP->QueryOption(INTERNET_OPTION_SECURITY_FLAGS, dwFlags);  

            dwFlags |= (SECURITY_FLAG_IGNORE_CERT_CN_INVALID |

                SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |

                SECURITY_FLAG_IGNORE_UNKNOWN_CA  |

                SECURITY_FLAG_IGNORE_WRONG_USAGE |

                SECURITY_FLAG_IGNORE_REVOCATION);

            //set web server option   

            BOOL s = pHTTP->SetOption(INTERNET_OPTION_SECURITY_FLAGS, dwFlags); 

        }

        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();   

        }   

    }    

    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;   

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  VC HTTPS
相关文章推荐