I am trying to send images to TwitPic using OAuthConsumer. I keep getting 401 "Failed to authenticate you (header rejected by twitter)." error.
I also use the Twitter + OAuth library to process the login and publish regular tweets, and then save the secret token and token for use with TwitPic.
This is the code in which I use the query construct:
NSURL *twitpicUrl = [NSURL URLWithString:@"http://api.twitpic.com/2/upload.json"]; NSString* realm = @"http://api.twitter.com/"; OAToken* oaToken = [[OAToken alloc] initWithKey:savedToken secret:savedTokenSecret]; OAConsumer* oaConsumer = [[OAConsumer alloc] initWithKey:kOAuthConsumerKey secret:kOAuthConsumerSecret]; OAMutableURLRequest *request = [[[OAMutableURLRequest alloc] initWithURL:twitpicUrl consumer:oaConsumer token:oaToken realm:realm signatureProvider:nil] autorelease]; [request prepare]; [request setHTTPMethod:@"POST"]; [request setValue:@"https://api.twitter.com/1/account/verify_credentials.json" forHTTPHeaderField:@"X-Auth-Service-Provider"]; NSString* authorizeHeader = [request valueForHTTPHeaderField:@"Authorization"]; [request setValue:authorizeHeader forHTTPHeaderField:@"X-Verify-Credentials-Authorization"];
And if I print my headers, this is what I get (excluding the unused authorization header):
"X-Auth-Service-Provider" = "https://api.twitter.com/1/account/verify_credentials.json"; "X-Verify-Credentials-Authorization" = "OAuth realm=\"http%3A%2F%2Fapi.twitter.com%2F\", oauth_consumer_key=\"JOvwW7mtZUjRXZRInkQI7w\", oauth_token=\"293217559-pD0HL0oE6TZSkU35mPnc7kia325oPDgMfQMTVArK\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"ctmCK35JFwx8qs8lQj0AYB6sUr4%3D\", oauth_timestamp=\"1304580843\", oauth_nonce=\"7EBE3EB0-641A-40EA-A57C-8D071B5E647F\", oauth_version=\"1.0\"";
Received error:
Error: The operation couldn't be completed. (NSURLErrorDomain error -1012.) {"errors":[{"code":401,"message":"Could not authenticate you (header rejected by twitter)."}]}
I have excluded some details here, especially adding these messages, mainly because I do not think this refers to the error. If you think otherwise please let me know and I will update the question.
Can anyone help?
Update: Here is the code that I am now successfully using
In the title:
#define kVerifyCredentialsUrl @"https://api.twitter.com/1/account/verify_credentials.json" #define kTwitPicUrl @"http://api.twitpic.com/2/upload.json"
Implementation:
//prepare the verify credentials header NSURL* serviceUrl = [NSURL URLWithString:kVerifyCredentialsUrl]; NSString* realm = @"http://api.twitter.com/"; OAToken* token = [[OAToken alloc] initWithKey:tokenKey secret:tokenSecret]; OAConsumer* consumer = [[OAConsumer alloc] initWithKey:kOAuthConsumerKey secret:kOAuthConsumerSecret]; OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:serviceUrl consumer:consumer token:token realm:realm signatureProvider:nil]; [request setHTTPMethod:@"GET"]; [request prepare]; NSDictionary* headerDictionary = [request allHTTPHeaderFields]; NSString* oAuthHeader = [NSString stringWithString:[headerDictionary valueForKey:@"Authorization"]]; [request release]; request = nil; //prepare the full request serviceUrl = [NSURL URLWithString:kTwitPicUrl]; request = [[OAMutableURLRequest alloc] initWithURL:serviceUrl consumer:consumer token:token realm:realm signatureProvider:nil]; [request setHTTPMethod:@"POST"]; [request setValue:kVerifyCredentialsUrl forHTTPHeaderField:@"X-Auth-Service-Provider"]; [request setValue:oAuthHeader forHTTPHeaderField:@"X-Verify-Credentials-Authorization"]; //add the content and start the request UIImage* imageToUpload = [UIImage imageNamed:@"test.png"]; NSData *data = UIImagePNGRepresentation(imageToUpload); ASIFormDataRequest *asiRequest = [[[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:kTwitPicUrl]] autorelease]; [asiRequest addRequestHeader:@"X-Auth-Service-Provider" value:kVerifyCredentialsUrl]; [asiRequest addRequestHeader:@"X-Verify-Credentials-Authorization" value:oAuthHeader]; [asiRequest setPostValue:@"Message here" forKey:@"message"]; [asiRequest setPostValue:kTwitPicAPIKey forKey:@"key"]; [asiRequest setData:data forKey:@"media"]; [asiRequest setDidFinishSelector:@selector(requestDone:)]; [asiRequest setDidFailSelector:@selector(requestWentWrong:)]; [asiRequest setDelegate:self]; [asiRequest startAsynchronous];