Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse.Cloud.httpRequest: provide default string encoding for body option #727

Closed
yuzeh opened this issue Feb 29, 2016 · 7 comments · Fixed by #892
Closed

Parse.Cloud.httpRequest: provide default string encoding for body option #727

yuzeh opened this issue Feb 29, 2016 · 7 comments · Fixed by #892

Comments

@yuzeh
Copy link
Contributor

yuzeh commented Feb 29, 2016

Somewhat related to #703.

The 'request' library in node requires the body option to be a string, whereas Parse.Cloud.httpRequest will pass in an object if it is given an object, with no Content-Type header.

This is running on parse-server v2.1.3.

example node repl session illustrating the issue:

> require('parse-server');
{ ParseServer: [Function: ParseServer],
  S3Adapter: [Function: S3Adapter] }
> Parse.Cloud.httpRequest({method: 'POST', url: 'http://httpbin.org/post', body: {p1: 'v1', p2: 2}})
TypeError: Cannot read property 'statusCode' of undefined
    at Request._callback (dist/node_modules/parse-server/lib/httpRequest.js:46:35)
    at self.callback (dist/node_modules/parse-server/node_modules/request/request.js:199:22)
    at emitOne (events.js:77:13)
    at Request.emit (events.js:169:7)
    at setContentLength (dist/node_modules/parse-server/node_modules/request/request.js:451:14)
    at Request.init (dist/node_modules/parse-server/node_modules/request/request.js:456:5)
    at new Request (dist/node_modules/parse-server/node_modules/request/request.js:141:8)
    at request (dist/node_modules/parse-server/node_modules/request/index.js:55:10)
    at Object.module.exports [as httpRequest] (dist/node_modules/parse-server/lib/httpRequest.js:44:3)
    at repl:1:13
> Parse.Cloud.httpRequest({method: 'POST', url: 'http://httpbin.org/post', body: {p1: 'v1', p2: 2}, headers: {'content-type': 'application/x-www-form-urlencoded'}})
ParsePromise {
  _resolved: false,
  _rejected: false,
  _resolvedCallbacks: [],
  _rejectedCallbacks: [] }
> 
@flovilmart
Copy link
Contributor

Originally the Parse.Cloud.httpRequest requires you to set the contentType manually so the body is properly encoded, either in JSON or in application/x-www-form-urlencoded

We could add the json option instead that would automatically set the contentType for your request.

Would that help?

@yuzeh
Copy link
Contributor Author

yuzeh commented Mar 1, 2016

Oh, I didn't realize that was the default behavior. I encountered this issue while trying to use the code here: https://github.com/ParsePlatform/JavaScriptModulesTutorial/blob/master/myMailModule-1.0.0.js

I assumed that this was how Mailgun on Parse is implemented, but I guess that is not the case.

I think parse-server should match hosted Parse as closely as possible, so I'm going to close this issue.

@yuzeh yuzeh closed this as completed Mar 1, 2016
@flovilmart
Copy link
Contributor

then it's maybe not the default behaviour! how is it working on parse.com?

@flovilmart flovilmart reopened this Mar 1, 2016
@wavo89
Copy link

wavo89 commented Mar 3, 2016

I'm having a similar problem with this (used to work on Parse.com):

OpenTokSDK.prototype.apiRequest = function(endpoint, authScheme, options, cb) {

  // options is optional
  if (cb === undefined) { cb = options; options = {}; }

  var requestOptions = {
    url: urlFromEndpoint(endpoint, options.endpoint),
    method: methodFromEndpoint(endpoint),
    headers: {},
    body: options.data || {},
    success: function(response) {
      cb(null, response);
    },
    error: function(response) {
      cb(new Error("Request failed with response code " + response.status + "\n" +
                   "Raw response: \n" + response.text + "\n"));
    }
  };

  if (authScheme === AUTH.PARTNER) {
    requestOptions.headers[authScheme] = this.apiKey + ':' + this.apiSecret;
  } else if (authScheme === AUTH.TOKEN) {
    requestOptions.headers[authScheme] = this.generateToken.apply( this, options.auth );
  } else {
    console.warn("OpenTok: No known authentication scheme chosen for the following request: \n" +
      JSON.stringify(requestOptions) + "\n");
  }

  Parse.Cloud.httpRequest(requestOptions);
  console.log("OpenTok: Sent the following request: \n" + JSON.stringify(requestOptions) + "\n");
  return;
};

Parse.Cloud.httpRequest(requestOptions) is line 196.

The command line:

Uncaught internal server error. [TypeError: Cannot read property 'statusCode' of undefined] TypeError: Cannot read property 'statusCode' of undefined
2016-03-03T01:47:51.698829+00:00 app[web.1]:     at Request._callback (/app/node_modules/parse-server/lib/httpRequest.js:46:35)
2016-03-03T01:47:51.698830+00:00 app[web.1]:     at self.callback (/app/node_modules/request/request.js:199:22)
2016-03-03T01:47:51.698831+00:00 app[web.1]:     at emitOne (events.js:90:13)
2016-03-03T01:47:51.698832+00:00 app[web.1]:     at Request.emit (events.js:182:7)
2016-03-03T01:47:51.698832+00:00 app[web.1]:     at setContentLength (/app/node_modules/request/request.js:451:14)
2016-03-03T01:47:51.698833+00:00 app[web.1]:     at Request.init (/app/node_modules/request/request.js:456:5)
2016-03-03T01:47:51.698834+00:00 app[web.1]:     at new Request (/app/node_modules/request/request.js:141:8)
2016-03-03T01:47:51.698835+00:00 app[web.1]:     at request (/app/node_modules/request/index.js:55:10)
2016-03-03T01:47:51.698836+00:00 app[web.1]:     at Object.module.exports [as httpRequest] (/app/node_modules/parse-server/lib/httpRequest.js:44:3)
2016-03-03T01:47:51.698836+00:00 app[web.1]:     at OpenTokSDK.apiRequest (/app/cloud/opentok/opentok.js:196:15)

@videre
Copy link

videre commented Mar 4, 2016

@yuzeh how did you solve it? I still cannot get the https://github.com/ParsePlatform/JavaScriptModulesTutorial/blob/master/myMailModule-1.0.0.js
to work despite trying various options like setting the header and even turning the object into a string
if (typeof params === 'object') {
params = JSON.stringify(params);
console.log("after stringify of params: " + params);
}

return Parse.Cloud.httpRequest({
method: "POST",
url: "https://api:" + key + "@" + url + "/" + domain + "/messages",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: params

  }).then(function(httpResponse) {
          //success

Checking the console.log shows that it does run, but the http status code returned by mailgun is always status 400. Which means the httpRequest is working but sending malformed requests to it. This same code used to work (without the added code of changing the param object into a string) on Parse. Any hints would be great.

@videre
Copy link

videre commented Mar 4, 2016

As a follow up, changing the Content-Type to multipart/form-data gives a different response from mailgun. Instead of 400, it now returns http status code of 502

@wavo89
Copy link

wavo89 commented Mar 4, 2016

I was using an API called OpenTok, and I basically got rid of it and made sure I was using the newest version of the SDK for it, and the newest build for Parse-Server.

The code I had been using, was from a sample project that implemented the OpenTok API via parse server. By using npm install of the OpenTok framework from scratch, it seemed to be able to run it from scratch.

Good luck.

On Mar 4, 2016, at 4:12 AM, videre notifications@github.com wrote:

@yuzeh https://github.com/yuzeh how did you solve it? I still cannot get the https://github.com/ParsePlatform/JavaScriptModulesTutorial/blob/master/myMailModule-1.0.0.js https://github.com/ParsePlatform/JavaScriptModulesTutorial/blob/master/myMailModule-1.0.0.js
to work despite trying various options like setting the header and even turning the object into a string
if (typeof params === 'object') {
params = JSON.stringify(params);
console.log("after stringify of params: " + params);
}

return Parse.Cloud.httpRequest({
method: "POST",
url: "https://api:" + key + "@" + url + "/" + domain + "/messages",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: params

}).then(function(httpResponse) {
//success

Reply to this email directly or view it on GitHub #727 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants