使用 curlpp 在 C++ 中发出 POST 请求
Making a POST request in C++ with curlpp
我正在尝试使用 C++ 中的 curlpp 向加拿大统计局 getDataFromVectorsAndLatestNPeriods 发出 POST 请求。我似乎无法从请求中获得结果。
#include <stdlib.h>
#include <stdio.h>
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
int main()
{
curlpp::Cleanup cleanup;
curlpp::Easy request;
curlpp::Forms form;
request.setOpt(curlpp::options::Url(std::string("https://www150.statcan.gc.ca/t1/wds/rest/getDataFromVectorsAndLatestNPeriods")));
request.setOpt(curlpp::options::Verbose(true));
form.push_back(new curlpp::FormParts::Content("vectorID:54325508","latestN:1"));
request.setOpt(new curlpp::options::HttpPost(form));
request.setOpt(new curlpp::options::WriteStream(&std::cout));
request.perform();
return 0;
}
我用 g++ -std=gnu++11 -lcurl -lcurlpp cry.cpp
编译了它
而当 verbose 设置为 true 时的输出是:
* Trying 205.193.226.160...
* TCP_NODELAY set
* Connected to www150.statcan.gc.ca (205.193.226.160) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=CA; ST=Ontario; L=Ottawa; jurisdictionCountryName=CA; O=Statistics Canada; businessCategory=Government Entity; serialNumber=1970-01-01; CN=www150.statcan.gc.ca
* start date: Oct 4 16:33:01 2019 GMT
* expire date: Jan 3 17:02:58 2022 GMT
* subjectAltName: host "www150.statcan.gc.ca" matched cert's "www150.statcan.gc.ca"
* issuer: C=US; O=Entrust, Inc.; OU=See www.entrust.net/legal-terms; OU=(c) 2014 Entrust, Inc. - for authorized use only; CN=Entrust Certification Authority - L1M
* SSL certificate verify ok.
> POST /t1/wds/rest/getDataFromVectorsAndLatestNPeriods HTTP/1.1
Host: www150.statcan.gc.ca
Accept: */*
Content-Length: 161
Content-Type: multipart/form-data; boundary=------------------------8fe530d4d57d4b83
* We are completely uploaded and fine
< HTTP/1.1 415
< Date: Sat, 06 Nov 2021 03:39:47 GMT
< Content-Length: 0
< Connection: keep-alive
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Content-Security-Policy: default-src 'self' 'unsafe-inline' *.statcan.gc.ca *.statcan.ca *.stc.ca *.demdex.net *.omtrdc.net *.everesttech.net blob:; style-src 'self' 'unsafe-inline' *.statcan.gc.ca *.statcan.ca https://fonts.googleapis.com blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.statcan.gc.ca *.statcan.ca *.googletagmanager.com *.adobedtm.com *.jsdelivr.net *.mathjax.org cdnjs.cloudflare.com blob:; connect-src 'self' *.statcan.gc.ca *.statcan.ca *.stc.ca *.demdex.net *.omtrdc.net https://api.mapbox.com/ https://events.mapbox.com/; img-src 'self' *.statcan.gc.ca *.statcan.ca *.stc.ca *.demdex.net *.omtrdc.net *.everesttech.net *.jsdelivr.net data: blob:; font-src 'self' *.statcan.gc.ca *.statcan.ca https://fonts.gstatic.com; worker-src 'self' 'unsafe-inline' 'unsafe-eval' *.statcan.gc.ca *.statcan.ca blob:; frame-src 'self' 'unsafe-inline' *.statcan.gc.ca *.statcan.ca *.stc.ca https://dv-vd.shinyapps.io *.demdex.net blob:;
< Strict-Transport-Security: max-age=31536000; includeSubDomains
< Strict-Transport-Security: max-age=31536000
<
* Connection #0 to host www150.statcan.gc.ca left intact
* Closing connection 0
发生了什么,我怎样才能让它做我真正想做的事?
我没有使用过 libcurlpp
,但是对于 libcurl
,发出 POST 请求的一种自然方式是通过 CURLOPT_POST
和 CURLOPT_POST_FIELDS
选项,例如 How to use libcurl for HTTP post?。这引出了这个简单的主要内容:
int main()
{
curlpp::Cleanup cleanup;
curlpp::Easy request;
request.setOpt(curlpp::options::Url(std::string("https://www150.statcan.gc.ca/t1/wds/rest/getDataFromVectorsAndLatestNPeriods")));
// request.setOpt(curlpp::options::Verbose(true));
std::list<std::string> header =
{
"Content-Type: application/json",
"accept: application/json"
};
request.setOpt(new curlpp::options::HttpHeader(header));
std::string query = "[{\"vectorId\":54325508, \"latestN\":1}]";
request.setOpt(new curlpp::options::PostFields(query));
request.setOpt(new curlpp::options::WriteStream(&std::cout));
request.perform();
}
对于您连接的服务器,实际上可以跳过设置 HTTP header 的部分。该解决方案与 curlpp
文档中的示例 12 完全一致,https://github.com/jpbarrette/curlpp/blob/master/examples/example12.cpp .
我正在尝试使用 C++ 中的 curlpp 向加拿大统计局 getDataFromVectorsAndLatestNPeriods 发出 POST 请求。我似乎无法从请求中获得结果。
#include <stdlib.h>
#include <stdio.h>
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
int main()
{
curlpp::Cleanup cleanup;
curlpp::Easy request;
curlpp::Forms form;
request.setOpt(curlpp::options::Url(std::string("https://www150.statcan.gc.ca/t1/wds/rest/getDataFromVectorsAndLatestNPeriods")));
request.setOpt(curlpp::options::Verbose(true));
form.push_back(new curlpp::FormParts::Content("vectorID:54325508","latestN:1"));
request.setOpt(new curlpp::options::HttpPost(form));
request.setOpt(new curlpp::options::WriteStream(&std::cout));
request.perform();
return 0;
}
我用 g++ -std=gnu++11 -lcurl -lcurlpp cry.cpp
编译了它而当 verbose 设置为 true 时的输出是:
* Trying 205.193.226.160...
* TCP_NODELAY set
* Connected to www150.statcan.gc.ca (205.193.226.160) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=CA; ST=Ontario; L=Ottawa; jurisdictionCountryName=CA; O=Statistics Canada; businessCategory=Government Entity; serialNumber=1970-01-01; CN=www150.statcan.gc.ca
* start date: Oct 4 16:33:01 2019 GMT
* expire date: Jan 3 17:02:58 2022 GMT
* subjectAltName: host "www150.statcan.gc.ca" matched cert's "www150.statcan.gc.ca"
* issuer: C=US; O=Entrust, Inc.; OU=See www.entrust.net/legal-terms; OU=(c) 2014 Entrust, Inc. - for authorized use only; CN=Entrust Certification Authority - L1M
* SSL certificate verify ok.
> POST /t1/wds/rest/getDataFromVectorsAndLatestNPeriods HTTP/1.1
Host: www150.statcan.gc.ca
Accept: */*
Content-Length: 161
Content-Type: multipart/form-data; boundary=------------------------8fe530d4d57d4b83
* We are completely uploaded and fine
< HTTP/1.1 415
< Date: Sat, 06 Nov 2021 03:39:47 GMT
< Content-Length: 0
< Connection: keep-alive
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Content-Security-Policy: default-src 'self' 'unsafe-inline' *.statcan.gc.ca *.statcan.ca *.stc.ca *.demdex.net *.omtrdc.net *.everesttech.net blob:; style-src 'self' 'unsafe-inline' *.statcan.gc.ca *.statcan.ca https://fonts.googleapis.com blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.statcan.gc.ca *.statcan.ca *.googletagmanager.com *.adobedtm.com *.jsdelivr.net *.mathjax.org cdnjs.cloudflare.com blob:; connect-src 'self' *.statcan.gc.ca *.statcan.ca *.stc.ca *.demdex.net *.omtrdc.net https://api.mapbox.com/ https://events.mapbox.com/; img-src 'self' *.statcan.gc.ca *.statcan.ca *.stc.ca *.demdex.net *.omtrdc.net *.everesttech.net *.jsdelivr.net data: blob:; font-src 'self' *.statcan.gc.ca *.statcan.ca https://fonts.gstatic.com; worker-src 'self' 'unsafe-inline' 'unsafe-eval' *.statcan.gc.ca *.statcan.ca blob:; frame-src 'self' 'unsafe-inline' *.statcan.gc.ca *.statcan.ca *.stc.ca https://dv-vd.shinyapps.io *.demdex.net blob:;
< Strict-Transport-Security: max-age=31536000; includeSubDomains
< Strict-Transport-Security: max-age=31536000
<
* Connection #0 to host www150.statcan.gc.ca left intact
* Closing connection 0
发生了什么,我怎样才能让它做我真正想做的事?
我没有使用过 libcurlpp
,但是对于 libcurl
,发出 POST 请求的一种自然方式是通过 CURLOPT_POST
和 CURLOPT_POST_FIELDS
选项,例如 How to use libcurl for HTTP post?。这引出了这个简单的主要内容:
int main()
{
curlpp::Cleanup cleanup;
curlpp::Easy request;
request.setOpt(curlpp::options::Url(std::string("https://www150.statcan.gc.ca/t1/wds/rest/getDataFromVectorsAndLatestNPeriods")));
// request.setOpt(curlpp::options::Verbose(true));
std::list<std::string> header =
{
"Content-Type: application/json",
"accept: application/json"
};
request.setOpt(new curlpp::options::HttpHeader(header));
std::string query = "[{\"vectorId\":54325508, \"latestN\":1}]";
request.setOpt(new curlpp::options::PostFields(query));
request.setOpt(new curlpp::options::WriteStream(&std::cout));
request.perform();
}
对于您连接的服务器,实际上可以跳过设置 HTTP header 的部分。该解决方案与 curlpp
文档中的示例 12 完全一致,https://github.com/jpbarrette/curlpp/blob/master/examples/example12.cpp .