1

我正在尝试使用 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--
"
4

2 回答 2

1

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

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

必须改为

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

还有帖子文件版本

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

 pHTTP->Write((LPSTR)(LPCSTR)CW2A(strPostFileData.GetBuffer()), strPostFileData.GetLength());
于 2013-02-14T23:44:58.257 回答
0

好吧,您的服务器端代码中有三种情况可能出错:

if ((($_FILES["file"]["type"] == "text/plain")
)
&& ($_FILES["file"]["size"] < 20000)
&& in_array($extension, $allowedExts))

除了可怕的缩进和大括号放置之外,您是否尝试过分别测试每个条件以便您知道 php 部分到底认为什么是错误的?

[错误已被删除]

于 2013-02-12T10:59:24.443 回答