有curl --data-urlencode的libcurl curl_easy_setopt()版本吗

pqwbnv8z  于 2023-08-03  发布在  其他
关注(0)|答案(1)|浏览(111)

我正在尝试连接到最新的皇家邮政API V4以获得基于C和libcurl中现有工作代码的令牌,以连接到V3。我有一个curl示例脚本,它使用--data-urlencode获取一个令牌,返回一个令牌。

  1. curl -k --location 'https://authentication.proshipping.net/connect/token' \
  2. --header 'Content-Type: application/x-www-form-urlencoded' \
  3. --data-urlencode 'client_id=AAAAAAA' \
  4. --data-urlencode 'client_secret=BBBBBBBBB' \
  5. --data-urlencode 'grant_type=client_credentials'

字符串
我在C和libcurl中尝试了以下操作

  1. curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, FALSE);
  2. curl_easy_setopt(hnd, CURLOPT_URL, "https://authentication.proshipping.net/connect/token");
  3. curl_easy_setopt(hnd, CURLOPT_POST, TRUE);
  4. headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
  5. curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);
  6. postfields = curl_slist_append(postfields, "client_id=AAAAAAA");
  7. postfields = curl_slist_append(postfields, "client_secret=BBBBBBBBB");
  8. postfields = curl_slist_append(postfields, "grant_type=client_credentials");
  9. curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, postfields);
  10. curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, writefunc);
  11. curl_easy_setopt(hnd, CURLOPT_WRITEDATA, &s);
  12. res = curl_easy_perform(hnd);


但是libcurl示例返回输出

  1. {"error":"invalid_client"}


有人能在libcurl中使用--data-urlencode或等效命令吗?谢啦,谢啦

krcsximq

krcsximq1#

似乎没有一个easy option可以模仿--data-urlencode的全部功能,其中包括使用特殊语法加载和编码文件的功能,还可以将其参数连接起来形成一个blob。
用于对以空值结尾的字节字符串进行URL编码的库函数是curl_easy_escape。当使用者使用完之后,产生的字串必须传递至curl_free

  1. char *curl_easy_escape(CURL *curl, const char *string, int length);
  2. void curl_free(void *ptr);

字符串

  • (内部data_urlencode(实现--data-urlencode)使用curl_easy_escape。)*

至于CURLOPT_POSTFIELDS

  1. CURLcode curl_easy_setopt(CURL *handle, CURLOPT_POSTFIELDS, char *postdata);


第三个参数应该是以空值结尾的字节字符串(默认情况下;可以使用CURLOPT_POSTFIELDSIZE手动调整大小)。
根据您的示例,--libcurl生成:

  1. curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, "client_id=AAAAAAA&client_secret=BBBBBBBBB&grant_type=client_credentials");


另请参阅:http-post.c
--data-urlencode最基本功能(name=content语法)的一个模糊的模仿大概是:

  1. #include <curl/curl.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. static int data_append(char **to, const char *name, const char *field)
  6. {
  7. /* 1 if initial segment, 0 if concat, justifies & below */
  8. unsigned init = (NULL == *to);
  9. /* first argument ignored in 7.82.0+, otherwise modify `data_append` */
  10. char *escaped_field = curl_easy_escape(NULL, field, 0);
  11. if (!escaped_field)
  12. return 0;
  13. /* previous */
  14. size_t offset = !init ? strlen(*to) : 0;
  15. /* name=escaped */
  16. size_t length = strlen(name) + 1 + strlen(escaped_field);
  17. /* previous&name=escaped\0 */
  18. char *result = realloc(*to, offset + !init + length + 1);
  19. if (result) {
  20. sprintf(result + offset, "&%s=%s" + init, name, escaped_field);
  21. *to = result;
  22. }
  23. curl_free(escaped_field);
  24. return NULL != result;
  25. }
  26. int main(void)
  27. {
  28. CURL *curl = curl_easy_init();
  29. char *data = NULL;
  30. data_append(&data, "name", "field");
  31. data_append(&data, "foo", "hello world!");
  32. fprintf(stderr, "DEBUG: Sending: <%s>\n", data);
  33. curl_easy_setopt(curl, CURLOPT_URL, "https://mockbin.org/request");
  34. curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
  35. curl_easy_perform(curl);
  36. curl_easy_cleanup(curl);
  37. free(data);
  38. }


结果如下:

  1. ./a.out
  2. DEBUG: Sending: <name=field&foo=hello%20world%21>
  3. ...
  4. ...
  5. "postData": {
  6. "mimeType": "application/x-www-form-urlencoded",
  7. "text": "name=field&foo=hello%20world%21",
  8. "params": {
  9. "name": "field",
  10. "foo": "hello world!"
  11. }
  12. }
  13. ...
  14. ...


这是 * 大致 *

  1. $ curl -L 'https://mockbin.org/request' --data-urlencode 'name=field' --data-urlencode 'foo=hello world!'

  • --data-urlencode实现了RFC1866中所述的' ' => '+'转换。)*

另外:还有CURLOPT_MIMEPOST,可用于 * 多部分/表单数据 *。

展开查看全部

相关问题