Skip to content

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

Description

@yuzeh

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: [] }
> 

Activity

  1. flovilmart commented on Mar 1, 2016

    @flovilmart
    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?

  2. yuzeh commented on Mar 1, 2016

    @yuzeh
    ContributorAuthor

    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.

  3. flovilmart commented on Mar 1, 2016

    @flovilmart
    Contributor

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

  4. wavo89 commented on Mar 3, 2016

    @wavo89

    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)
    
  5. videre commented on Mar 4, 2016

    @videre

    @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.

  6. videre commented on Mar 4, 2016

    @videre

    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

  7. wavo89 commented on Mar 4, 2016

    @wavo89

    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 [email protected] 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions