I'm trying to post a tweet to Twitter with the following code, but keep getting the error "Could not authenticate you","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);
Now, I looked at Twitter's documentation and the discussion on their website, and they recommend three things:
Content-Type: application/x-www-form-urlencoded
in the header of the request. My understanding is that this is default for how I'm using cURL, and indeed, when I use the VERBOSE
option, I can see that it is in the header.oauth_sign_url2
does this correctly when fetching things from Twitter, and I've tried using oauth_url_escape("status=test")
on the status (even though I don't think I'm supposed to do that). That doesn't work either.I have a feeling it's something completely obvious, but I am stumped.
What was missing from my original code was to properly build the header. The following code works.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With