Я использую libcurl с C ++ для отправки запроса POST, чтобы запросить некоторую информацию о RateBeer по конкретному пиву.В нем говорится, что данные были отправлены, но я получаю сообщение об ошибке «POST fields empty» (я полагаю, что это на стороне graphQL).
Ниже приведен дамп текущего результата (у меня также есть печать необработанных данных постов)
* Trying 13.249.142.63...
* TCP_NODELAY set
* Connected to api.r8.beer (13.249.142.63) port 443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: none
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=*.r8.beer
* start date: Aug 14 00:00:00 2018 GMT
* expire date: Sep 14 12:00:00 2019 GMT
* subjectAltName: host "api.r8.beer" matched cert's "*.r8.beer"
* issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
* SSL certificate verify ok.
> POST /v1/api/graphql/ HTTP/1.1
Host: api.r8.beer
User-Agent: libcurl-agent/1.0
Content-Type:application/json
Accept:application/json
x-api-[key:Removed for privacy]
Transfer-Encoding: chunked
cb
* upload completely sent off: 210 out of 203 bytes
< HTTP/1.1 500 Internal Server Error
< Content-Type: application/json
< Content-Length: 61
< Connection: keep-alive
< Date: Thu, 31 Jan 2019 16:07:38 GMT
< x-amzn-RequestId: 547d7bc7-2572-11e9-b411-af48978c268e
< CF-RAY: 4a1d6eb288bda66b-DUB
< Access-Control-Allow-Origin: *
< Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, x-api-key, x-api-auth
< x-amzn-Remapped-Connection: keep-alive
< X-Request-Id: 54b37fa0-2572-11e9-ac7f-9d4fc71779d1
< Set-Cookie: __cfduid=d84de3db6937ad5bef73abca5ae68e43a1548950858; expires=Fri, 31-Jan-20 16:07:38 GMT; path=/; domain=.r8.beer; HttpOnly; Secure
< x-amz-apigw-id: UYGDpFkeDoEFR2w=
< x-amzn-Remapped-Server: cloudflare
< X-Powered-By: Express
< x-amzn-Remapped-Date: Thu, 31 Jan 2019 16:07:38 GMT
< X-Cache: Error from cloudfront
< Via: 1.1 feeead777aa6b11f4775062f1953fdc4.cloudfront.net (CloudFront)
< X-Amz-Cf-Id: kg0xraCi9C9zdmNff3iEZXOBpTMKPwNSQa6nzV-tyXqCdVCFFOP2Jg==
<
* Connection #0 to host api.r8.beer left intact
{"query":"query{\nTruth:beerSearch(query: \"Truth\", first : 5) {\n...beerfields\n}\n}\nfragment beerfields on BeerList{\nitems{\nname\nbrewer{\nname\n}\ndescription\nratingCount\n}\n}","variables":"{}"}
Response: POST body missing. Did you forget use body-parser middleware Response End
Некоторая отладка, которую я пробовал в этом завоевании:
Изменение кода для использования обратного вызова обратного чтения вместо использования значения по умолчанию POST_FIELDS, тот же результат
Использование заглавных букв в заголовках
- Изменен метод передачи для использования chunked
- Попытка POST к API песочницы и производственному API
Вот функция запроса:
NOTE: m_api is just a member with the api key and the api base URL
void cURLWrapperRateBeer::QueryBeerList(const CBeerList& inBeerList)
{
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl)
{
// Construct the header struct
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type:application/json");
headers = curl_slist_append(headers, "Accept:application/json");
std::string keyPhrase = std::string("x-api-key:").append(m_api.second);
headers = curl_slist_append(headers, keyPhrase.c_str());
headers = curl_slist_append(headers, "Transfer-Encoding: chunked");
// Set the URL and the data we want
curl_easy_setopt(curl, CURLOPT_URL, m_api.first.c_str());
// Signify our intention to post data
curl_easy_setopt(curl, CURLOPT_POST, 1L);
// Verbose Output
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
// Give it a user agent
curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
std::string data = CreateRequestURL(inBeerList);
data.append("\0");
// Set up the data container for our push request
const char* c_data = data.c_str();
std::cout << c_data;
struct WriteStatus data_container;
data_container.p = c_data;
data_container.remaining = (long)strlen(c_data);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data_container.p);
/*
Define the buffer for writing memory and what the callback function will
use for its buffer
*/
//curl_easy_setopt(curl, CURLOPT_READFUNCTION, &cURLWrapperRateBeer::ReadData);
//curl_easy_setopt(curl, CURLOPT_READDATA, &data_container);
// Size of the data
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)data_container.remaining);
// Handler for reading response
std::string response;
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &cURLWrapperRateBeer::WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
// Set our custom set of headers
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
if(res != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(res));
//std::cout << "DUMP : " << data_container.p;
}
#ifdef SKIP_PEER_VERIFICATION
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
#ifdef SKIP_HOSTNAME_VERIFICATION
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
std::cout << "Response: " << response;
std:: cout << "Response End";
/* Check for errors */
if(res != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(res));
}
/* always cleanup */
curl_easy_cleanup(curl);
}
curl_global_cleanup();
}