ciaranj / node-oauth

OAuth wrapper for node.js
MIT License
2.44k stars 660 forks source link

Content-Type Override #331

Open fayebutler opened 7 years ago

fayebutler commented 7 years ago

From this bit of code in _putorPost() function in oauth.js (line 496)

if ( typeof post_body != "string" && !Buffer.isBuffer(post_body) ) { post_content_type= "application/x-www-form-urlencoded" extra_params= post_body; post_body= null; }

With the new Twitter DM API I need to be able to set the Content Type to JSON when the post-body is JSON https://dev.twitter.com/rest/reference/post/direct_messages/events/new

So currently my post function looks like this : oauth.post( 'https://api.twitter.com//1.1/direct_messages/events/new.json', access_token, access_token_secret, {"event": {"type": "message_create", "message_create": {"target": {"recipient_id": "4534871"}, "message_data": {"text": "Hello World!"}}}}, "application/json", function(e, data ) { } );

But as post-content-type gets overridden to "application/x-www-form-urlencoded", I get an error. Could this please be updated so you can specify the content type?

mitchellporter commented 7 years ago

+1

rausanka commented 6 years ago

Same is true about get(). Seems like these snippets are the problem (notice null always being passed which means default of "application/x-www-form-urlencoded" will always be set

exports.OAuth.prototype.delete= function(url, oauth_token, oauth_token_secret, callback) {
  return this._performSecureRequest( oauth_token, oauth_token_secret, "DELETE", url, null, "", null, callback );
}

exports.OAuth.prototype.get= function(url, oauth_token, oauth_token_secret, callback) {
  return this._performSecureRequest( oauth_token, oauth_token_secret, "GET", url, null, "", null, callback );
}
…
exports.OAuth.prototype.put= function(url, oauth_token, oauth_token_secret, post_body, post_content_type, callback) {
  return this._putOrPost("PUT", url, oauth_token, oauth_token_secret, post_body, post_content_type, callback);
}

exports.OAuth.prototype.post= function(url, oauth_token, oauth_token_secret, post_body, post_content_type, callback) {
  return this._putOrPost("POST", url, oauth_token, oauth_token_secret, post_body, post_content_type, callback);
}

One option is to be able to set the content-type to use for all requests when constructing an OAuth object. I don't love adding yet another parameter to the constructor so what about adding a setContentType() method on the OAuth object (with the default being "application/x-www-form-urlencoded" if you don't call this new method) and have the code in _performSecureRequest use the object's value rather than hard-coding "application/x-www-form-urlencoded" if content-type isn't explicitly passed into the method?

I'm happy to put together a PR if people think this is the way to go.

rausanka commented 6 years ago

A minimal change (which I think is less obvious/explicit and thus don't like as well) is to change _performSecureRequest to move the headers["Content-Type"]= post_content_type; line above

 for( var key in this._headers ) {
    if (this._headers.hasOwnProperty(key)) {
      headers[key]= this._headers[key];
    }
  }

That way if you include 'Content-Type' in the customHeaders object passed to the OAuth constructor. I don't love this though due to the obvious/explicit problem I mentioned above and because it forces you to pass all of the parameters before customHeaders when you want to change the content-type.

ghost commented 6 years ago

@fayebutler I merged a patch into oauth-libre (written by @rausanka ) that should solve this issue: https://github.com/omouse/node-oauth-libre/pull/30 it's in release 0.9.17 of oauth-libre

terrynguyen255 commented 3 years ago

+1