libcURL缓冲文件上传不工作

libcURL buffered file upload not working

本文关键字:工作 缓冲 文件 libcURL      更新时间:2023-10-16

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

代码清单1: libcurl code

#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: %sn",
                      curl_easy_strerror(res));
            curl_easy_cleanup(curl);
            curl_formfree(formpost);
        }
    }
    return 0;
}
以下是我得到的php错误:
( ! ) Notice: Undefined index: file in F:wampwwwupload_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:wampwwwupload.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文件上传处理脚本

$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";
}
?> 
当在web浏览器上运行时,HTML代码和PHP脚本(我用于测试)将显示消息

文件有效,已成功上传

后跟数组的输出。当我运行libcurl代码时,情况并非如此。我得到php错误信息和文本

上传失败

这是一个令人讨厌的错误,只有在发现时才明显。问题确实存在于对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控制文件字节被有效发布