libcURL缓冲文件上传不起作用

时间:2014-08-18 19:51:29

标签: c++ libcurl

我正在尝试使用libcurl上传文件。但我得到的只是php错误,好像我没有任何POST数组调用脚本。

代码清单1: libcurl代码

#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdlib>
#include <curl/curl.h>

int main(int argc, char *argv[])
{
    CURL *curl;
    CURLcode res;


    std::streampos size;
    char * memblock;

    std::ifstream file ("unnamed.png", std::ios::in|std::ios::binary|std::ios::ate);
    if (file.is_open())
    {
        size = file.tellg();
        memblock = new char [size];
        file.seekg (0, std::ios::beg);
        file.read (memblock, size);
        file.close();

        struct curl_httppost *formpost=NULL;
        struct curl_httppost *lastptr=NULL;

        curl_formadd(&formpost,
                &lastptr,
                CURLFORM_COPYNAME, "file",
                CURLFORM_BUFFER, "unnamed.png",
                CURLFORM_BUFFERPTR, memblock,
                CURLFORM_BUFFERLENGTH, size,
                CURLFORM_END);


        curl = curl_easy_init();

        if(curl) {

            curl_easy_setopt(curl, CURLOPT_URL, "http://localhost/upload_file.php");

            curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);


            res = curl_easy_perform(curl);
            if(res != CURLE_OK)
              fprintf(stderr, "curl_easy_perform() failed: %s\n",
                      curl_easy_strerror(res));

            curl_easy_cleanup(curl);
            curl_formfree(formpost);
        }

    }

    return 0;
}

以下是我得到的php错误:

( ! ) Notice: Undefined index: file in F:\wamp\www\upload_file.php on line 4
Call Stack
#   Time    Memory  Function    Location
1   0.0003  240408  {main}( )   ..\upload_file.php:0

Notice: Undefined index: file in F:\wamp\www\upload.php on line 8
Call Stack
#   Time    Memory  Function    Location
1   0.0003  242624  {main}( )   ..\upload.php:0

此外,我想知道是否应该以某种方式添加内容类型。我知道CURLFORM_FILE有CURLFORM_CONTENTTYPE,但我没有看到任何CURLFORM_BUFFER。

编辑:这是HTML上传表单和PHP文件上传处理脚本。

代码清单2: html表单

<form enctype="multipart/form-data" action="upload.php" method="POST">
    Send this file: <input name="file" type="file" />
    <input type="submit" value="Send File" />
</form>

代码清单3: php fileupload处理脚本     

$uploaddir = '/';
$uploadfile = $uploaddir . basename($_FILES['file']['name']);

echo "<p>";

if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
  echo "File is valid, and was successfully uploaded.\n";
    echo '<pre>';
      print_r($_FILES);
    print "</pre>";
} else {
   echo "Upload failed";
}

?> 

HTML代码和PHP脚本(我用于测试)将显示何时在Web浏览器上运行消息

  

文件有效,已成功上传

然后打印数组。当我运行libcurl代码时不是这种情况。我收到了php错误消息和文本

  

上传失败

1 个答案:

答案 0 :(得分:4)

这是一个令人讨厌的错误,只有在发现时才会显而易见。问题确实在于对curl_formadd的呼吁。如果参数不正确(在下面这种情况,请参见下文),则该函数不执行任何操作,只返回非空值。您没有注意到它,因为您忘记测试返回代码(并且此处没有预料到错误...)

所以当你发帖时,你会做一个空帖子(没有部分),这完全解释了php脚本中的错误。

问题是CURLFORM_BUFFERLENGTH之后的参数必须是long,而您传递std::streampos

修复很简单(我还添加了内容类型):

long lsize = size.seekpos();

CURLFORMcode code = curl_formadd(&formpost,
    &lastptr,
    CURLFORM_COPYNAME, "file",
    CURLFORM_BUFFER, "unnamed.png",
    CURLFORM_BUFFERPTR, memblock,
    CURLFORM_BUFFERLENGTH, lsize,
    CURLFORM_CONTENTTYPE, "image/png",
    CURLFORM_END);
if (code != 0) {
    // to avoid other problems ...
}

我可以通过wireshark控制文件字节是否有效发布。