ПУБЛИКАЦИЯ твита с использованием libcurl и liboauth в C

#c #twitter #http-headers #twitter-oauth #libcurl

#c #Twitter #http-заголовки #twitter-oauth #libcurl

Вопрос:

Я пытаюсь опубликовать твит в Twitter со следующим кодом, но продолжаю получать сообщение об ошибке «Не удалось аутентифицировать вас», «code»: 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);
  

Теперь я просмотрел документацию Twitter и обсуждение на их веб-сайте, и они рекомендуют три вещи:

  1. Восстановите свои токены доступа. Я сделал это и попытался опубликовать в Twitter через них, используя консоль разработчиков в моей настольной программе Twitter, и это работает. Это заставляет меня думать, что проблема кроется в другом.
  2. Включить Content-Type: application/x-www-form-urlencoded в заголовок запроса. Насколько я понимаю, это значение по умолчанию для того, как я использую cURL, и действительно, когда я использую VERBOSE опцию, я вижу, что она находится в заголовке.
  3. Правильно закодируйте URL-адрес. Я знаю, что это oauth_sign_url2 делает это правильно при извлечении данных из Twitter, и я пробовал использовать oauth_url_escape("status=test") для статуса (хотя я не думаю, что я должен это делать). Это тоже не работает.

У меня такое чувство, что это что-то совершенно очевидное, но я в тупике.

Комментарии:

1. Работает ли ваш запрос, если вы выполняете его с помощью curl инструмента командной строки?

2. @ ams Это был очень хороший вопрос. Я использовал инструмент, предоставляемый Twitter, для генерации команды для меня, просто чтобы быть уверенным, что это сработает, и, между прочим, я получаю то же сообщение об ошибке. Конечно, это означает, что проблема в их конце?

3. Я попробовал еще раз, и, к сожалению, я хочу сказать, что это прошло. Я понятия не имею, что тогда было по-другому.

4. Кто знает, может быть, происходит какая-то блокировка от злоупотреблений? В любом случае, если проблема устранена, все хорошо. 🙂

5. Что ж, код по-прежнему не работает. Это работает только тогда, когда я использую инструмент командной строки.

Ответ №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, amp;argv);
  free(ser_url);

  temp_url = oauth_sign_array2(amp;argc, amp;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);
}