RocketChat / Rocket.Chat.Apps-engine

The Rocket.Chat Apps engine and definitions.

Home Page:https://rocketchat.github.io/Rocket.Chat.Apps-engine/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

http.post on content-type not application/json leads to empty data field

col-panic opened this issue · comments

I am trying to submit a binary image of type image/jpeg from within executePostMessageSentusing the following code

let result = await http.post('https://postman-echo.com/post', {
                data: binary,
                headers: {
                    'Content-Type': 'image/jpeg'
                }
            })

doing this leaves the data part being empty. If I remove the content-type header, the binary data is correctly set, but the content-type is defaulted to application/json which is wrong.

Additionally adding the 'Content-Length' header does not change this, as it is automatically being set when the data is correctly entered!

Here the two example HttpResponses

(a) with Content-Type header set

[
  "result",
  {
    "statusCode": 200,
    "content": "{\"args\":{},\"data\":{},\"files\":{},\"form\":{},\"headers\":{\"x-forwarded-proto\":\"https\",\"x-forwarded-port\":\"443\",\"host\":\"postman-echo.com\",\"x-amzn-trace-id\":\"Root=1-5ef60128-0d9d2ebc35f4ed6092c8b060\",\"content-length\":\"20623\",\"content-type\":\"image/jpeg\"},\"json\":null,\"url\":\"https://postman-echo.com/post?\"}",
    "headers": {
      "date": "Fri, 26 Jun 2020 14:07:36 GMT",
      "content-type": "application/json; charset=utf-8",
      "content-length": "298",
      "connection": "close",
      "etag": "W/\"12a-URL2AVXdpaNHCw+mRtxbmOx75zQ\"",
      "vary": "Accept-Encoding",
      "set-cookie": [
        "sails.sid=s%3AcMvp6EZQdpYvOC2HumOdcRsrbsaZZNbE.J7heP%2FiRRuOoM4HpB8VUOdrjA85xJPmbsJP4r5D%2FBKU; Path=/; HttpOnly"
      ]
    },
    "data": {
      "args": {},
      "data": {},
      "files": {},
      "form": {},
      "headers": {
        "x-forwarded-proto": "https",
        "x-forwarded-port": "443",
        "host": "postman-echo.com",
        "x-amzn-trace-id": "Root=1-5ef60128-0d9d2ebc35f4ed6092c8b060",
        "content-length": "20623",
        "content-type": "image/jpeg"
      },
      "json": null,
      "url": "https://postman-echo.com/post?"
    }
  }
]

(b) without Content-Type header set

[
  "result",
  {
    "statusCode": 200,
     "content": "{\"args\":{},\"data\":\"\\\"ÿØÿà\\\\u0000\\\\u0010JFIF\\\\u0000\\\\u0001\\\\u0001\\\\u0001\\\\u0000\\\\u0001\\\\u0000\\\\u0001\\\\u0000\\\\u0000ÿÛ\\\\u0000C\\\\u0000\\\\b\\\\u0006 ...
    "headers": {
      "date": "Fri, 26 Jun 2020 14:07:36 GMT",
      "content-type": "application/json; charset=utf-8",
      "content-length": "25544",
      "connection": "close",
      "etag": "W/\"12a-URL2AVXdpaNHCw+mRtxbmOx75zQ\"",
      "vary": "Accept-Encoding",
      "set-cookie": [
        "sails.sid=s%3AcMvp6EZQdpYvOC2HumOdcRsrbsaZZNbE.J7heP%2FiRRuOoM4HpB8VUOdrjA85xJPmbsJP4r5D%2FBKU; Path=/; HttpOnly"
      ]
    },
    "data": {
      "args": {},
      "data": "\"ÿØÿà\\u0000\\u0010JFIF\\u0000\\u0001\\u0001\\u0001\\u00 ....
      "files": {},
      "form": {},
      "headers": {
        "x-forwarded-proto": "https",
        "x-forwarded-port": "443",
        "host": "postman-echo.com",
        "x-amzn-trace-id": "Root=1-5ef60128-0d9d2ebc35f4ed6092c8b060",
        "content-length": "20623",
        "content-type": "application/json"
      },
      "json": null,
      "url": "https://postman-echo.com/post?"
    }
  }
]

So it seems that by means of the default Meteor Http Client it is not possible to send binary data. E.g. https://stackoverflow.com/questions/30161716/how-to-make-post-request-with-a-binary-body-in-meteor-js

What would be the right way to include a third-party library like https://www.npmjs.com/package/superagent such that is bundled with the app and I can call post with binary data from the server side?

Is it possible to bundle a library like https://github.com/request/request with an App? Can I do something like `npm i -s request/request' and deploy it with the app for usage?

Unfortunately, it is not possible to add external dependencies to Rocket.Chat Apps right now. It is a problem we're aware and we're working on solving it, but it requires multiple steps to do it responsibly (with sandboxing, bundling, etc.).

The alternative to sending this payload would be to encode it with base64 and assign it to the content property of the IHttpRequest instead of data - it is far from the ideal solution, but it is a way to transfer the content given the current context.

Fortunately the REST api provided a means to transport type application/json so I could go for a resp. call. But it seems that both, not being able to transmit binary packages (due to the meteor client library not supporting this) and the disability to add own extensions currently make it impossible to write rocketchat apps that have to transmit binary data.

References https://docs.meteor.com/api/http.html (no support for binary data) and #56