使用 libcurl 上传文件
Use libcurl to upload a file
我正在尝试使用 libcurl
和 post 访问一个包含文件上传的表单。我不是 100% 确定我在做什么,因为我基本上是使用 chrome 开发人员工具对网站进行逆向工程并分析 POST/GET 调用,然后我将使用 libcurl
.[= 复制它26=]
所以基本上我正在访问某种论坛,在那里可以 post 可以有附件的消息。我的程序已经可以使用 POST 以上述形式登录、阅读消息和 post 短信。唯一不起作用的是 post 发送消息和文件附件。
根据chrome开发者工具,当我使用浏览器。但是,我在 chrome 开发人员工具 中看不到任何关于文件上传的指示,因此我没有关于如何以编程方式执行此操作的提示。
基本上,我只是想做的是使用相同的 POST 使用 libcurl
我可以成功地用于 post 非附件消息,但是
- 我将包括额外的 post-参数
- 向
libcurl
提供读取函数
- 告诉
libcurl
上传(CURLOPT_UPLOAD
)
- 供应
CURLOPT_INFILESIZE
- 我也试过额外提供
CURLOPT_POST
现在,成功的 POST(没有附件)将始终重定向到概览,因此 HTTP 302 表示操作成功。
然而,一旦我尝试使用上面的代码上传,我只会收到 HTTP 200 并且消息是 not 发送。但是我可以看到调用了我的读取函数,并且传输了文件的所有字节。
有趣的是,当我省略 CURLOPT_UPLOAD
时,我可以看到我的读取函数 未被调用 (因此没有文件被传输),并且 POST 将收到 HTTP 302 作为回复,消息实际上是 posted。但是,当您查看它时,它包含一个提示 "attachment was deleted".
我知道这一切对于我尝试访问的网站来说非常特别,可能没有人能确切地知道服务器期望什么。但是谁能给我一些提示,告诉我可能出了什么问题,或者通常是什么原因造成的?
有没有人知道一些虚拟站点,我至少可以用它来测试我的一般 POST/upload 功能,以验证我的 libcurl
用法是否正确?
任何 hints/tips 非常感谢:)
- 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
几秒暂停/上传这里
< 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
我可以使用相同的 libcurl
代码将文件成功上传到 posttestserver.com,所以我不确定是什么问题。最让我困惑的是 * HTTP error before end of send, stop sending
语句。似乎服务器以某种方式 aborting/refusing 上传。在网站上,我可以看到我提交的消息,提示上传的文件已被删除(或从未完全上传?)。
会不会是 libcurl
被服务器的 302 响应弄糊涂了(这是 正常 新消息提交的响应,因为它重定向到消息概述),或者可能是什么问题?
请帮忙:(
这是我的代码:
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);
没关系,我想我在多部分表单数据中发送了错误的内容。在使用 CURLOPT_DEBUGFUNCTION
添加调试输出并仔细检查并将输出与 chrome 的输出进行比较后,我发现文件名参数与浏览器调用相比有一个错误的名称。
修复此问题后,我的上传工作正常。所以我上面的实现是正确的:)
我正在尝试使用 libcurl
和 post 访问一个包含文件上传的表单。我不是 100% 确定我在做什么,因为我基本上是使用 chrome 开发人员工具对网站进行逆向工程并分析 POST/GET 调用,然后我将使用 libcurl
.[= 复制它26=]
所以基本上我正在访问某种论坛,在那里可以 post 可以有附件的消息。我的程序已经可以使用 POST 以上述形式登录、阅读消息和 post 短信。唯一不起作用的是 post 发送消息和文件附件。
根据chrome开发者工具,当我使用浏览器。但是,我在 chrome 开发人员工具 中看不到任何关于文件上传的指示,因此我没有关于如何以编程方式执行此操作的提示。
基本上,我只是想做的是使用相同的 POST 使用 libcurl
我可以成功地用于 post 非附件消息,但是
- 我将包括额外的 post-参数
- 向
libcurl
提供读取函数
- 告诉
libcurl
上传(CURLOPT_UPLOAD
) - 供应
CURLOPT_INFILESIZE
- 我也试过额外提供
CURLOPT_POST
现在,成功的 POST(没有附件)将始终重定向到概览,因此 HTTP 302 表示操作成功。
然而,一旦我尝试使用上面的代码上传,我只会收到 HTTP 200 并且消息是 not 发送。但是我可以看到调用了我的读取函数,并且传输了文件的所有字节。
有趣的是,当我省略 CURLOPT_UPLOAD
时,我可以看到我的读取函数 未被调用 (因此没有文件被传输),并且 POST 将收到 HTTP 302 作为回复,消息实际上是 posted。但是,当您查看它时,它包含一个提示 "attachment was deleted".
我知道这一切对于我尝试访问的网站来说非常特别,可能没有人能确切地知道服务器期望什么。但是谁能给我一些提示,告诉我可能出了什么问题,或者通常是什么原因造成的?
有没有人知道一些虚拟站点,我至少可以用它来测试我的一般 POST/upload 功能,以验证我的 libcurl
用法是否正确?
任何 hints/tips 非常感谢:)
- 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
几秒暂停/上传这里
< 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
我可以使用相同的 libcurl
代码将文件成功上传到 posttestserver.com,所以我不确定是什么问题。最让我困惑的是 * HTTP error before end of send, stop sending
语句。似乎服务器以某种方式 aborting/refusing 上传。在网站上,我可以看到我提交的消息,提示上传的文件已被删除(或从未完全上传?)。
会不会是 libcurl
被服务器的 302 响应弄糊涂了(这是 正常 新消息提交的响应,因为它重定向到消息概述),或者可能是什么问题?
请帮忙:(
这是我的代码:
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);
没关系,我想我在多部分表单数据中发送了错误的内容。在使用 CURLOPT_DEBUGFUNCTION
添加调试输出并仔细检查并将输出与 chrome 的输出进行比较后,我发现文件名参数与浏览器调用相比有一个错误的名称。
修复此问题后,我的上传工作正常。所以我上面的实现是正确的:)