Redirect to a https url on server rather than sending 3XX in express - node.js

I have a sample http server .
I have a post API which in some scenario have to route to a third party https-server.
Third party server also exposes a post API.
I dont want to send a redirect to client and do this silently on http server.
My application is built using express.
I have tried using request module and tried to use pipe like this .. but request is timing out.
let request = require('request');
console.log(`vishal going here for 300 `);
var pipe = req.pipe(request.post('https url here'));
var response = [];
pipe.on('data', function (chunk) {
response.push(chunk);
});
pipe.on('end', function () {
var res2 = Buffer.concat(response);
console.log(res2);
res.send(res2);
});
Not sure whats missing.
Also how to pass the body and hears to https server request

Related

How to determine http vs https in nodejs / nextjs api handler

In order to properly build my urls in my xml sitemaps and rss feeds I want to determine if the webpage is currently served over http or https, so it also works locally in development.
export default function handler(req, res) {
const host = req.headers.host;
const proto = req.connection.encrypted ? "https" : "http";
//construct url for xml sitemaps
}
With above code however also on Vercel it still shows as being served over http. I would expect it to run as https. Is there a better way to figure out http vs https?
As Next.js api routes run behind a proxy which is offloading to http the protocol is http.
By changing the code to the following I was able to first check at what protocol the proxy runs.
const proto = req.headers["x-forwarded-proto"];
However this will break the thing in development where you are not running behind a proxy, or a different way of deploying the solution that might also not involve a proxy. To support both use cases I eventually ended up with the following code.
const proto =
req.headers["x-forwarded-proto"] || req.connection.encrypted
? "https"
: "http";
Whenever the x-forwarded-proto header is not present (undefined) we fall back to req.connection.encrypted to determine if we should serve on http vs https.
Now it works on localhost as well a Vercel deployment.
my solution:
export const getServerSideProps: GetServerSideProps = async (context: any) => {
// Fetch data from external API
const reqUrl = context.req.headers["referer"];
const url = new URL(reqUrl);
console.log('====================================');
console.log(url.protocol); // http
console.log('====================================');
// const res = await fetch(`${origin}/api/projets`)
// const data = await res.json()
// Pass data to the page via props
return { props: { data } }
}

NodeJS express framework reads the same event multiple times

I'm working with a service (WSO2CEP) that sends events to a node js program that I developed, let's call it receiver.js, and then it stores these events in a mongo db. The comunication between WSO2CEP and receiver.js is done through a HTTP connection. The problem I'm facing on is that when the WSO2 sends an event, the receiver.js caputres it and stores it in the db, and after a few seconds/minutes, it detects that a new events has arrived, which is not true, and stores it again in the db. This second event is identical to the first one.
When I saw that I thought that the problem was that the WSO2 was sending the same event multiple times, but I've debug it an I'm 100% sure that only one events is being sent, so the problem seems to be the HTTP connection.
The HTTP connection is being handled by the receiver.js acting as a server and WSO2 as a client, which sends the events through HTTP post request. The http server implementation in receiver.js is done with the "express" framework. As it can be seen in below code chunk.
'use strict';
const express = require('express');
const bodyParser = require('body-parser');
const EventEmitter = require('events');
const port = Whatever;
module.exports = class WSO2Server extends EventEmitter {
constructor () {
super();
const app = express();
app.use(bodyParser.json()); // to support JSON-encoded bodies
app.route('/Whatever').post( (req, res) => {
let event = req.body;
this.emit('event', event);
});
this.server = app.listen(port);
}
destroy () {
this.server.close();
}
}
I suspect that the events are being stored in a queu (or similar) and are being retransmitted every so often. Any idea about that? Thank you
Looking at your code, I can't see you using the response object at all. After you've called this.emit('event', event); you should call something like res.status(201).end(); which will dispatch a HTTP Status 201 back to the calling client.
Because you're not setting any information on the response object, your application is hanging and not making a response to the HTTP call. Thus something like nginx or apache is re-issuing the request to your application after a specific timeout.
If you explicitly create the response with something res.status(201).end(); then your request will end correctly and a duplicate call will not be made.

Handling inbound Twilio messages using node.js

I'm reading through portions of the Twilio documentation (https://www.twilio.com/help/faq/why-does-my-twilio-number-respond-with-thanks-for-the-message-configure-your-numbers-sms-url-to-change-this-message) pertinent to SMS messaging responses, and am trying to build a node.js app which will allow me to respond to inbound SMS messages with programmatic responses.
I've been trying to emulate this SO post which deals with a similar problem (How can I respond to incoming Twilio calls and SMS messages using node.js?) and have the following code:
var AUTH_TOKEN = "*********************";
var twilio = require('twilio');
var express = require('express');
var http = require('http');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded());
app.post('/welcome/sms/reply/', function(req, res) {
//Validate that this request really came from Twilio...
if (twilio.validateExpressRequest(req, AUTH_TOKEN)) {
var twiml = new twilio.TwimlResponse();
twiml.say('Hi! Thanks for checking out my app!');
res.type('text/xml');
res.send(twiml.toString());
}
else {
res.send('you are not twilio. Buzz off.');
}
});
http.createServer(app).listen(3000);
Calling the POST request /welcome/sms/reply through a REST client yields the else statement, and I'm not sure why since the AUTH_TOKEN is exactly what I have in my account dashboard.
Twilio developer evangelist here.
If you're trying to call your own endpoint there using a REST client and you are validating requests (twilio.validateExpressRequest) then you will need to construct your request the same as Twilio does. Crucially this includes a X-Twilio-Signature header, read more at that link for more details.
If you test your code with Twilio, it should work and be a valid request.
See this post for reference in incorporating ngrok + Express. https://www.twilio.com/blog/2015/09/monitoring-call-progress-events-with-node-js-and-express.html

NodeJS respond to http.ServerResponse via stream

I'm currently experimenting with NodeJS streams and had a deeper look into the http.ServerResponse object that's being created upon every http request of the http.createServer request handler.
What I'm now trying to do is having the exact same API of the http.ServerResponse object in a different process connected via another arbitrary method (for instance using Streams) and pipe all output of this object (including headers!) to the actual request, like the following:
-[http]-> server1 -[stream]-> server2 -[stream]-> server1 -[http]->
I've tried a couple of variants, like the following (only local) example:
var http = require('http');
var net = require('net');
var through = require('through');
var StreamWrap = require('_stream_wrap').StreamWrap;
http.createServer(function(req, _res) {
var resStream = through();
resStream.pipe(_res.socket);
resStream.__proto__.cork = function() {};
resStream.__proto__.uncork = function() {};
var resSocket = new StreamWrap(resStream);
var res = new http.ServerResponse(req);
res.assignSocket(resSocket);
res.writeHead(201, {'Content-Type': 'text/plain'});
res.write('hello');
res.end();
}).listen(8000, function() {
console.log("Server listening");
});
which should essentially send the raw HTTP message to the underlying socket (or not?), but for some reason I'm getting a Segmentation fault: 11 - I'm also not sure whether I'm using the StreamWrap object correctly. But I think that this is not an optimal solution as the ServerResponse object handles a lot of things with regards to the socket internally.
So what would be the best way to tackle this?
If I'm piping directly to the response object, this results only in writing to the HTTP body (see also this answer), and I'm loosing the header information. So would it be best to separate header and body and then transfer them separately? How do I know when the headers are being set final on the ServerResponse object, and when the data starts (apart from other options such as trailing headers)?
Another option would be to remotely call methods on the ServerResponse Object i.e. via dnode, but isn't there a better way to do this? I would really love to be able to use Express for instance on the remotely connected server, that's why I want to keep the http.ServerResponse API.
I'm glad for any input!
Thanks!

how to inspect requests response proxied through node.js

I am trying to use node.js to setup a simple proxy server. The idea behind that is to get all web services calls made to one web service go through a node.js proxy in order to easily inspect and debug web service calls.
In order to do that, I am trying to use the following code to proxy the requests:
var
url = require('url'),
http = require('http'),
acceptor = http.createServer().listen(8008);
acceptor.on('request', function(request, response) {
console.log('request ' + request.url);
request.pause();
var options = url.parse(request.url);
options.headers = request.headers;
options.method = request.method;
options.agent = false;
var connector = http.request(options, function(serverResponse) {
serverResponse.pause();
response.writeHeader(serverResponse.statusCode, serverResponse.headers);
serverResponse.pipe(response);
serverResponse.resume();
});
request.pipe(connector);
request.resume();
});
But I can't figure out where to inspect / dump to file the response. With node-inspector, I was looking at the response object at line: serverResponse.pipe(response); but the body of the response is not yet available.
I found the following question node.js proxied request body but it is written in CoffeeScript.
The idea is write your own 'data' handler and don't use pipe().
You cannot eavesdrop on the data once you piped the stream.

Resources