Port redirection in node.js - node.js

I have a two server(running on two different port), one is for chat application, and another is for API generation server(user should register by providing company
details,and my algorithm gives a API key to the user).
The problem is, i am checking the valid API key,provided by the user, if API key is true then it should redirect to chat server(port no 5200).
But it doesn't work, please give any idea to resolve this issues.
Here is my code,
`
app.post('/checkAPIkey',function(req,res){
var apikey=req.query.apikey;
var apikey1=uuidAPIkey.isAPIKey(apikey);
if(apikey1){
res.writeHead(302, {
Location: 'http://localhost:5200'
});
}else{
res.end("error");
}
});`

What you need is called Request Forwarding.
Example:
const http = require('http');
app.post('/checkAPIkey', function(req,res){
var apikey=req.query.apikey;
var apikey1 = uuidAPIkey.isAPIKey(apikey);
if(apikey1){
const options = {
port: NEW_PORT,
hostname: 'NEW_HOST',
method: 'POST',
path: '/'
};
var reqForward = http.request(options, (newResponse) => {
//Do something with your newResponse
var responseData = "";
newResponse.on('data', (chunk) => {
//Add data response from newResponse
responseData += chunk;
});
newResponse.on('end', () => {
//Nothing more, send it with your original Response
response.send(responseData);
});
});
// If ERROR
reqForward.on('error', (e) => {
console.error('Error: ' + e);
});
// Write to the request
reqForward.write(YOUR_POST_DATA);
reqForward.end();
} else {
res.end("error");
}
});

Related

https Request in Alexa Skill

I can't seem to get HTTP requests to work in my alexa skill, here is the relevant sample code:
var https = require('https');
...
function getTreeFact(callbackFunction){
var url = 'https://alexa.phl.chs.network/treefacts/index.php';
https.get(url, function(res){
var body = '';
res.on('data', function(chunk){
body += chunk;
});
res.on('end', function(){
var gameResponse = JSON.parse(body);
callbackFunction(gameResponse);
});
}).on('error', function(e){
// Handle error
});
}
...
this.getTreeFact(function (responseMessage){
this.emit(':tell', responseMessage.message);
});
I have no idea what I am doing wrong, I think I am making the HTTP request correctly. I know the skill works without this (simply commenting out the last three lines and replacing with just this.emit(':tell', 'hello') works fine).
Let me explain my below code...Here I have used https request in the "LaunchRequest"
which in turns gives me a response and with that response and I'm making my alexa to speak
note: jsonplaceholder.typicode.com is very useful for testing your https req and response
Simply use this code in your aws online editor console make sure you type the right intent name and invocation name.
exports.handler = (event, context, callback) => {
var speechResult;
switch (event.request.type) {
case "LaunchRequest":
var resultis;
const querystring = require('querystring');
const https = require('https');
var postData = querystring.stringify({
'msg' : 'Hello World!'
});
var options = {
hostname: 'jsonplaceholder.typicode.com',
path: '/posts',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': postData.length
}
};
var req = https.request(options, (res) => {
//console.log('statusCode:', res.statusCode);
//console.log('headers:', res.headers);
res.on('data', (d) => {
//console.log("my data is "+d);
var obj = JSON.parse(d);
var resul = obj.msg;
resultis = JSON.stringify(resul);
context.succeed(generateResponse(buildSpeechletResponse(resultis, true)));
});
});
req.on('error', (e) => {
console.error(e);
});
req.write(postData);
req.end();
break;
case "IntentRequest":
switch (event.request.intent.name) {
case "MyIntent":
var a = "are you ready";
context.succeed(generateResponse(buildSpeechletResponse(a, true)))
break;
}
break;
}
}
//Alexa Speech function
buildSpeechletResponse = (outputText, shouldEndSession) => {
return {
outputSpeech: {
type: "PlainText",
text: outputText
},
shouldEndSession: shouldEndSession
}
}
generateResponse = (speechletResponse) => {
return {
version: "1.0",
response: speechletResponse
}
}
Alexa's official github page has a very thorough documentation on api calls. Check their Cooking list skill documentation it covers all of the get and post requests https://github.com/alexa/alexa-cookbook
and https://github.com/alexa/ main repo for other samples.
You better use a promise version, for example
https://github.com/request/request-promise
To me it looks like
this.emit(':tell', responseMessage.message);
should be
this.emit(':tell', responseMessage);
I can't see any .message in this
var gameResponse = JSON.parse(body);
callbackFunction(gameResponse);

NodeJS data throughput

I've set up a NodeJS server which can be accessed by a client. Every once in a while it's necessary to let the server connect to a second server and feed the information retrieved back to the client.
Connecting to the second server is the easy part, but to be honest I have no idea how to send it back to the client. res.write seems to be forbidden during the connection with the second server.
The connection from the client is handled by handleGetRequest. The connection with the second server starts at http.get.
var http = require('http');
var url = require('url');
var server = http.createServer(function(req, res) {
var url_parsed = url.parse(req.url, true);
if (req.method ==='GET') {
handleGetRequest(res, url_parsed);
} else {
res.end('Method not supported');
}
});
handleGetRequest = function(res, url_parsed) {
if (url_parsed.path == '/secondary') {
var OPTIONS = {
hostname: "localhost",
port: "8900",
path: "/from_primary"
}
http.get(OPTIONS, function(secget) {
resget.on('data', function(chunk) {
// either store 'chunk' for later use or send directly
});
}).on('error', function(e) {
console.log("Error " + e.message);
});
} else {
res.writeHead(404);
}
res.end('Closed');
};
server.listen(8000);
How do I send the chunk from http.request to the client?
I thinks passing the callback to the handleGetRequest will fix this issue:
if (req.method === 'GET') {
handleGetRequest(url_parsed, function (err, response) {
if (err) {
return res.sendStatus(500);
}
res.json(response);
});
} else {
res.end('Method not supported');
}
handleGetRequest = function (url_parsed, callback) {
// OPTIONS ...
http.get(OPTIONS, function(resget) {
var data = '';
resget.on('data', function(chunk) {
data += chunk;
});
resget.on('end', function() {
callback(null, data);
});
}).on('error', function(e) {
callback(e);
});
}
Thanks to #TalgatMedetbekov for the suggestions. I managed to implement it like this:
var http = require('http');
var url = require('url');
var server = http.createServer(function(req, res) {
var url_parsed = url.parse(req.url, true);
if (req.method ==='GET') {
handleGetRequest(res, url_parsed);
} else {
res.end('Method not supported');
}
});
handleGetSecondaryRequest = function(callback, res) {
var OPTIONS = {
hostname: "localhost",
port: "8900",
path: "/from_primary"
}
var data = null;
http.get(OPTIONS, function(func, data) {
func.on('data', function(chunk) {
data += chunk;
});
func.on('end', function() {
callback(res, data);
});
}).on('error', function(e) {
callback(res, e);
})
};
var secReqCallback = function(res, recData)
{
res.write(recData);
res.end("END");
};
handleGetRequest = function(res, url_parsed) {
if (url_parsed.path == '/secondary') {
handleGetSecondaryRequest(secReqCallback, res);
} else {
res.writeHead(404);
}
};
server.listen(8000);
It works, kind of. There's an 'undefined' in front of the string which I can't find the cause for, but the basic functionality works perfect.
The callback construction is necessary to synchronize the asynchronous nature of NodeJS.

Express: npm test returns "connect ECONNREFUSED"

I'm trying to test my app, and it always returns an error of connect ECONNREFUSED. I made a simple example to show what's happening. Here's my controller (CompoundJS code):
load('application');
action('test', function() {
var obj = {success: true, data: 'blah'};
send(obj);
});
action(function show(data) {
var http = require('http');
var options = {
path: '/getTest',
port: process.env.PORT // without this, http fails because default port is 80
};
var req = http.get(options, function(res) {
var data = '';
res.on('data', function(chunk) {
data += chunk;
});
res.on('end', function() {
data = JSON.parse(data);
return send(data);
});
});
req.on('error', function(e) {
return send({success: false, data: e.message}); // returns "connect ECONNREFUSED"
});
});
So when I have the app running, I can hit /test (which is the show method there) and /getTest just fine without any errors. However, when I try to run the following test code, I get the error as stated above, and the issue comes down to that http.get, as I can get into the show function just fine.
var app, compound
, request = require('supertest')
, sinon = require('sinon');
function TestStub() {
return {
};
}
describe('TestController', function() {
beforeEach(function(done) {
app = getApp();
compound = app.compound;
compound.on('ready', function() {
done();
});
});
/*
* GET /tests
* Should render tests/index.ejs
*/
it('should render "index" template on GET /tests', function(done) {
request(app)
.get('/test')
.end(function(err, res) {
console.log(res.body);
done();
});
});
});
Any ideas on how to fix this? Cross posted from the CompoundJS Google Group.

No response after database-access in jugglingdb

I try to use my compound.js-application as a (transparent) proxy-server. When a user tries to request a external website, the application will check, if the user with that ip-address was authenticated before.
If so, the external site will be shown, if not, the user will be encouraged to login.
The problem is, that the response is not processed, when there is an access to the database-object "User".
When I comment out the database section and just use the code inside the anonymous function, the programm works as expected.
action('exturl', function () {
User.all({ where: { ipaddress: req.ip }}, function(err, users) {
if (users.length > 0) {
this.user = user[0];
var proxy = http.createClient(80, req.headers['host'])
var proxy_request = proxy.request(req.method, req.url, req.headers);
proxy_request.addListener('response', function (proxy_response) {
proxy_response.addListener('data', function(chunk) {
res.write(chunk, 'binary');
});
proxy_response.addListener('end', function() {
res.end();
});
res.writeHead(proxy_response.statusCode, proxy_response.headers);
});
req.addListener('data', function(chunk) {
proxy_request.write(chunk, 'binary');
});
req.addListener('end', function() {
proxy_request.end();
});
} else {
redirect(path_to.login);
}
});
});
Is there a failure inside my code? I don't know what I am doing wrong.

how to do Auth in node.js client

I want to get use this rest api with authentication. I'm trying including header but not getting any response. it is throwing an output which it generally throw when there is no authentication. can anyone suggest me some solutions. below is my code
var http = require('http');
var optionsget = {
host : 'localhost', // here only the domain name
port : 1234,
path:'/api/rest/xyz',
headers: {
'Authorization': 'Basic ' + new Buffer('abc'+ ':' + '1234').toString('base64')
} ,
method : 'GET' // do GET
};
console.info('Options prepared:');
console.info(optionsget);
console.info('Do the GET call');
var reqGet = http.request(optionsget, function(res) {
console.log("statusCode: ", res.statusCode);
res.on('data', function(d) {
console.info('GET result:\n');
process.stdout.write(d);
console.info('\n\nCall completed');
});
});
reqGet.end();
reqGet.on('error', function(e) {
console.error(e);
});
The request module will make your life easier. It now includes a Basic Auth as an option so you don't have build the Header yourself.
var request = require('request')
var username = 'fooUsername'
var password = 'fooPassword'
var options = {
url: 'http://localhost:1234/api/res/xyz',
auth: {
user: username,
password: password
}
}
request(options, function (err, res, body) {
if (err) {
console.dir(err)
return
}
console.dir('headers', res.headers)
console.dir('status code', res.statusCode)
console.dir(body)
})
To install request execute npm install -S request
In your comment you ask, "Is there any way that the JSOn I'm getting in the command prompt will come in the UI either by javascript or by Jquery or by any means."
Hey, just return the body to your client:
exports.requestExample = function(req,res){
request(options, function (err, resp, body) {
if (err) {
console.dir(err)
return;
}
// parse method is optional
return res.send(200, JSON.parse(body));
});
};

Resources