Custom code parsing issue- Request Entity Too Large - Oracle MCS - node.js

Hi I am facing an issue while accessing custom api using Oracle MCS
{
"message": "Custom Code Problem parsing JSON: request entity too large"
}
This occur while calling an api with request containing a byte array of an image.
my code given below
service.post('/mobile/custom/meraasmcs/documentofrecords/updateemiratesid',function(req,res){
console.info("Request Before Api call=>"+req);
var connector = '/documentofrecords/updateemiratesid'
commonHandler.CommonHandlerPostMethodFunction(
req,res,connector)
commonHandler.js
module.exports = {
CommonHandlerPostMethodFunction:
function (req, res, connector) {
/*
* Description : This function handles all the request and response
* Output : Returns a json content success message
* Author : Anand Raj
* Created Date : 10/10/2016
*/
var app = express();
var newReqBody=app.use(bodyParser.json({limit: '50mb'}));
console.info('New ReqBody=>'+newReqBody);
var errorMsg;
var finalResponse;
var headerIndex = JSON.stringify(
req.headers).search('application/json');
var versionNumberIndex = JSON.stringify(
req.headers).search('x-api-version');
var reqBody = JSON.stringify(req.body);
console.info('header ' + JSON.stringify(req.headers));
console.info('version index ' + versionNumberIndex);
console.info('version number ' + req.headers['x-api-version']);
console.info('Req body ' + reqBody);
res.header('Access-Control-Allow-Origin','*'); // To overcome cross origin issue in Windows platform
if (0 > headerIndex) {
finalResponse = jbuilder.encode(function (json) {
json.set('Response', function (json) {
json.set('responseCode', '415');
json.set('responseMessage', 'Unsupported media-type');
});
});
res.status(415).send(finalResponse);
res.end();
} else if (reqBody === '{}') {
finalResponse = jbuilder.encode(function (json) {
json.set('Response', function (json) {
json.set('responseCode', '400');
json.set('responseMessage', 'Malformed request body');
});
});
res.status(400).send(finalResponse);
res.end();
} else if (0 > versionNumberIndex) {
finalResponse = jbuilder.encode(function (json) {
json.set('Response', function (json) {
json.set('responseCode', '400');
json.set('responseMessage', 'Version Number missing');
});
});
res.status(400).send(finalResponse);
res.end();
} else {
/* request part */
var versionNumber = req.headers['x-api-version'];
var optionsList = {
uri: '/mobile/connector/MeraasAllConnector'+connector,
body: reqBody,
headers: {
'Content-Type': 'application/json',
'X-API-Version': versionNumber
}
};
/* handler part */
var handler = function (error, response, body) {
if (error) {
if ('message' in error) {
errorMsg = error.message;
//res.send(500, errorMsg);
//res.end();
finalResponse = jbuilder.encode(function (json) {
json.set('Response', function (json) {
json.set('responseCode', '500');
json.set('responseMessage', errorMsg);
});
});
res.status(500).send(finalResponse);
res.end();
} else {
finalResponse = jbuilder.encode(function (json) {
json.set('Response', function (json) {
json.set('responseCode', '408');
json.set('responseMessage', 'Response Timed Out');
});
});
res.status(408).send(finalResponse);
res.end();
}
} else {
if (response.statusCode !== 200) {
finalResponse = jbuilder.encode(function (json) {
json.set('Response', function (json) {
json.set('responseCode', response.statusCode);
json.set('responseMessage', response.message);
});
});
res.status(response.statusCode).send(finalResponse);
res.end();
} else if(response.statusCode==401){
finalResponse = jbuilder.encode(function (json) {
json.set('Response', function (json) {
json.set('responseCode', '401');
json.set('responseMessage', 'Authorization Required.');
});
});
res.status(401).send(finalResponse);
res.end();
}
else {
res.status(200).send(body);
res.end();
}
}
};
req.oracleMobile.rest.post(optionsList, handler);
}
}
};
Package.json
{
"name" : "meraasmcs",
"version" : "1.47.0",
"description" : "Contains all the custom Apis for Meraas Mobile App",
"main" : "meraasmcs.js",
"dependencies":
{
"jbuilder":"0.0.4",
"body-parser":"1.15.2",
"express":"4.14.0"
},
"oracleMobile" : {
"dependencies" : {
"apis" : { },
"connectors" : {"/mobile/connector/MeraasAllConnector":"1.0"}
}
}
}
If i reduce the size of image then pass its corresponding byte array, then there response will be success.
I checked related questions, all it says
var bodyParser = require('body-parser');
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
But i tried that also. Could anyone please help me??
Sample Request
{
"P_PERSON_ID": 31441,
"P_LOGIN_PERSON_ID": 31441,
"TIME_STAMP": null,
"P_EMIRATES_ID_TAB": [{
"DocumentExtraInfoId": "",
"ValidFrom": "2016-11-23",
"ValidTo": "2016-11-24",
"CardNumber": "Ggv4"
}],
"P_ATTACHMENT_TAB": [{
"Title": "image.jpg",
"DocumentId": null,
"DeleteFlag": "N",
"Description": "Testqwe",
"AttachmentName": "Test",
"FileData": "",
"AttachmentType": "image/jpeg"
}]
}
Issue comes when the length of the value of FileData is too large.
Thanks in advance

Related

Cannot view data on page after adding API requests nodejs

I've added API requests which would retrieve data from MongoDB I believe. Whilst no issues arise when running the code, the pages do not show any data; I just get an error message (retrieved from a separate piece of code) stating the page cannot be found.
This is the code from my Locations controller:
module.exports.homelist = function(req, res){
var requestOptions, path;
path = '/api/locations';
requestOptions = {
url : apiOptions.server + path,
method : "GET",
json : {},
qs : {
lng : -0.7992599,
lat : 51.378091,
maxDistance : 20
}
};
request (
requestOptions,
function(err, response, body) {
var i, data;
data = body;
if(response.statusCode === 200 && data.length){
for (i=0; i<data.length; i++) {
data[i].distance = _formatDistance(data[i].distance);
}
}
renderLocHomepage(req, res, body);
}
);
var _formatDistance = function (distance){
var numDistance, unit;
if (distance > 1){
numDistance = parseFloat(distance).toFixed(1);
unit = 'km';
} else {
numDistance = parseInt(distance * 1000,10);
unit = 'm';
}
return numDistance + unit;
}
};
var renderLocHomepage = function(req, res, responseBody){
var message;
if(!(responseBody instanceof Array)){
message = "API lookup error";
responseBody = [];
} else {
if (!responseBody.length) {
message = "No places found nearby";
}
}
res.render('location', {
title: 'Location Title 2',
pageHeader: {
title: 'fuiewhf',
strapline: 'sdjkcdivfdvdj'
},
sidebar: "efvibjdmkdsuidjvifdvhiskfbvzd",
locations: responseBody,
message: message
});
};
/* GET 'Locations List' page*/
module.exports.locationsList = function(req, res) {
res.render('locations-list', {title: 'Locations List'});
};
module.exports.locationInfo = function(req, res){
renderDetailPage(req, res);
};
var renderDetailPage = function (req, res, locDetail){
res.render('location-info', {
title: locDetail.name,
pageHeader: {title: locDetail.name},
sidebar: {
context: 'is on Loc8r because it has some accessible wifi and space to sit',
callToAction: 'If you\'ve been and you like it or don\'t, please leave a review'
},
location: locDetail
});
};
/*GET 'Location info' page */
module.exports.locationInfo = function(req, res){
var requestOptions, path;
path = "/api/locations/" + req.params.locationid;
requestOptions = {
url : apiOptions.server + path,
method : "GET",
json : {}
};
request (requestOptions, function(err, response, body) {
var data = body;
if (response.statusCode === 200){
data.coords = {
lng : body.coords[0],
lat : body.coords[1],
};
renderDetailPage(req, res, data);
} else{
_showError(req, res, response.statusCode);
}
}
);
};
module.exports.locationsListByDistance = function(req, res){
var lng = parseFloat(req.query.lng);
var lat = parseFloat(req.query.lat);
var point = {
type: "Point",
coordinates: [lng, lat]
};
var geoOptions = {
spherical: true,
maxDistance: theEarth.getRadsFromDistance(20),
num: 10
};
if ((!lng && lng!==0) || (!lat && lat!==0)) {
sendJsonResponse(res, 404, {
"message": "lng and lat query parameters are required"
});
return;
}
Location.geoNear(point, geoOptions, function(err, results, stats){
var locations = [];
if (err) {
sendJsonResponse(res, 404, err);
} else {
results.forEach(function(doc) {
locations.push({
distance: theEarth.getDistanceFromRads(doc.dis),
name: doc.obj.name,
address: doc.obj.address,
rating: doc.obj.rating,
facilities: doc.obj.facilities,
_id: doc.obj._id
});
});
sendJsonResponse(res, 200, locations);
}
});
};
var _formatDistance = function (distance){
var numDistance, unit;
if (distance > 1){
numDistance = parseFloat(distance).toFixed(1);
unit = 'km';
} else {
numDistance = parseInt(distance * 1000,10);
unit = 'm';
}
return numDistance + unit;
};
//defining a call to an API
var requestOptions = {
url: "", //define URL of API call to be made
method: "GET", //set request method
json: {},
qs: {
offset: 20
}
};
request(requestOptions, function(err, response, body) {
if(err){
console.log(err);
} else if(response.statusCode === 200) {
console.log(body);
} else {
console.log(response.statusCode);
}
});
//Create a new reusable function to get location information
var getLocationInfo = function(req, res, callback) {
var requestOptions, path;
path = "/api/locations/" + req.params.locationid;
requestOptions = {
url : apiOptions.server + path,
method : "GET",
json : {}
};
request (
requestOptions,
function(err, response, body) {
var data = body;
if (response.statusCode === 200) {
data.coords = {
lng : body.coords[0],
lat : body.coords[1]
};
callback(req, res, data);
} else {
_showError(req, res, response.statusCode);
}
}
);
};
module.exports.locationInfo = function(req, res){
getLocationInfo(req, res, function (req, res, responseData){
renderDetailPage(req, res, responseData);
});
};
In renderHomepage you have res.render('/'... but res.render takes as first parameter the name of the file you want to render (minus the file extension):
res.render('index', ...
if your homepage is under views/index.ejs for example.

How to send selected files to a node server using react native fs?

I am using https://github.com/itinance/react-native-fs to upload files from a react-native client, but it's not getting received in my nodejs server. By the way, I have used react-native-document-picker https://github.com/Elyx0/react-native-document-picker to select the files from the Android file system. Here is my client app's code;
async uploadToNode() {
let testUrl = this.state.multipleFile[0].uri; //content://com.android.providers.media.documents/document/image%3A7380
const split = testUrl.split('/');
const name = split.pop();
const setFileName = "Img"
const inbox = split.pop();
const realPath = `${RNFS.TemporaryDirectoryPath}${inbox}/${name}`;
const uploadUrl = "http://localhost:8082/uploadToIpfs";
var uploadBegin = (response) => {
const jobId = response.jobId;
console.log('UPLOAD HAS BEGUN! JobId: ' + jobId);
};
var uploadProgress = (response) => {
const percentage = Math.floor((response.totalBytesSent/response.totalBytesExpectedToSend) * 100);
console.log('UPLOAD IS ' + percentage + '% DONE!');
};
RNFS.uploadFiles({
toUrl: uploadUrl,
files: [{
name: setFileName,
filename:name,
filepath: realPath,
}],
method: 'POST',
headers: {
'Accept': 'application/json',
},
begin: uploadBegin,
beginCallback: uploadBegin, // Don't ask me, only way I made it work as of 1.5.1
progressCallback: uploadProgress,
progress: uploadProgress
})
.then((response) => {
console.log(response,"<<< Response");
if (response.statusCode == 200) { //You might not be getting a statusCode at all. Check
console.log('FILES UPLOADED!');
} else {
console.log('SERVER ERROR');
}
})
.catch((err) => {
if (err.description) {
switch (err.description) {
case "cancelled":
console.log("Upload cancelled");
break;
case "empty":
console.log("Empty file");
default:
//Unknown
}
} else {
//Weird
}
console.log(err);
});
}
I'm not sure if the nodejs code is correct to get the files from the client app. And here is my Server code;
app.post('/uploadToIpfs', (req, res) => {
// network.changeCarOwner(req.body.key, req.body.newOwner)
// .then((response) => {
// res.send(response);
// });
// var fileName = "Img";
// if(req.name == fileName){
// console.log(req.filename);
// res.send("Passed")
// }else{
// res.send("failed")
// }
console.log(req.files[0].filename);
res.send("Passed")
});
app.listen(process.env.PORT || 8082);

Downloading a compressed folder on client side not working in angular+node (MEAN)

I need to allow user to download compressed folders from server. I managed to make the compression however even if I try to read the tar file and send it to client side for download file is corrupted or is saving only one file from folder (1/7 for example).
I have tried to send json files and the same code worked but for large and tar files it's not sending entire file.
I have tried just to send tar file from backend to client side to download but it also doesn't work.
/* back controller. */
const getDataDownload = function(req,res) {
if (req.params && req.params.dataId){
DataModel
.findById(req.params.dataId)
.exec((err,data) => {
if(data){
var file = '../data/filename.tar';
var stat = fs.statSync(file);
res.writeHead(200, {
'Content-Type' : 'application/tar',
'Content-Length' : stat.size
});
var tempTarFile = fs.createReadStream(file);
tempTarFile.pipe(res);
}})}
else {
res
.status(404)
.json({"message":"No Id in request"});
}
}
/* front controller. */
public dataDownload(dataId: string){
const url: string = `${this.apiBaseUrl}/dataDownload/${dataId}/`;
const req = new HttpRequest('GET', url, {
headers: new HttpHeaders({'Authorization': token}),
responseType: 'text' as 'text',
reportProgress: true});
this.http.request(req).subscribe((event: HttpEvent<any>)=>{
switch (event.type) {
case HttpEventType.Response:
const filename = 'filename.tar'
var blob = new Blob([event.body], { type: "application/tar" });
saveAs(blob, 'filename.tar')
break;
case HttpEventType.DownloadProgress:
console.log(' (',Math.round(event.loaded/event.total),')');
break;
}}
)
}
File doesn't open properly and it doesn't have a proper size.
Please help
Back controller:
const getDataDownload = function (req, res) {
if (req.params && req.params.dataId) {
DataModel
.findById(req.params.dataId)
.exec((err, data) => {
if (data) {
let file = '/home/pierbjx/Documents/sorfML/test.tar';
try {
let stat = fs.statSync(file);
res.writeHead(200, {
'Content-Type': 'application/tar',
'Content-Length': stat.size
});
let tempTarFile = fs.createReadStream(file);
tempTarFile.pipe(res);
} catch (err) {
console.log('Error: ' + err);
}
}
})
}
else {
res
.status(404)
.json({ "message": "No Id in request" });
}
}
Front controller:
public dataDownload(dataId: string): void {
const url: string = `${this.apiBaseUrl}/dataDownload/${dataId}/`;
const req = new HttpRequest('GET', url, {
responseType: "blob",
headers: new HttpHeaders().append("Content-Type", "application/json"),
reportProgress: true
});
this.http.request(req)
.subscribe(
event => {
if (event.type === HttpEventType.DownloadProgress) {
console.log("Download progress event", event);
}
if (event.type === HttpEventType.Response) {
console.log("response received...", event.body);
const filename = 'filename.tar';
saveAs(event.body, filename);
}
},
err => {
alert("Problem while downloading the file.");
console.error(err);
}
);
}

Synchronous api calls in Node.js

I've a cronjob that runs every 10 secs. It requests for machines for a single client and does computation based on the response and then has to update or create documents with those computations in a for loop. But, the api calls after '***' in the code don't happen until the for loop has executed and the data sent to the api calls is that of the last machine which is wrong. I want to solve this by this way or some other way possible. My code looks like this:
// index.js
const cron = require("node-cron");
const express = require("express");
const fs = require("fs");
const request = require("request");
app = express();
var clientId = 'ABCD';
var apiUrl = 'http://example.com:3001/';
var getMachines = apiUrl + 'getMachines/',
updateMachine = apiUrl + 'updateMachine/',
getControlRoomStatus = apiUrl + 'getControlRoomStatus/',
registerControlRoomStatus = apiUrl + 'registerControlRoomStatus/',
updateControlRoomStatus = apiUrl + 'updateControlRoomStatus/';
cron.schedule("*/10 * * * * *", function() {
APICall(getMachines, { 'clientId' : clientId }, 'POST', function(err, machines) {
if (err) {
console.log(err);
} else {
console.log('--------------------------------------------------------------------------------------------------');
var allMachines = machines;
var currentDateTime = IST();
for (var i = 0; i < 2; i++) {
var lastCycleTime = new Date(allMachines[i]['lastCycleTime']);
var lastHeartbeat = new Date(allMachines[i]['lastHeartbeat']);
var machineData;
var controlRoomData;
var machineId = {
'machineId' : allMachines[i]['machineId']
};
console.log(machineId);
if (allMachines[i]['downtimeStatus'] == '0') {
if ((currentDateTime - lastCycleTime)>300000) {
if ((currentDateTime - lastHeartbeat)>300000) {
console.log(allMachines[i]['machineId'] ,' No Internet');
controlRoomData = {
'clientId': clientId,
'lastTimeStamp': allMachines[i]['lastCycleTime'],
'status': 'Inactive',
'type': 'No Internet/Power'
};
} else {
console.log(allMachines[i]['machineId'] ,' No button pressed');
controlRoomData = {
'clientId': clientId,
'lastTimeStamp': allMachines[i]['lastCycleTime'],
'status': 'Inactive',
'type': 'No Button Pressed'
};
}
machineData = {
'status' : 'Inactive'
};
} else {
console.log(allMachines[i]['machineId'] ,' Active');
machineData = {
'status' : 'Active'
};
controlRoomData = {
'clientId': clientId,
'lastTimeStamp': allMachines[i]['lastCycleTime'],
'status': 'Active',
'type': 'N.A'
};
}
} else {
if ((currentDateTime - lastHeartbeat)>300000) {
console.log(allMachines[i]['machineId'] ,' button pressed ',' No Internet');
controlRoomData = {
'clientId': clientId,
'lastTimeStamp': allMachines[i]['lastCycleTime'],
'status': 'Inactive',
'type': 'No Internet/Power'
};
} else {
var downtimeLength = allMachines[i]['downtimeData'].length - 1;
console.log(allMachines[i]['machineId'] ,' button pressed ',allMachines[i]['downtimeData'][downtimeLength]['downtimeType']);
controlRoomData = {
'clientId': clientId,
'lastTimeStamp': allMachines[i]['lastCycleTime'],
'status': 'Inactive',
'type': allMachines[i]['downtimeData'][downtimeLength]['downtimeType']
};
}
machineData = {
'status' : 'Inactive'
};
}
***
APICall(getControlRoomStatus, machineId, 'POST', function(err, controlRoom) {
if (err) {
console.log(err);
} else {
console.log(machineId,controlRoomData);
if (controlRoom == null ) {
APICall(registerControlRoomStatus, controlRoomData, 'POST', function(err, body) {
if (err) {
console.log(err);
} else {
// console.log(body);
}
});
} else {
var updateControlRooomUrl = (updateControlRoomStatus+''+controlRoom['_id']+'');
// console.log(updateControlRooomUrl);
APICall(updateControlRooomUrl, controlRoomData, 'PUT', function(err, body) {
if (err) {
console.log(err);
} else {
// console.log(body);
}
});
}
}
});
var updateMachineUrl = (updateMachine+''+allMachines[i]['_id']+'');
// console.log(updateMachineUrl);
APICall(updateMachineUrl, machineData, 'PUT', function(err, body) {
if (err) {
console.log(err);
} else {
console.log(i,machineId);
// console.log(body);
}
});
}
}
});
});
function APICall(url, requestData, method, callback) {
request({
url: url,
form: requestData,
method: method
}, function (error, response, body) {
if (error || response.statusCode !== 200) {
return callback(error || {statusCode: response.statusCode});
}
callback(null, JSON.parse(body));
});
}
function IST(){
var dateUTC = new Date();
var dateUTC = dateUTC.getTime();
var dateIST = new Date(dateUTC);
dateIST.setHours(dateIST.getHours() + 5);
dateIST.setMinutes(dateIST.getMinutes() + 30);
return dateIST;
}
app.listen(3128);
Thank you in advance.
I used a different method to do things and now it's working just as it's supposed to. I used 'async' and replaced the for loop with the following:
var async = require('async');
...
async.map(allMachines , function(machine, callback) {
...
});
...
You can try the following package:
sync-request
You can find it here on NPM.
Here is an example how to use it (from the docs):
var request = require('sync-request');
var res = request('GET', 'http://example.com');
console.log(res.getBody());
As stated in the documentation, don't use it in production code, since this will terribly block your server and it will slow down considerably (if you are running a HTTP server which you are using express).
If you have asynchronous code and you want to execute some code after the asynchronous you also can use:
Observables (not native need to use a package, RxJS for example)
Promises (native ES6 JS)

Export HTTP request as module function Node.js

I've tried (with success) to do an http request. I have some REST Api's, like graph.facebook.com as target. The functionality is the same. When i make an HTTP request with node.js as a simple program i can do it.
Really i want to make a little module, and i have this code:
// file: facebook.js
var http = require('http');
var Facebook = (function() {
function Facebook(access_token) {
this.access_token = access_token;
}
Facebook.prototype.getObject = function(id) {
var options;
this.id = id;
options = {
host: 'graph.facebook.com',
port: 80,
path: '/' + id + '?access_token=' + this.access_token
};
return http.request(options, function(response) {
response.on('data', function(d) {
return JSON.parse(d);
});
request.end();
return request.on('error', function(err) {
return {
error: 'An error ocurred.'
};
});
});
};
return Facebook;
})();
module.exports = Facebook;
After, when i write a program i can do this:
var facebook = require('./facebook.js');
var fb = facebook('my_Access_token')
// Here's the problem:
var response = fb.getObject('My_facebook_profile_ID')
I get a response like
{ domain: null,
_events:
{ response: { [Function: g] listener: [Function] },
socket: { [Function: g] listener: [Function] } },
....
When i must have something like
{
"id": "MyIDNumer",
"first_name": "Orlando",
"gender": "male",
"last_name": "Sanchez",
"link": "https://www.facebook.com/MyFacebookName",
"locale": "es_LA",
"name": "Orlando S\u00e1nchez",
"username": "MyUsername"
}
What can i do?
The first thing you should do is rewrite the module to not use the same function name twice ('Facebook').
Secondly, there's no need for the closure, just export the constructor.
Thirdly, you are trying to return a value from an asynchronous callback. This particular issue is common with people coming from the synchronous world.
Assuming you wanted to do a GET request, here's your module refactored after the above and other things are fixed:
// file: facebook.js
var http = require('http');
function Facebook(access_token) {
if (!(this instanceof Facebook))
return new Facebook(access_token);
this.access_token = access_token;
}
Facebook.prototype.getObject = function(id, cb) {
var options;
this.id = id;
options = {
host: 'graph.facebook.com',
port: 80,
path: '/' + id + '?access_token=' + this.access_token
};
http.get(options, function(res) {
var buf = '',
hadError = false;
res.on('data', function(d) {
buf += d;
}).on('error', function(err) {
hadError = true;
cb(err);
}).on('end', function() {
if (hadError)
return;
var val;
try {
val = JSON.parse(buf);
} catch (err) {
return cb(err);
}
cb(null, val);
});
});
};
module.exports = Facebook;
Then use it like so:
var facebook = require('./facebook.js');
var fb = facebook('my_Access_token');
fb.getObject('My_facebook_profile_ID', function(err, response) {
if (err) {
// include better error handling here
return console.log(err);
}
// use response here
console.dir(response);
});

Resources