Node file upload ends with 502 Gateway Error - node.js

I am trying to upload a file using request module to Telegram's Bot API. However, I end up with a 502 Gateway Error. Here's my code:
var request = require("request");
var fs = require("fs");
fs.readFile("image.png",function(err,data){
var formdata = {};
formdata.chat_id = <chatid>;
formdata.photo = data;
if(err)
console.log(err);
request({
url : "https://api.telegram.org/bot<token>/sendPhoto",
method : "POST",
headers : {
"Content-Type" : "multipart/form-data"
},
formData : formdata
},function(err,res,body){
if(err)
console.log(err)
console.log(body);
})
});
Is this the proper way to upload a file or am I making a mistake somewhere?

I suggest, it's better for you to use form field of request object, which gives you possibility to send file using createReadStream function of fs module.For example:
var r = request.post({
url: url
},someHandler);
var form = r.form();
form.append('file',fs.createReadStream(filePath));
For proper use read:
https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options
https://github.com/request/request#forms

Related

How to upload file using axios post request

I am trying to upload a file to url using axios post request. But i am getting 500 internal server error.
If the same request I tried from postman file gets uploaded with 200 status code.
I am not sure what should be the content-Type here.
here is my code.
const axios = require('axios')
var FormData = require('form-data');
var fs = require("fs");
var request = require('request');
const formData = {
file: fs.createReadStream('myfile.txt')
}
const config = {
headers: {
'Content-Type': 'multipart/form-data'
}
};
axios.post('myurl',formData,config)
.then((res) => {
console.log(`statusCode: ${res.status}`)
console.log(res.data)
})
.catch((error) => {
console.log(error)
})
Please check your frontend, when you click submit, do you call event.preventDefault();
const formData = {
file: fs.createReadStream('myfile.txt')
}
It's a plain javascript object, not a ready-to-use formData. You just forget to transform it into a real FormData object. Just check for the document of form-data module.
Also it seems that when you post a real FormData, the "Content-type" header is unnecessary as axios will automaticly handle it for you.

how to read image from local and convert it into file object using node.js

I have a .png file in my node project folder and I want to read that file and send that file to a remote REST api which accepts form-data format and returns the image url after uploading it to S3.
I have previously used the same api for image upload in front-end using JavaScript. In my JS application I was using input type file to upload a image, which was giving me image in file format and then I was passing that to api after adding that file into formData object like this:
let formData = new FormData();
formData.append("content_file", file)
but when I'm trying to do the same in node.js, I'm not able to read that file into file format, due to which Api is not accepting the request body.
I'm new to node js, I'm not even sure that I'm reading the file in right way or not. Please help!
var express = require('express');
var fs = require('fs');
var path = require('path');
var Request = require("request");
var FormData = require('form-data');
var app = express();
// for reading image from local
app.get('/convertHtml2image1', function (req, res) {
fs.readFile(`image_path`, (err, data) => {
if (err) res.status(500).send(err);
let extensionName = path.extname(`banner.png`);
let base64Image = new Buffer(data, 'binary').toString('base64');
let imgSrcString = `data:image/${extensionName.split('.').pop()};base64,${base64Image}`;
// for converting it to formData
let formData = new FormData();
formData.append("content_file", data)
// for calling remote REST API
Request.post({
"headers": { "token": "my_token" },
"url": "api_url",
"body": formData
}, (error, response, body) => {
if (error) {
return console.log(error);
}
let result = JSON.parse(body)
res.send("image_url: " + result.url)
});
})
})
app.listen(5000);
As far as I understand, you try to create Blobs in Nodejs. It is not defined but it is basically an arraybuffer with file information. Maybe, you can use an external npm package to make it blob. Check this
Instead of fs.readFile() use fs.createReadStream() and don't upload image inside file stream, first read the file then add it to formData and then upload(or send it to api) because instead of file you were uploading the stream here.
var express = require('express');
var fs = require('fs');
var path = require('path');
var Request = require("request");
var FormData = require('form-data');
var app = express();
app.get('/convertHtml2image', function (req, res) {
var formData = {
name: 'content_file',
content_file: {
value: fs.createReadStream('banner.png'),
options: {
filename: 'banner.png',
contentType: 'image/png'
}
}
};
Request.post({
"headers": {
"Content-Type": "multipart/form-data",
"token": my_token
},
"url": api_url,
"formData": formData
}, (error, response, body) => {
if (error) {
return console.log("Error: ", error);
}
let result = JSON.parse(body)
res.send("image_url: " + result.url)
});
})
app.listen(5000);

How to add file attachment to soap request with node-soap library ?

I need to add an file attachment to a soap request from node.js application.
I am able to send request with node-soap library, and now I need to add a file to the request.
I did it with a java client or with soapUI, but I have to do it in node.js, maybe it's possible to do that overriding default request object ?
I didn't find a solution with node-soap, I had to build manually my soap request :
var soapHeader = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header/><soapenv:Body><ws:method>';
var soapFooter = '</ws:method></soapenv:Body></soapenv:Envelope>';
function sendSoapRequestWithAttachments(soap,files){
var soapRequest = jsonToXml.buildObject(mail);
var finalSoapRequest = soapHeader + soapRequest + soapFooter;
var multipartMail = [];
// Add soap request
multipartMail.push({
'Content-Type': 'text/xml; charset=utf-8',
body: finalSoapRequest
});
// Add attachments
if (files) {
files.forEach(function (file) {
multipartMail.push({
'Content-Id': '<' + file.uuid + '>',
'Content-Type': 'application/octet-stream',
'Content-Transfer-Encoding': 'binary',
body: fs.createReadStream(file.path)
});
});
}
var options = {
uri: URL,
method: 'POST',
multipart: multipartMail
};
request.post(options, function (error, response) {
...
}
}
I found a way to send attachment using node-soap using base64 encoding
here is an example
import soap from 'soap'
import fs from 'fs'
async function main(){
const filepath = '/path/to/attachment/file.extension'
const client = await soap.createClientAsync(/* ... */)
const result = await client.AnApiMethodAsync({
expectedKeyForTheFile: await fs.readFileAsync(filepath, 'base64')
})
}
main()

AWS DeviceFarm Uploading the URL to S3 causes Error: read ECONNRESET?

While uploading the DeviceFarm S3 url for file uploading getting error code:ECONNRESET.
This is my code:
var AWS = require('aws-sdk');
var fs = require('fs');
var req = require('request');
var devicefarm = new AWS.DeviceFarm();
AWS.config.loadFromPath('C:/Users/Abin.mathew/AWSdata/config.json');
var apkPath= "D:/DTS/APKs/TPLegacyPlugin-googleplaystore-debug-rc_16.2.15.apk";
var stats = fs.statSync(apkPath);
var url= "https://prod-us-west-2-uploads.s3-us-west-2.amazonaws.com/arn%3Aaws%3Adevicefarm%3Aus-west-2%3A594587224081%3Aproject%3Ade07f584-7c64-4748-aebd-ec965ab107cf/uploads/arn%3Aaws%3Adevicefarm%3Aus-west-2%3A594587224081%3Aupload%3Ade07f584-7c64-4748-aebd-ec965ab107cf/5dd627eb-4eb2-4f2d-a300-0fde0720bde4/MyAppiumPythonUpload?AWSAccessKeyId";
fs.createReadStream(apkPath).pipe(req({
method: 'PUT',
url: url,
headers: {
'Content-Length': stats['size']
}
}, function (err, res, body) {
console.log(body);
console.log(res);
console.log(err);
}));
Your URL is incorrect. It represents the Appium test package but you are trying to upload an APK. Are you reusing a URL from a previous operation? Pre-signed URLs also expire after a period of time so they should not be reused.
To make this work,
Call CreateUpload and get the pre-signed URL from the result.
Post the correct file to the URL.
We have published a blog post that describes the procedure to follow. The code samples use the CLI but translating them to nodejs should be trivial.

Upload file to Box API from string using Node.js

I'm using version 2 of Box's API and attempting to upload files. I have Oauth 2 all working, but I'm having trouble making actual uploads.
I'm using Node.js and Express, along with the "request" module. My code looks something like this:
request.post({
url: 'https://upload.box.com/api/2.0/files/content',
headers: {
Authorization: 'Bearer ' + authToken
},
form: {
filename: ????,
parent_id: '0'
}
}, function (error, response, body) {
// ...
});
For now, I'm trying to upload to the root folder which, if I understand correctly, has an ID of '0'.
What I'm really not sure about is what value to give "filename". I don't have a true file to read from, but I do have a lengthy string representing the file contents I would like to upload.
How best should I upload this "file"?
For Box, I believe you want to use requests multi-part/form-data implementation.
It should look something like this:
var request = require('request');
var fs = require('fs');
var r = request.post(...);
var form = r.form();
form.append('filename', new Buffer("FILE CONTENTS"), {filename: 'file.txt'});
form.append('parent_id', 0);
var fs = require('fs');
var request = require('request');
var path = require('path');
function requestCallback(err, res, body) {
console.log(body);
}
var accessToken = 'SnJzV20iEUw1gexxxxvB5UcIdopHRrO4';
var parent_folder_id = '1497942606';
var r = request.post({
url: 'https://upload.box.com/api/2.0/files/content',
headers: { 'Authorization': 'Bearer ' + accessToken }
}, requestCallback);
var form = r.form();
form.append('folder_id', parent_folder_id);
form.append("filename", fs.createReadStream(path.join(__dirname, 'test.mp4')));

Resources