Posting in the api with special characters like +


#1

Hi
I’m using the twitter API for posting tweets and encounter the following problem.
When posting any words, the API works, but when posting a character like + I’m getting back an error from the API
"[“Could not authenticate with OAuth.”]"
This is clearly not an authentication issue but a character isssue.
I’m encoding the character with UTF8, for other characters like ! it works ok, but not for +
This seems like a bug.
Has anyone encoutered this?
See my post example
https://api.twitter.com/1/statuses/update.json?status=%2B&lat=X&long=X
Thanks
Guy


#2

How are you encoding the +? A lot of URL encoding functions treat + like a space, which is incorrect for the purposes of OAuth.

Here’s the correct encoded form of “X+Y”:
status=X%2bY


#3

I’m encoding like you wrote with %2b, See my example at the bottom of my post.


#4

That’s correct in the POST body, but if you have a %2b in your POST body, then the signature base string needs to account for it as %252b.

Also, make sure you specific params for POST methods like statuses/update in the POST body instead of the query string.


#5

I’m not sure what you mean by signature base string.
When sending the post request, I used the java code below to sign the post request - this works for request I send without + :

PostMethod postMethod = new PostMethod(urlString); if ( parameters != null) { for (String key : parameters.keySet()) { postMethod.addParameter(key, parameters.get(key)); } } OAuthConsumer consumer = new HttpClient2OAuthConsumer(consumerKey, consumerSecretKey,SignatureMethod.HMAC_SHA1); consumer.setTokenWithSecret(token, tokenSecret); consumer.sign(postMethod);

Regarding your second suggestion, I tried setting the status and other parameters in the post body instead of the url and got the same result.


#6

You’re assuming that the library you’re using is doing the right thing… :slight_smile: The signature base string is an implementation detail of OAuth, but the implementation detail where things go wrong.

When you use a plus character, are you intending it to represent a " " character in a status or are you intending it to represent literally a “+”? If you’re wanting it to be literally a “+” character, than it MUST be used as %2B in the POST body. If you’re wanting it to be a " " character, you’re better off using %20 instead of “+” to represent a space.

You might need to crack open the underlying code in the library you’re using to investigate what it’s doing with the + character you’re using – you also might need to scrub the status text string before sending it into OAuth signing.


#7

I seem to remember Java being one of the languages where the standard URL encoding isn’t compatible with OAuth for + characters. Which OAuth library are you using?


#8

I’m using oauth signpost libary: http://code.google.com/p/oauth-signpost/
For other characters, it works ok e.g posting “hello!” the text is encoded to hello%21 and the post works.
For +, however it fails.
Do you have an idea how I will be able to post + character?


#9

That’s why I always use rawurlencode in PHP, so that " " becomes “%20” and not “+”, and it’s generally stricter about what to escape than urlencode.


#10

How are you setting “status” in parameters?


#11

I tried both to set it in the parameters and in the url itself. Got the same result.


#12

I meant, can you list the code you’re using to create and initialize the parameters object?


#13

If I understand you correctly it’s the code above, the parameters hashtable holds in the key “status” and in the value %2b.
It’s added as a parameters to the post method


#14

Can you show how you’re creating the parameters hashtable?


#15

String url = “https://api.twitter.com/1/statuses/update.json?status=hi%2B&lat=32.066157&long=34.777821”;
PostMethod postMethod = new PostMethod(urlString);
try {
if ( token != null && tokenSecret != null) {
OAuthConsumer consumer = new
HttpClient2OAuthConsumer(consumerKey,
consumerSecretKey,SignatureMethod.HMAC_SHA1);
consumer.setTokenWithSecret(token, tokenSecret);
consumer.sign(postMethod);
client.executeMethod(postMethod);
}

I got an exception

error:JSONString(1:10)[“Could not authenticate with OAuth.”], request:JSONString(1:57)["/1/statuses/update.json?status=hi%2b&lat=32.066157&long=34.777821"]

This is also the exception I got when trying to send the parameters status,lat,long in the post body instead of the url.
According to the API, I’m supposed to add the parameters in the url


#16

For a POST, put the parameters in the body. In this case, I’m not confident that the parameters you’re including in your URL are actually being parsed and signed correctly by the library.

What is the client object? How are you initializing it?

Would you list the code you’re using for the post body request?


#17

What is the right way to post special characters? I’m using Abraham’s twitteroauth library and that is what I have tried:

  • for $to->post(‘statuses/update’, array(‘status’ => “Comentário”)); and $to->post(‘statuses/update’, array(‘status’ => utf_encode(“Comentário”) )); I get the error “Could not authenticate you”
  • for $to->post(‘statuses/update’, array(‘status’ => utf_decode(“Comentário”) )); The message sent was “Coment?rio”
  • for $to->post(‘statuses/update’, array(‘status’ => urlencode(“Comentário”) )); the message sent was “coment%C3%A1rio”

I also tried to encode my php file from “ANSI” and “UTF-8 without BOM” and did the above tests again, but nothing works.

Any ideia?


#18

For me problem has been solved by removing the utf8_encode function and only a rawurlencode, provided all data are in proper utf-8 charset:

public function encode($string) {
//return rawurlencode(utf8_encode($string));
return rawurlencode($string);
}

in the EpiOAuth class.


#19

Hi All

Need help on this. Spent an entire day after adapting to 1.1 and making oauth changes. Now it’s erratic. My hypothesis is that this could be special character issue. A couple of tweets where it fails are “Google Play app: Pet Care - How To Videos” and “connect directly xyz, Pediatric Dentistry from Tempe, AZ, on”. Something that works is “sample string without any special character”

I can see commas, exclamations, hyphens etc. Any help is appreciated.

Thanks


#20

Use it like this, it’s working for me:
String rawString = “Árvíztűrő tükörfúrógép”;

String encodedText = new String(rawString.getBytes(), “UTF-8”);
entity.addPart(“status”, new StringBody(encodedText, Charset.forName(“UTF-8”)));