The getOAuthHeader method doesn't take into account that there may be more than
one query string value or more than one post value and as such, if you put more
than one in, the signature will not get generated properly.
I found this by extending twitcurl to allow reply functionality where you must
pass in a second post variable to signify what id you are replying to. I also
had the problem with the query string trying to set the optional parameters to
return entities.
I got it to work and here are the code modifications I used. Basically all I
did was add a method to parse the key value pair to a map and then use that
data for the signature. It looks at both url and post data and combines them
into one map. I know this can be simplified and needs a bit of refactoring,
but it works. I also passed a blank string to buildOAuthTokenKeyValuePairs for
the rawData since I am parsing it and adding it to the rawKeyValuePairs. It
made more sense to me to do all the parsing at once instead of haivng the
buildOAuthTokenKeyValuePairs method parse the rawData.
bool oAuth::getOAuthHeader( const eOAuthHttpRequestType eType,
const std::string& rawUrl,
const std::string& rawData,
std::string& oAuthHttpHeader,
const bool includeOAuthVerifierPin )
{
oAuthKeyValuePairs rawKeyValuePairs;
std::string rawParams( "" );
std::string oauthSignature( "" );
std::string paramsSeperator( "" );
std::string pureUrl( rawUrl );
/* Clear header string initially */
oAuthHttpHeader.assign( "" );
rawKeyValuePairs.clear();
/* If URL itself contains ?key=value, then extract and put them in map */
size_t nPos = rawUrl.find_first_of( "?" );
if( std::string::npos != nPos )
{
/* Get only URL */
pureUrl = rawUrl.substr( 0, nPos );
/* Get only key=value data part */
std::string dataPart = rawUrl.substr( nPos + 1 );
std::map<std::string,std::string> querystring;
char* data = const_cast<char *>(dataPart.c_str());
querystring = ParseKeyValuePair(data);
std::map<std::string, std::string>::iterator qspos;
for(qspos = querystring.begin(); qspos != querystring.end(); ++qspos)
{
rawKeyValuePairs[qspos->first] = urlencode(qspos->second);
}
}
if(rawData != "")
{
std::map<std::string,std::string> querystring;
char* data = const_cast<char *>(rawData.c_str());
querystring = ParseKeyValuePair(data);
std::map<std::string, std::string>::iterator qspos;
for(qspos = querystring.begin(); qspos != querystring.end(); ++qspos)
{
rawKeyValuePairs[qspos->first] = urlencode(qspos->second);
}
}
/* Build key-value pairs needed for OAuth request token, without signature */
buildOAuthTokenKeyValuePairs( includeOAuthVerifierPin, "", std::string( "" ), rawKeyValuePairs );
/* Get url encoded base64 signature using request type, url and parameters */
getSignature( eType, pureUrl, rawKeyValuePairs, oauthSignature );
/* Now, again build key-value pairs with signature this time */
buildOAuthTokenKeyValuePairs( includeOAuthVerifierPin, std::string( "" ), oauthSignature, rawKeyValuePairs );
/* Get OAuth header in string format */
paramsSeperator = ",";
getStringFromOAuthKeyValuePairs( rawKeyValuePairs, rawParams, paramsSeperator );
/* Build authorization header */
oAuthHttpHeader.assign( oAuthLibDefaults::OAUTHLIB_AUTHHEADER_STRING.c_str() );
oAuthHttpHeader.append( rawParams.c_str() );
return ( oAuthHttpHeader.length() > 0 ) ? true : false;
}
std::map<std::string,std::string> oAuth::ParseKeyValuePair(char * data)
{
std::map<std::string,std::string> valuemap;
std::string tmpkey, tmpvalue;
std::string *tmpstr = &tmpkey;
register char* raw_get = data;
if (raw_get==NULL) {
valuemap.clear();
return valuemap;
}
while (*raw_get != '\0') {
if (*raw_get=='&') {
if (tmpkey!="") {
valuemap[UrlDecode(tmpkey)] = UrlDecode(tmpvalue);
}
tmpkey.clear();
tmpvalue.clear();
tmpstr = &tmpkey;
} else if (*raw_get=='=') {
tmpstr = &tmpvalue;
} else {
(*tmpstr) += (*raw_get);
}
raw_get++;
}
//enter the last pair to the map
if (tmpkey!="") {
valuemap[UrlDecode(tmpkey)] = UrlDecode(tmpvalue);
tmpkey.clear();
tmpvalue.clear();
}
return valuemap;
}
Original issue reported on code.google.com by dtmorgri...@gmail.com on 20 Dec 2010 at 2:57
Original issue reported on code.google.com by
dtmorgri...@gmail.com
on 20 Dec 2010 at 2:57