Apiary multipart/form-data - node.js

I have tried creating an Apiary request with multipart/form-data, which seems alright, except when I try actually sending it via the console on Apiary to an existing (and functional) endpoint written in Node.js using async-busboy I'm getting back
{
"message": "Unexpected end of multipart data"
}
The Apiary Blueprint for this request looks like this:
+ Request
+ Headers
Content-Type: multipart/form-data; boundary=BOUNDARY
+ Body
--BOUNDARY
Content-Disposition: form-data; name="name"
John Doe
--BOUNDARY
Content-Disposition: form-data; name="email"
john.doe#email.com
--BOUNDARY--
I'd like to know if there is any problem that can be fixed in the Blueprint snippet or if this is even supported, or if the problem might be in the server itself (but the server works when I send a multipart post request from postman, curl and there are also few client implementations using it)

Related

Not getting response from AWS after uploading image through ESP32

General context:
I am working on an IoT application where I upload images from an ESP32 connected to an SBC.
The uploading is done through an API provided by a third-party backend developer.
The upload API works through other mediums (such as Postman, python requests library, python http client library)
The ESP32 is connected to the SBC through UART.
I construct/generate the HTTP request on the SBC and send it as bytes. I have written a function on ESP32 that can send the bytes as a generic HTTP request, to the URL specified.
Then it sends the response string back to the SBC.
All of this works. For small requests, I am facing no issues. I am able to download images, etc.
However, when uploading an image, I don't get a response and I end up timing out after 30s. I checked without timeout FYI, but no response.
I checked from the server-side. It appears my request has succeeded and the server is sending me 200 with the URL of the image. Using that URL, I was able to verify that the image was uploaded successfully.
However, I do not receive this response on the microcontroller.
Not sure what the issue is. Any suggestions as to what I can do?
I can't give out the code but I'll send a general structure:
ESP32
-> Receives URL, port, length of request
-> Connects to server and reads the request from UART and writes to server
-> Wait for response after response is sent
Python raw http
POST (server path) HTTP/1.1
Host: (url)
correlation-id: test5
Content-Type: multipart/form-data; boundary=WebKitFormBoundary7MA4YWxkTrZu0gW
Authorization: Bearer (access token)
Content-Length: 268
--WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="portraits"; filename="name"
Content-Type: image/jpeg
(data)
--WebKitFormBoundary7MA4YWxkTrZu0gW--
Edit 1:
So, turns out it is not only "upload image", some other requests are also behaving similarly. Our server has many microservices. The services written in nodeJS which have more than 1 redirects are not working...?
I figured out what the issue is and hopefully, it will help anyone else facing the same issue. Also, some of my requests to the backend server which used a different authentication method worked
I had been generating the raw HTTP using postman code generation but it turns out Postman doesn't add a few headers which are needed for communicating with more complex servers.
What I mean is that if I host a local server, the above code will work. I had already tested it that way
What solved my problem is adding these headers:
POST (server path) HTTP/1.1
Host: (server URL)
User-Agent: ESP32
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
correlation-id: test
Authorization: Bearer (access_token)
Content-Length: 146360
Content-Type: multipart/form-data; boundary=af59ef02d60cd0efefb7bc03db1f4ffc
--af59ef02d60cd0efefb7bc03db1f4ffc
Content-Disposition: form-data; name="portraits"; filename="(name)"
Content-Type: image/jpeg
(data)
--af59ef02d60cd0efefb7bc03db1f4ffc--

Parse incoming x-www-form-urlencoded in nodejs

I am using hapi for a simple API. I need to submit some data to a 3rd party api, with the data in a POST body, Content-Type: application/x-www-form-urlencoded in the header and the body containing the form data. I'm doing this successfully using form-data and node-fetch.
I'm writing a test for this using jest-fetch-mock to mock the fetch service. However, the mocked fetch request is a FormData() object, and to get the values of the body I have to use the form-data methods, specifically getBuffer(). The best I can do is get the text of the form data stream, which looks like this:
----------------------------873172308964049871716608
Content-Disposition: form-data; name="grant_type"
mockAuthorization_code
----------------------------873172308964049871716608
Content-Disposition: form-data; name="code"
mockAuthCode
----------------------------873172308964049871716608
Content-Disposition: form-data; name="redirect_uri"
redirectUrl.com/
----------------------------873172308964049871716608--
Is there any way I can parse these to test that the correct values are being submitted?
Thanks

Retrieve Image from Node JS Get server response

I am using a third party API which I send a GET request in Node JS and it responds with XML and an image encoded in base64.
I have tried looking for a third party module to split this out, but these all seem to work on a POST response.
Can Multer use the response from a GET to save the image?
Response is as follows:
--boundary
Content-Disposition: form-data; name="file.xml"; filename="file.xml"
Content-Type: text/xml
Content-Length: 1665
<XML>
.....
</XML>
--boundary
Content-Disposition: form-data; name="licensePlatePicture.jpg";
filename="licensePlatePicture.jpg"
Content-Type: image/jpeg
Content-Length: 7231
<BASE64 ENCODED IMAGE HERE>
I'm looking for an example of how to save the image without having to parse it manually.
Thanks.

nodejs- unable to fetch form data

I'm using Express JS (v 4.15.3) for building a node api.
I'm trying to fetch the values send from a form (via POSTman client). I'm not able to fetch it.
This is my form
with headers specified
Without headers
This is how I'm trying to fetch it:
router.post('/login',function(req, res, next) {
var email= req.body.email;
//var email= req.query.email; //also tried this
res.json({
value: email
});
});
I'm not getting error.
Note: I have included body parser.
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
Can anyone tell me why I am not getting the value? Thanks!
This is my first attempt at learning Node JS.
Your code seems perfectly alright. Though the issue is with the way you are sending request from POSTman client.
When you are sending request using use form data, POSTman sends this request as multipart/form-data, which actually sends your data in the format as below:
POST /api/login HTTP/1.1
Host: localhost:3000
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="email"
example#example.com
----WebKitFormBoundaryE19zNvXGzXaLvS5C
For multipart/form-data requests you need to use multer middleware, if you really need file-uploads with your application. But for your case you can just send data without using use form data (un-check the use form data checkbox), and setting content-type header as:
Content-Type: application/x-www-form-urlencoded
So after all these modifications your raw web request should look something like below:
POST /api/login HTTP/1.1
Host: localhost:3000
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
email=example#example.com
The POSTman screen capture for building the request and response is as below:
The POSTman screen capture for Raw request and response is as below:
Hope this will help you.
Try to set Content-Type to application/json and in body in raw write in json format like this :
{
"email":"example#gmail.com"
}
Here are the images which you can refer.
Don't forget to upvote the answer if you find it helpful.

The bodyParser not work when post "form-data" with POSTMAN

the HTTP preview:
POST /kflq_webcfg/v1/update HTTP/1.1
Host: h.innmall.cn
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="data"
{"orderInnerId":"12146","p":{"imei":"866568022978356","mac":"58:1f:28:ea:4d:e1","os":"android4.4.2","platform":"Android","ptype":"H60-L01_19_4.4.2","version":"6.1.1"},"type":1}
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="mode"
plain
----WebKitFormBoundaryE19zNvXGzXaLvS5C
But can parser x-www-form-urlencode:
POST /kflq_webcfg/v1/update HTTP/1.1
Host: h.innmall.cn
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
data={"orderInnerId":"12146","p":{"imei":"866568022978356","mac":"58:1f:28:ea:4d:e1","os":"android4.4.2","platform":"Android","ptype":"H60-L01_19_4.4.2","version":"6.1.1"},"type":1}&mode=plain
How to solve this problem through the body-parser middleware?
I need these two cases to get the same result.
thank you very much!
Body-parser cannot handle multipart bodies, you should use something like multer for that. In addition to handling file uploads multer also parses the text fields of a multipart data into req.body. Body-parser docs also give a good explanation.

Resources