Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用libcurl上载文件_C++_Http_Post_File Upload_Libcurl - Fatal编程技术网

C++ 使用libcurl上载文件

C++ 使用libcurl上载文件,c++,http,post,file-upload,libcurl,C++,Http,Post,File Upload,Libcurl,我正在尝试使用libcurl访问一个网站,并将其发布到包含文件上载的表单中。我不是100%确定我在做什么,因为我基本上是使用chrome开发者工具对网站进行反向工程&分析POST/GET调用,然后使用libcurl复制 所以基本上我正在访问某种论坛,在那里可以发布消息,可以有附件。我的程序已经可以登录,阅读消息,并使用post将文本消息发送到上述表单。唯一不起作用的是发布一条消息和文件附件 根据ChromeDeveloperTools,当我使用浏览器上传文件时,我只能看到同一表单的帖子,包括更多

我正在尝试使用
libcurl
访问一个网站,并将其发布到包含文件上载的表单中。我不是100%确定我在做什么,因为我基本上是使用chrome开发者工具对网站进行反向工程&分析POST/GET调用,然后使用
libcurl
复制

所以基本上我正在访问某种论坛,在那里可以发布消息,可以有附件。我的程序已经可以登录,阅读消息,并使用post将文本消息发送到上述表单。唯一不起作用的是发布一条消息和文件附件

根据ChromeDeveloperTools,当我使用浏览器上传文件时,我只能看到同一表单的帖子,包括更多参数(文件名、文件上传标志)。然而,我在chrome开发者工具中看不到任何文件上传的迹象,因此我没有关于如何通过编程方式上传的提示

基本上,我只是想使用相同的POST使用
libcurl
,我可以成功地使用它发布非附件消息,但是

  • 我将包括额外的post参数
  • libcurl
  • 告诉
    libcurl
    上传(
    CURLOPT\u upload
  • 供应
    CURLOPT_infiresize
  • 我还尝试另外提供
    CURLOPT\u POST
现在,成功的帖子(没有附件)将始终重定向到概览,因此HTTP 302表示操作成功。
但是,一旦我尝试使用上面的代码上传,我将只获得HTTP 200,并且消息不会发送。但是我可以看到我的read函数被调用了,文件的所有字节都被传输了

有趣的是,当我省略
CURLOPT_UPLOAD
时,我可以看到我的read函数没有被调用(因此没有文件被传输),POST将得到一个http302作为回复,消息实际上被发布了。但是,当您查看它时,它包含一个提示“附件已删除”

我知道这一切对于我试图访问的网站来说非常特别,可能没有人能够确切地知道服务器期望的是什么。但是,有谁能给我一些提示,说明可能出了什么问题,或者是什么原因导致了这种情况?
是否有人知道某个虚拟站点,我至少可以用它来测试我的一般POST/上传功能,以验证我的
libcurl
用法是否正确

非常感谢任何提示/提示:)


-3月12日更新:


正如daniel stenberg所建议的,我现在尝试使用multipart/formpost上传,但仍然没有成功。这就是详细输出给我的:

16/03/12 23:21:04 [HTTP] POST http://www.some.url // printed by my lib
* Found bundle for host www.some.url: 0x154f53460
* Re-using existing connection! (#1) with host www.some.url
* Connected to www.some.url (someipaddress) port 80 (#1)
> POST /some/path/ HTTP/1.1

Host: www.some.url
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:22.0)         Gecko/20100101 Firefox/22.0
Accept: */*
Cookie: FUP_sid=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;             FUP_vid=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;     FUPautologin=cb8c3ef4fcdecc390f6eca3f37814f623431219
Content-Length: 170627
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------1b0a4317b11b7518

< HTTP/1.1 100 Continue

没关系,我想我在多部分formdata中发送了错误的内容。在使用
CURLOPT_DEBUGFUNCTION
添加调试输出,并仔细检查和比较输出与chrome的输出后,我发现与浏览器调用相比,filename参数的名称错误。

修复此问题后,我的上传工作正常。所以我上面的实现是正确的:)

不管怎样,我认为我在多部分formdata中发送了错误的内容。在使用
CURLOPT_DEBUGFUNCTION
添加调试输出,并仔细检查和比较输出与chrome的输出后,我发现与浏览器调用相比,filename参数的名称错误。

修复此问题后,我的上传工作正常。因此,我上面的实现是正确的:)

您需要阅读文档<代码>CULLOPT_上传表示上传。您可能需要一个多部分的formpost,比如使用
CURLOPT\u HTTPPOST
。哦,我明白了。目前我正在使用
curl\u easy\u setopt(h,CURLOPT\u URL,URL)发布帖子
curl\u easy\u setopt(h,CURLOPT\u POSTFIELDS,fields)后接
curl\u easy\u perform(h)。因此,您的意思是将
CURLOPT\u HTTPPOST
struct curl\u HTTPPOST
一起使用(也适用于非上载)将是更好的方法,并且也基本上解决了我在这里描述的问题?这是否适用于
CURLOPT_READFUNCTION
?因为我不是在上传文件,我是在从内存上传二进制数据。你需要仔细阅读文档和我的评论。您可能需要使用确切的http post方法,是的,libcurl可以直接从内存中发送任何一种方法。尝试了您建议的方法,但没有成功。请参见上面的编辑。我在posttestserver.com上通过实现进行了测试,它可以正常工作,所以实现似乎还可以。但是它在那个特殊的网站上仍然不起作用。你需要阅读文档<代码>CULLOPT_上传
表示上传。您可能需要一个多部分的formpost,比如使用
CURLOPT\u HTTPPOST
。哦,我明白了。目前我正在使用
curl\u easy\u setopt(h,CURLOPT\u URL,URL)发布帖子
curl\u easy\u setopt(h,CURLOPT\u POSTFIELDS,fields)后接
curl\u easy\u perform(h)。因此,您的意思是将
CURLOPT\u HTTPPOST
struct curl\u HTTPPOST
一起使用(也适用于非上载)将是更好的方法,并且也基本上解决了我在这里描述的问题?这是否适用于
CURLOPT_READFUNCTION
?因为我不是在上传文件,我是在从内存上传二进制数据。你需要仔细阅读文档和我的评论。您可能需要使用确切的http post方法,是的,libcurl可以直接从内存中发送任何一种方法。尝试了您建议的方法,但没有成功。请参见上面的编辑。我在posttestserver.com上通过实现进行了测试,它可以正常工作,所以实现似乎还可以。但在那个特殊的网站上它仍然不起作用。
< HTTP/1.1 302 Found
< Date: Sat, 12 Mar 2016 22:21:04 GMT
< Server: Apache
< Cache-Control: private, proxy-revalidate, s-maxage=0, no-cache
< X-XSS-Protection: 1; mode=block
< X-Frame-Options: SAMEORIGIN
< Location: http://www.some.url/some/path/redirect/
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=UTF-8
* HTTP error before end of send, stop sending
< 
* Closing connection 1
16/03/12 23:21:06 [HTTP] DONE (0/302)    // printed by my lib, http code of last operation
struct curl_httppost* postForm = NULL;
struct curl_httppost* last = NULL;

for (HtmlInput* param= form->getFirstParameter(); param;
     param= form->getNextParameter())
{
  HtmlElement::Attribute* nameAtt= param->getAttribute("name");
  HtmlElement::Attribute* valueAtt= param->getAttribute("value");

  curl_formadd(&postForm, &last,
               CURLFORM_COPYNAME,     notNull(nameAtt ? nameAtt->value.c_str() : 0),
               CURLFORM_COPYCONTENTS, notNull(valueAtt ? valueAtt->value.c_str() : 0),
               CURLFORM_END);
}

if (attachment)
{
  curl_formadd(&postForm, &last,
               CURLFORM_COPYNAME, "name",
               CURLFORM_BUFFER, attachmentName ? attachmentName : "fileupload",
               CURLFORM_BUFFERPTR, uploadBuffer.buffer,
               CURLFORM_BUFFERLENGTH, uploadBuffer.size,
               CURLFORM_CONTENTTYPE, contentType,
               CURLFORM_END);
}

curl_easy_setopt(session, CURLOPT_URL, url);
curl_easy_setopt(session, CURLOPT_HTTPPOST, formpost);
curl_easy_setopt(session, CURLOPT_VERBOSE, 1L);

CURLcode curlCode= curl_easy_perform(session);