Node.js Connect middleware Limit not working - javascript

I have a problem
server:
var connect = require('connect');
var http = require('http');
var app = connect()
.use(connect.limit('32kb'))
.use(connect.urlencoded())
.use(connect.json())
.use(function(req, res){
console.log('yo');
res.end('hello\n');
});
http.createServer(app).listen(3000);
client:
var http = require('http');
var req = http.request({
method: 'POST',
port: 3000,
headers: {
'Content-Type': 'application/json'
}
});
req.write('[');
var n = 30000000;
while (n--) {
req.write('"foo",');
}
req.write('"bar"]');
req.end();
Connect's middleware limit not "limiting" size of json. I know that it will deprecated, but instead Express framework what can i use to limit a size of requests?

do this instead:
.use(connect.urlencoded({
limit: '32kb'
}))
.use(connect.json({
limit: '32kb'
}))
or just:
.use(connect.bodyParser({
limit: '32kb'
})
you can still write to req, but that doesn't necessarily mean the server will receive those bytes. if you check the response and it isn't a 4xx error, then it's a bug.
EDIT:
req.once('response', function (res) {
assert.equal(res.statusCode, 413)
})
.write(new Buffer(123123123213223122))
.end()

the limit middleware checks the header Content-Length of request message only while there's no such header out of your HTTP POST request.
You can verify this by using:
var app = connect()
.use(connect.limit('32kb'))
.use(connect.urlencoded())
.use(connect.json())
.use(function(req, res){
console.log(req.headers);
console.log('yo');
res.end('hello\n');
});
You can test the limit middle via this code:
var http = require('http');
var req = http.request({
method: 'POST',
port: 3000,
headers: {
'Content-Type': 'application/json',
'Content-Length': 40 * 1024
}
});
BTW: you can check how the limit middleware is tested: https://github.com/senchalabs/connect/blob/master/test/limit.js

Related

Node.js with express.js returns 500 to ajax call

I have a cordova project where I do the following request.
$("#asd").on("click",function(){
var data = {};
data.title = "title";
data.message = "message";
$.ajax('127.0.0.1:3000/register',
{
type: 'POST',
data: JSON.stringify(data),
contentType: 'application/json',
success: function() { console.log('success');},
error : function() { console.log('error');}
});
});
Server side code:
var express = require('express');
var app = express();
app.use(express.bodyParser());
app.post('/register', function(req, res){
var obj = {};
console.log('body: ' + JSON.stringify(req.body));
res.send(req.body);
});
app.listen(3000);
But I get Internal Server Error 500 when I send the request. If I make a request simply by an html form or curl it just works fine.
What might be the cause of this?
$.ajax({
url:'/register', //or 'localhost:3000/register'
type: 'POST',
data: JSON.stringify(data),
contentType: 'application/json',
success: function() { console.log('success');},
error : function() { console.log('error');}
});
Also you are required to use cors()
var cors = require('cors')
var app = express();
app.use(cors());
Also: https://enable-cors.org/server_expressjs.html
If it's related to the CORS, then you need to allow CORS on the server wich serves static via adding the following HTTP header:
Access-Control-Allow-Origin: http://127.0.0.1:3000
Here is the example for Express (they put a wildcard * instead of http://127.0.0.1:3000).
Try JSON.stringify() in response
res.send(JSON.stringify(req.body));

How to use the node.js 'request' library with this http request?

I was trying to make a simple request to site. it should get html text, but it gets ' '
NPM module here: github.com/request/request
Code:
var fs = require('fs');
var request = require('request');
var options = {
url:'https://sample.site/phpLoaders/getInventory/getInventory.php',
encoding : 'utf8',
gzip : true,
forever: true,
headers: {
'Host': 'sample.site',
'Connection': 'keep-alive',
'Content-Length': '58',
'Cache-Control': 'max-age=0',
'Accept': '*/*',
'Origin': 'https://csgosell.com',
'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Referer': 'https://sample.site/',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4',
'Cookie': 'my-cookies from browser'
},
form: {
stage:'bot',
steamId:76561198284997423,
hasBonus:false,
coins:0
}
};
request.post(options,
function(error, response, body){
console.log(response.statusCode);
if (!error) {
fs.writeFileSync('site.html', body);
}
else{
console.log(error);
}
}
);
Chrome request: https://i.stack.imgur.com/zKQo5.png
Nodejs request:https://i.stack.imgur.com/yH9U3.png
the difference is in headers:
:authority:csgosell.com
:method:POST :path:/phpLoaders/getInventory/getInventory.php :scheme:https
after some googling, I anderstood that it is http2, and tried to put it inow another agent's options, but nothing changed.
var spdy = require('spdy');
var agent = spdy.createAgent({
host: 'sample.site',
port: 443,
spdy: {
ssl: true,
}
}).once('error', function (err) {
this.emit(err);
});
options.agent = agent;
To answer your question i will copy/paste a part of my code that enable you to receive a post request from your frontend application(angularJS) to your backend application (NodeJS), and another function that enable you to do the inverse send a post request from nodeJS to another application (that might consume it):
1) receive a request send from angularJS or whatever inside your nodeJS app
//Import the necessary libraries/declare the necessary objects
var express = require("express");
var myParser = require("body-parser");
var app = express();
// we will need the following imports for the inverse operation
var https = require('https')
var querystring = require('querystring')
// we need these variables for the post request:
var Vorname ;
var Name ;
var e_mail ;
var Strasse ;
app.use(myParser.urlencoded({extended : true}));
// the post request is send from http://localhost:8080/yourpath
app.post("/yourpath", function(request, response ) {
// test the post request
if (!request.body) return res.sendStatus(400);
// fill the variables with the user data
Vorname =request.body.Vorname;
Name =request.body.Name;
e_mail =request.body.e_mail;
Strasse =request.body.Strasse;
response.status(200).send(request.body.title);
});
2) Do the inverse send a POST request from a nodeJS application to another application
function sendPostRequest()
{
// prepare the data that we are going to send to anymotion
var jsonData = querystring.stringify({
"Land": "Land",
"Vorname": "Vorname",
"Name": "Name",
"Strasse": Strasse,
});
var post_options = {
host: 'achref.gassoumi.de',
port: '443',
method: 'POST',
path: '/api/mAPI',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': jsonData.length
}
};
// request object
var post_req = https.request(post_options, function(res) {
var result = '';
res.on('data', function (chunk) {
result += chunk;
console.log(result);
});
res.on('end', function () {
// show the result in the console : the thrown result in response of our post request
console.log(result);
});
res.on('error', function (err) {
// show possible error while receiving the result of our post request
console.log(err);
})
});
post_req.on('error', function (err) {
// show error if the post request is not succeed
console.log(err);
});
// post the data
post_req.write(jsonData);
post_req.end();
// ps : I used a https post request , you could use http if you want but you have to change the imported library and some stuffs in the code
}
So finally , I hope this answer will helps anyone who is looking on how to get a post request in node JS and how to send a Post request from nodeJS application.
For further details about how to receive a post request please read the npm documentation for body-parser library : npm official website documentation

Redirect to new page and set POST data

I am trying to redirect to a new web site and set post data to be sent to that website. I tried this:
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(302, {"Location": "http://example.com/newpage/", "Content-Type": "application/x-www-form-urlencoded"});
res.end("param1=value1&param2=value2");
}).listen(process.env.PORT, process.env.IP);
This is unsuccessful. How can I redirect to a new website and set POST data?
Simple redirect cannot send with post data.
You have to make a new request and pipe to original request
http.createServer(function (req, res) {
var http = require('http');
var post_data = JSON.stringify({aaa: 'abc', bbb: 123});
var options = {
host: 'example.com',
port: '80',
path: '/',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': post_data.length
};
var req = http.request(options, function(resp_new) {
resp_new.setEncoding('utf8');
resp_new.on('data', function(chunk){
res.send(chunk);
});
resp_new.on('end', function(){
res.end();
});
});
req.write(post_data);
req.end();
});

How to resolve NODE.Js HTTP POST "ECONNRESET" Error

I have this function and the below data which is passed into this function returns a ECONNRESET, socket hang up error. However, when the discountCode array is reduced to like only 10 objects, it can POST without any problem.
What could the cause for this problem? I tried to do multiple req.write() by segmenting the data in Buffer, however that doesn't work out well. Any NodeJs ninja could give some insights to this problem?
createObj: function(data, address, port, callback) {
//console.log('Create Reward: '+JSON.stringify(data));
var post_data = JSON.stringify(data);
var pathName = '/me/api/v1/yyy/'+data.idBusinessClient+'/newObj';
//
var options = {
hostname: address,
port: port,
path: pathName,
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Accept': 'application/json',
'Accept-Encoding': 'gzip,deflate,sdch',
'Accept-Language': 'en-US,en;q=0.8'
}
};
// http call to REST API server
var req = restHttp.request(options, function(res) {
console.log('HTTP API server PUT Reward response received.');
var resData = '';
res.on('data', function(replyData) {
// Check reply data for error.
console.log(replyData.toString('utf8'));
if(replyData !== 'undefined')
resData += replyData;
});
res.on('end', function() {
//<TODO>Process the data</TODO>
callback(JSON.parse(resData));
});
});
req.write(post_data);
req.end();
console.log('write end');
req.on('close', function() {
console.log('connection closed!');
});
req.on('error', function(err) {
console.log('http request error : '+err);
callback({'error':err});
throw err;
});
req.on('socket', function(socket) {
console.log('socket size:'+socket.bufferSize);
socket.on('data', function(data) {
console.log('socket data:'+data);
});
});
}
]}`
I had the same problem and was able to resolve it by adding a Content-Length header:
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': Buffer.byteLength(post_data),
'Accept': 'application/json',
'Accept-Encoding': 'gzip,deflate,sdch',
'Accept-Language': 'en-US,en;q=0.8'
}
However, I still have no clear idea why a missing Content-Length header causes such a trouble. I assume it's some kind of weirdness in the internal Node.js code. Maybe you can even call it a bug, but I'm not sure about that ;)
PS: I'm absolutely interested more information about the cause of this problem. So please leave a comment if you have any idea...
When you change the content of response for sure you need also to update on header the content length:
headers: {
...
'Content-Length': Buffer.byteLength(post_data),
...
}
But i run on this problem also when i try to make multiple request and seems that this is not well managed on different library so a workaround that i have found if this problem persist is to add on headers:
headers: {
...
connection: 'Close'
...
}
So if you are making request on different servers.. this close the connection after finish the process. This worked for me in net, node-http-proxy.
If Express and http-proxy-middleware is used to make the POST call, and some body parser middleware is used like express.json(), the request interceptor fixRequestBody must be used (more info). Otherwise the POST call will hang with the ECONNRESET error.
const express = require('express');
const { createProxyMiddleware, fixRequestBody } = require('http-proxy-middleware');
const app = express();
app.use(express.json());
app.post(
'/path',
createProxyMiddleware('/path', {
target: API_URL,
changeOrigin: true,
pathRewrite: (path, req) => `/something/${req?.body?.someParameter}`,
onProxyReq: fixRequestBody // <- Add this line
});
Had the same problem. The solution for me was to append it to the proxy for it to work. If you're not using a proxy, you can probably just append it to the post request itself.
With proxy:
import express from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';
import logger from './logger';
// setup routes
server.get('/isAlive', (req, res) => res.send('Alive'));
server.get('/isReady', (req, res) => res.send('Ready'));
server.use(express.static(path.join(__dirname, '../build')));
const restream = (proxyReq, req, res, options) => {
if (req.body) {
let bodyData = JSON.stringify(req.body);
proxyReq.setHeader('Content-Type', 'application/json');
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
proxyReq.write(bodyData);
}
};
server.use(
'/api',
createProxyMiddleware({
target: 'http://your-backendUrl-api',
onProxyReq: restream,
changeOrigin: true,
proxyTimeout: 30000,
secure: true,
logLevel: 'info',
onError: (err, req, res) => {
logger.error('error in proxy', err, req, res);
},
})
);
E.g without proxy:
import axios, { AxiosResponse } from 'axios';
const api = axios.create({
baseURL: '/api/....',
timeout: 35000,
withCredentials: true,
headers: { Pragma: 'no-cache', 'Cache-Control': 'no-cache' },
validateStatus: (status) => status < 400,
});
const response = await api.post(
`/somepath/${exampleInjectedId}/somepathToRestAPI`,
{
...payload
},
{
baseURL: '/api/...',
timeout: 35000,
withCredentials: true,
headers: {
Pragma: 'no-cache',
'Cache-Control': 'no-cache',
'Content-Length': Buffer.byteLength(
JSON.stringify({
...payload
})
),
},
validateStatus: (status) => status < 400,
}
);

How can I make AJAX requests using the Express framework?

I want to send AJAX requests using Express. I am running code that looks like the following:
var express = require('express');
var app = express();
app.get('/', function(req, res) {
// here I would like to make an external
// request to another server
});
app.listen(3000);
How would I do this?
You can use request library
var request = require('request');
request('http://localhost:6000', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Print the body of response.
}
})
You don't need Express to make an outgoing HTTP request. Use the native module for that:
var http = require('http');
var options = {
host: 'example.com',
port: '80',
path: '/path',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': post_data.length
}
};
var req = http.request(options, function(res) {
// response is here
});
// write the request parameters
req.write('post=data&is=specified&like=this');
req.end();
Since you are simply making a get request I suggest this
https://nodejs.org/api/http.html#http_http_get_options_callback
var http = require('http');
http.get("http://www.google.com/index.html", function(res) {
console.log("Got response: " + res.statusCode);
if(res.statusCode == 200) {
console.log("Got value: " + res.statusMessage);
}
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
That code is from that link

Categories

Resources