Node.js HTTP Request to send OSC message - javascript

I am new to Node.js and am wondering if anyone has an idea on how I'd go about making a program that sends an OSC message when someone makes an HTTP request to my server?
I have a simple program running right now that when you run it it sends an OSC message, how might I expand it so this message gets sent anytime a certain HTTP request is made?
var osc = require('node-osc');
var client = new osc.Client('127.0.0.1', 3333);
client.send('/1', 1);
Thanks

To receive HTTP requests, you need an HTTP server. Node has a built-in HTTP server. To handle simple routing, I usually go straight for Express which sets up a nice middleware stack and some other helpful bits as you build out your application. From the documentation:
var express = require('express');
var app = express();
app.get('/', function(req, res){
res.send('hello world');
});
app.listen(3000);
Now, what I would do is set up a specific endpoint for OSC messages:
app.all('/osc', functin (req, res) {
oscClient.send('/1', 1);
}
You can add parameters and what not if you want Express to handle that for you in the URL, or you can get at the query string or POST data directly from the req object.

Related

Node.js Proxy Server on Localhost Always Returns Empty Response

I've been working on a personal project lately, and it involves intercepting any HTTP/S requests coming from my PC to external servers (that includes requesting through browsers, curl, etc.) and sometimes redirecting requests to a personal page depending on the requested hostname.
In order to get a proof-of-concept for intercepting and forwarding requests, I built a quick HTTPS proxy server in Node.js. It shouldn't really do anything other than printing some information about each request and forwarding it to where it was supposed to go.
Here's the main part of it:
var https = require('https');
var httpProxy = require('http-proxy');
var fs = require('fs');
var path = require('path');
const options = {
ssl: {
key: fs.readFileSync(path.resolve(__dirname, './mycert.key'), 'utf8'),
cert: fs.readFileSync(path.resolve(__dirname, './mycert.crt'), 'utf8')
},
secure: false,
toProxy: true
}
const proxy = httpProxy.createProxyServer(options);
const httpsServer = https.createServer(options.ssl, (req, res) => {
console.log("WEBSERVER")
console.log(req.headers.host);
proxy.web(req, res, {
target: req.headers.host,
})
})
const httpsListener = httpsServer.listen(8080);
console.log("LISTENING ON 8080")
Problem is, whenever I turn my Windows proxy settings to go to my new server, any request made through a browser just gives me an ERR_EMPTY_RESPONSE, and nothing gets printed out in the console where I run the proxy.
If I do an HTTPS request directly to the proxy it does print what I need out, but obviously doesn't take me anywhere.
Any ideas about what I should try? To be honest, I'm not sure if it is even possible to make a "localhost" proxy server, so I might be completely off track :/.
Thanks!

Accessing the database API directly with client-side JS

I need to build a simple web front-end which will be mostly used to plot some data fetched from a database. The database (namely, InfluxDB) exposes a HTML API which I could just conveniently call directly from my Javascript front-end. I'm putting login service in front of it (AWS Cognito).
However, once a user logs in, they can easily discover my API endpoints in the client-side code, and therefore make arbitrary queries and possibly abuse it or just steal all my data. How can I avoid it? Is it possible to somehow make the API accessible only to the app's front-end? If not, what is the best practice I should follow here?
I'd suggest maybe creating a Node.js based webservice that would wrap your REST API. Using the Express module it's only a few lines to put together a simple REST service and call out to other APIs.
const request = require('request');
const express = require('express');
const app = express();
app.get("/test", function(req, res, next){
res.status(200).send('Hello World');
});
app.get("/testapi", function(req, res, next){
// Read from another API and return result...
var options = {
url: "https://httpbin.org/ip",
method: "get"
};
request(options, function (error, response, body) {
if (error) {
console.error('error:', error);
res.status(500).send(error.message);
} else {
res.status(200).send(body);
}
});
});
let port = process.env.PORT || 3000;
app.listen(port);
console.log(`Express listening on ${port}..`);
If your InfluxDB is also running on EC2, the fastest and safest approach would be to only allow your web application access to the influxdb instance by limiting it in the security group.
Image that your webapp is running on the default VPC with CIDR 172.31.0.0/16 and that influxdb is running on port 8086. Then simply create a security group with an INBOUND rule that port 8086 can only be reached from inside your AWS account (So IP 172.31.0.0/16) and attach it to your Influx EC2 instance. make sure other inbound rules allowing access to 0.0.0.0/0 are removed.

Keep Node JS connection opened and write (GET Request)

I was trying to implement a NODE JS get method where I could encode in the url parameters and send back responses like in Server Sent Events.
For example, when I used:
curl -D- 'http://localhost:8030/update'
The server would return a message, and then keep the connection opened to return more messages (like Push).
I was using require('connect'), I tried with require('express') but can't get it working.
Here's part of my code:
var http = require('http');
var connect = require('express');
var app = connect();
app.use(bodyParser.urlencoded({ extended: false }))
.use(bodyParser.json()) // JSON
.use(cors(corsOpts))
.get('/update', updateMiddleware);
var server = http.createServer(app);
server.listen("twserver.alunos.dcc.fc.up.pt", 8030);
function updateMiddleware(req, res) {
res.setHeader('Connection', 'keep-alive');
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.writeHead(200);
setTimeout(function() {
res.write("this is an event");
res.flushHeaders();
}, 1000);
setTimeout(function() {
res.write("this is another event");
}, 2000);
// should print without ending
}
EDIT: I found it was working, but only in chrome. In terminal, I only receive it after waiting a long time, and messages come like in chunks.
You can't use a single HTTP request to listen for multiple event data. If you are really stuck with HTTP (i.e. WebSocket or WebRTC is not an option) then the technique you are looking for is called long polling. This basically works this way:
Client sends request to server
Server waits until an event happens (or until a specific but not too long timeout, so the client application does not throw a timeout error for the request)
Server responses with a complete http response, containing the details of the event
Client receives the event details and immediately sends another request to listen to further events.
This method really takes advantage of HTTP Keep-Alive
EDIT:
For me it looks like your code does not follow the protocol of server sent events. Here is a tutorial: Server-Sent Events in nodejs.
Following another tutorial on MDN about Server-Sent Events, the structure of the messages should be the following:
: this is a test stream
data: some text
data: another message
data: with two lines
Note that the data to be sent must be followed by a double new-line \n\n.
In general, http endpoints in Express aren't supposed to do things like that. If you want live event data, the best way is to use a web socket.
That being said, this thread has an example on how to force Express to do this.
socket.io or Webrtc is the best choice

Using Express.JS to consume an API

var express = require('express');
var app = express();
var path = require('path');
var api = require('./api');
app.get('/', function(req, res){
res.sendFile(path.join(__dirname + '/index.html'));
})
app.listen(8080)
console.log('Server Running');
I know that we are requiring the express module. We are using the express function, we are requiring the module path and storing the reference in variable path and doing the same with api but beyond that I am a little lost. If I wanted to connect to twitter API how would I go about doing this? Can someone please explain the logic behind it so i can go learn this better and apply it by myself with different API's? I sincerely and greatly appreciate all of your help!
Express is a framework for organising your web application server. You open up certain API's routes to listen on the path and respond to the requests when necessary.
You can open API's only for internal use, i.e. calls from the browser running your app. Or you can expose your API to outer world (for example twitter API is doing that).
To connect to twitter API you need to make an outgoing request from your webserver. There are many ways to go about that, starting from native nodeJS package http https://nodejs.org/api/http.html to much more popular alternative request https://github.com/request/request
One thing to note here is that NodeJS web server are in general less restrictive than other language servers, especially when it comes to organising your app and code architecture. Hence more issues for beginners. Feel free to ask more questions.
Main purpose of app in
var app = express()
is to listen to routes (it is as well used to render pages, adding middleware etc.) and only that.
So assume u have a button on your UI which allows you to connect to twitter API. So on the click you make a GET request to your own server, to /api/twitter/connect .
On your server you listen on this path as follows:
var request = require('request'); //assuming you installed this module
app.get('/api/twitter/connect', function(req, res){
request(TWITTER_API_URL + API_KEYS, function(err, body){
res.json(body); //res is the response object, and it passes info back to client side
});
});
You can use "request" package to send requests. But in case of Cross-Origin-Request you must use "HTTPS" instead of "HTTP". You can configure Your request according to your request type like this..
//Load the request module
var request = require('request');
//Lets configure and request
request({
url: 'https://example.com/abc/demo', //URL to hit
qs: {from: 'example', time: +new Date()}, //Query string data
method: 'GET', // specify the request type
headers: { // speciyfy the headers
'Content-Type': 'MyContentType',
'Custom-Header': 'Custom Value'
},
body: 'Hello Hello! String body!' //Set the body as a string
}, function(error, response, body){
if(error) {
console.log(error);
} else {
console.log(response.statusCode, body);
}
});
Besides this there are others way to do the same. And for twitter you can also checkout the module called "twitter"

Sending http POST request to local nodejs Server

I am trying to find a way to send an Http POST with an array of latency data from a client's html page to the node server on localhost.
So far examples I have found instead show only how to set up the GET/POST request on the server side but not how to send POST request from the client to server.
I have no experience in with http requests so any advice or references anyone recommends?
Just need a push in the right direction :]
My node server needs to be able to receive that array from the client. Here's my server code
var http = require('http')
, connect = require('connect')
, io = require('socket.io');
var app = connect().use(connect.static(__dirname)).use(connect.directory(__dirname));
var server = http.createServer(app);
server.listen(8888);
io = io.listen(server);

Categories