WinSock手动HTTP文件上传

时间:2015-11-10 00:11:47

标签: c++ file http post upload

我正在使用Winsock API在C ++中编写一些HTTP通信。我在执行GET请求和接收响应时没有遇到任何问题,但是在尝试通过POST请求执行文件上载时遇到问题。

首先,我将分享我的PHP文件的代码,它接收上传请求(upload.php):

<?php
if(isset($_FILES['file'])){
    $errors= array();
    $file_name = $_FILES['file']['name'];
    $file_size =$_FILES['file']['size'];
    $file_tmp =$_FILES['file']['tmp_name'];
    $file_type=$_FILES['file']['type'];   
    $file_ext=strtolower(end(explode('.',$_FILES['file']['name'])));

    if(empty($errors)==true){
        move_uploaded_file($file_tmp,"uploads/".$file_name);
        echo "Success";
    }
}

else{
    echo "Was no file";
}
?>

<form action="" method="POST" enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="submit"/>
</form>

现在我知道这段代码没有任何问题,因为我成功使用WinInet API(HttpSendRequest)执行文件上传。我的WinInet代码适用于此PHP文件,包含以下主要步骤:

HttpOpenRequest(..., "POST", "uploader/upload.php", "HTTP/1.0", NULL, NULL, NULL, NULL)
HttpSendRequest with headers I set to: "Content-Type: multipart/form-data; boundary=---------FILE_BOUNDARY----------". I printed out the request body that was built by my program as you can see here, sorry I didn't print it out in a way which I could copy and paste here: http://i.imgur.com/mMmo7Xd.png

这很好用,文件正确上传。然而,当我尝试&#34; port&#34;此代码使用winsock API代替wininet。有了winsock,你可能知道,我必须完全手动构建整个请求(标题和正文)。我认为这必须是我的问题所在,因为请求本身的主体与我使用wininet API时的主体相同。以下是我发送的winsock请求的打印输出:http://i.imgur.com/TkLNGrq.png

PS我不知道为什么MessageBox将标题的边界部分放在另一行上,不是&#34; \ r \ n&#34;在我的代码中。这可能与我的问题有关吗?这是我构建整个请求字符串的代码。请不要给我关于安全性和缓冲区溢出的指示,这不是生产代码:

wsprintfA(FullReqStr, 
    // Headers
    "POST %s HTTP/1.0\r\n"
    "Host: %s\r\n"
    "Content-Type: multipart/form-data; boundary=---------FILE_BOUNDARY----------\r\n\r\n"
    // Body
    "-----------FILE_BOUNDARY----------\r\n"
    "Content-Disposition: form-data; name=\"file\"; filename=\"file.log\"\r\nContent-Type: application/octet-stream\r\n\r\n"
    "%s\r\n"
    "-----------FILE_BOUNDARY----------\r\n"
    "Content-Disposition: form-data; name=\"submit\"\r\n\r\n"
    "Submit\r\n"
    "-----------FILE_BOUNDARY------------\r\n",
    GatePath,  Server, FileBody
    );

是的,winsock请求中的文件字节不同,我使用不同的文件字节进行测试。这是重点。基本上,当我发送该请求并收到响应时,它会命中&#34;没有文件&#34;否则在PHP文件中。我觉得我必须在winsock请求的标题中缺少一些必填字段,否则在使用WinInet API时会自动添加。我想不出别的什么,但是我不确定我错过了什么。

有人能指出我的Winsock代码有什么问题吗?我将不胜感激。谢谢。顺便说一句,请注意,我并不是在寻找任何安全性或任何内容。我正试着让它发挥作用。它不适用于任何需要安全的系统或任何其他系统。

感谢。

1 个答案:

答案 0 :(得分:0)

看起来我没有仔细阅读RFC。 http://www.ietf.org/rfc/rfc1867.txt

我需要添加&#34; Content-Length&#34;字段到我的HTTP标头。现在我首先构造请求的主体,以便我可以获取长度,然后使用它构造整个请求。工作正常。