在C中使用libcurl和liboauth发布推文

ccc*_*ccc 5 c twitter libcurl http-headers twitter-oauth

我正在尝试使用以下代码向Twitter发布推文,但不断收到错误"无法验证您","代码":32":

 curl_global_init(CURL_GLOBAL_ALL);
 CURL *curl = curl_easy_init();

 char *signedurl = malloc(sizeof(char) * 1024); /* Not how it will be, but works in this example. */

 char *url = "https://api.twitter.com/1.1/statuses/update.json";
 signedurl = oauth_sign_url2(url, NULL, OA_HMAC, "POST", consumer_key, consumer_secret, user_token, user_secret);
 char *status = "status=test";

 curl_easy_setopt(curl, CURLOPT_URL, signedurl); /* URL we're connecting to, after being signed by oauthlib */
 curl_easy_setopt(curl, CURLOPT_USERAGENT, "dummy-string"); /* Not the actual string, just a dummy for this example */
 curl_easy_setopt(curl, CURLOPT_POST, 1);
 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, status);
 //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);

 int curlstatus = curl_easy_perform(curl); /* Execute the request! */

 curl_easy_cleanup(curl);
 free(signedurl);
Run Code Online (Sandbox Code Playgroud)

现在,我查看了Twitter的文档和他们网站上的讨论,他们推荐了三件事:

  1. 重新生成您的访问令牌.我已经做到了这一点,并尝试使用Twitter桌面程序中的开发者控制台通过它们发布到Twitter,这样做有效.这让我觉得问题出在其他地方.
  2. 包含Content-Type: application/x-www-form-urlencoded在请求的标头中.我的理解是这是我使用cURL的默认方式,事实上,当我使用该VERBOSE选项时,我可以看到它在标题中.
  3. 正确编码网址.我知道oauth_sign_url2从Twitter获取东西时这是正确的,我已尝试使用oauth_url_escape("status=test")状态(即使我不认为我应该这样做).这也行不通.

我感觉这是完全明显的,但我很难过.

ccc*_*ccc 1

我的原始代码中缺少的是正确构建标头。以下代码有效。

 char *ttwytter_request(char *http_method, char *url, char *url_enc_args)
 {
  struct curl_slist * slist = NULL;
  char * ser_url, **argv, *auth_params, auth_header[1024], *non_auth_params, *final_url, *temp_url;
  int argc;

  ser_url = (char *) malloc(strlen(url) + strlen(url_enc_args) + 2);
  sprintf(ser_url, "%s?%s", url, url_enc_args);

  argv = malloc(0);
  argc = oauth_split_url_parameters(ser_url, &argv);
  free(ser_url);

  temp_url = oauth_sign_array2(&argc, &argv, NULL, OA_HMAC, http_method, consumer_key, consumer_secret, user_token, user_secret);
  free(temp_url);

  auth_params = oauth_serialize_url_sep(argc, 1, argv, ", ", 6);
  sprintf( auth_header, "Authorization: OAuth %s", auth_params );
  slist = curl_slist_append(slist, auth_header);
  free(auth_params);

  non_auth_params = oauth_serialize_url_sep(argc, 1, argv, "", 1 );

  final_url = (char *) malloc( strlen(url) + strlen(non_auth_params) );

  strcpy(final_url, url);
  postdata = non_auth_params;

  for (int i = 0; i < argc; i++ )
  {
    free(argv[i]);   
  }
  free(argv);

  curl_easy_setopt(curl, CURLOPT_URL, url);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, "dummy-string");
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
  curl_easy_setopt(curl, CURLOPT_POST, 1);
  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata);

 int curlstatus = curl_easy_perform(curl); /* Execute the request! */

 curl_easy_cleanup(curl);
}
Run Code Online (Sandbox Code Playgroud)