c++ - 使用返回无效 win api 的 http post 上传 MFC C++ 文件

标签 c++ file-upload mfc http-post

我正在尝试使用 MFC C++ 上传文件,但由于某种原因,我在上传时收到无效文件。我觉得这可能是由于我使用的标题或帖子信息错误导致的问题,但经过几个小时的尝试后我找不到我的错误。这是我的代码。如果您的专家可以详细说明我的错误,以便我可以更正,我将不胜感激...

void CFileUpload::UploadByPost(CString strFileName,CString  strServerUrl,CString strServerUploadFile)
{

DWORD dwTotalRequestLength;
DWORD dwChunkLength;
DWORD dwReadLength;
DWORD dwResponseLength;
CHttpFile* pHTTP = NULL;

dwChunkLength = 64 * 1024; 
void* pBuffer = malloc(dwChunkLength);
CFile file ;

if (!file.Open(strFileName.GetBuffer(),
  CFile::modeRead | CFile::shareDenyWrite))
 {
        return;
   }

CInternetSession session(L"sendFile");
CHttpConnection *connection = NULL;

try
{
    //Create the multi-part form data that goes before and after the actual file upload.

    CString strHTTPBoundary = _T("FFF3F395A90B452BB8BEDC878DDBD152");       
    CString strPreFileData = MakePreFileData(strHTTPBoundary, file.GetFileName());
    CString strPostFileData = MakePostFileData(strHTTPBoundary);
    CString strRequestHeaders = MakeRequestHeaders(strHTTPBoundary);
    dwTotalRequestLength = strPreFileData.GetLength() + strPostFileData.GetLength() + file.GetLength();

    connection = session.GetHttpConnection(/*L"www.YOURSITE.com"*/strServerUrl.GetBuffer(),NULL,INTERNET_DEFAULT_HTTP_PORT);

    pHTTP = connection->OpenRequest(CHttpConnection::HTTP_VERB_POST, strServerUploadFile.GetBuffer());//_T("/YOUURL/submit_file.pl"));
    pHTTP->AddRequestHeaders(strRequestHeaders);
    pHTTP->SendRequestEx(dwTotalRequestLength, HSR_SYNC | HSR_INITIATE);

    //Write out the headers and the form variables
    pHTTP->Write((LPSTR)(LPCSTR)strPreFileData.GetBuffer(), strPreFileData.GetLength());

    //upload the file.

    dwReadLength = -1;
    int length = file.GetLength(); //used to calculate percentage complete.
    while (0 != dwReadLength)
    {
        dwReadLength = file.Read(pBuffer, dwChunkLength);
        if (0 != dwReadLength)
        {
        pHTTP->Write(pBuffer, dwReadLength);
        }
    }

    file.Close();

    //Finish the upload.
    pHTTP->Write((LPSTR)(LPCSTR)strPostFileData.GetBuffer(), strPostFileData.GetLength());
    pHTTP->EndRequest(HSR_SYNC);


    //get the response from the server.
    LPSTR szResponse;
    CString strResponse;
    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();
    }

    TRACE(L"%s",strResponse.GetBuffer());

    //close everything up.
    pHTTP->Close();
    connection->Close();
    session.Close();
}
catch(CInternetException* e)
{
    TRACE(L"error: %d \n",e->m_dwError);
}
catch(CFileException* e)
{
    TRACE(L"error: %d \n",e->m_cause);
}
catch(...)
{
    TRACE(L" unexpected error");
}

}

这是我的标题和帖子功能

CString CFileUpload::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 CFileUpload::MakePreFileData(CString& strBoundary, CString& strFileName)
{
CString strFormat;
CString strData;

strFormat += _T("--%s");
strFormat += _T("\r\n");
strFormat += _T("Content-Disposition: form-data; name=\"file\"; filename=\"%s\"");
strFormat += _T("\r\n");
strFormat += _T("Content-Type: text/plain");
strFormat += _T("\r\n");
strFormat += _T(" XXXXX ");
strFormat += _T("\r\n\r\n");

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

return strData;
}

CString CFileUpload::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=\"submit\"");
strFormat += _T("\r\n\r\n");
strFormat += _T("");
strFormat += _T("\r\n");
strFormat += _T("--%s--");
strFormat += _T("\r\n");

strData.Format(strFormat, strBoundary, strBoundary);

return strData;

}

它总是返回无效文件,我使用的文件服务器代码如下

<?php
$allowedExts = array("log", "txt");
$extension = end(explode(".", $_FILES["file"]["name"]));
if ((($_FILES["file"]["type"] == "text/plain")
)
&& ($_FILES["file"]["size"] < 20000)
&& in_array($extension, $allowedExts))
  {
  if ($_FILES["file"]["error"] > 0)
    {
    echo "Error: " . $_FILES["file"]["error"] . "<br>";
    }
  else
    {
    echo "Upload: " . $_FILES["file"]["name"] . "<br>";
    echo "Type: " . $_FILES["file"]["type"] . "<br>";
    echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
    echo "Stored in: " . $_FILES["file"]["tmp_name"];
    }
  }
else
  {
  echo "Invalid file";
  }
?> 

这是表格

<html>
<body>

<form action="upload_file.php" method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="Submit">
</form>

</body>
</html> 

注意:- 我不能使用 boost 或 poco、curl 或任何第三方库.. 只能使用 win32 或 mfc。

这是制作前和制作后的数据:

标题

"Content-Type: multipart/form-data; boundary=FFF3F395A90B452BB8BEDC878DDBD152
"

前文件

"--FFF3F395A90B452BB8BEDC878DDBD152
Content-Disposition: form-data; name="Filename"; filename="ddd.txt"
Content-Type: text/plain
Content-Transfer-Encoding: binary

"

发布文件

"
--FFF3F395A90B452BB8BEDC878DDBD152
Content-Disposition: form-data; name="submit" value="submit"


--FFF3F395A90B452BB8BEDC878DDBD152--
"

最佳答案

最后我得到了错误....这不是因为后文件或前文件数据或标题或服务器脚本,而是因为我从 http 对象调用写函数并将 unicode 转换为 ansi 的方式没有任何适当的转换。 ...我不知道我怎么没有意识到我犯的这个愚蠢的错误,哈哈...但为了其他人,我也想分享这些信息......

pHTTP->Write((LPSTR)(LPCSTR)strPreFileData.GetBuffer(), strPreFileData.GetLength());

必须更改为

pHTTP->Write((LPSTR)(LPCSTR)CW2A(strPreFileData.GetBuffer()), strPreFileData.GetLength());

还有post文件版本

 pHTTP->Write((LPSTR)(LPCSTR)strPostFileData.GetBuffer(), strPostFileData.GetLength());

 pHTTP->Write((LPSTR)(LPCSTR)CW2A(strPostFileData.GetBuffer()), strPostFileData.GetLength());

关于c++ - 使用返回无效 win api 的 http post 上传 MFC C++ 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14789018/

相关文章:

c++ - cin 和 continue 在一行中以逗号分隔

c++ - 防止将 AddString(某些进程)添加到组合框 MFC

file-upload - DropboxSDK : What's the benefit of uploadFileChunk: over uploadFile: in DBRestClient?

java - API 调用中文件扩展名的 HTTP header 参数

bitmap - 将 CBitmap 保存到 .bmp 文件

c++ - VS2010不理解自己文件的字符串编码

c++ - 我可以设置 array[n+k] = array[0] 吗?

c++ - 从 C++ 调用 Web 服务

c++ - 动态分配其中包含 vector 的结构

javascript - 使用 SWFUpload 或 FileSystemObject activeX 哪个更安全?