Non-blocking all the way

Text

NOTE: Most of the commands can be copy-and-pasted If any modification is required, is mentioned below.

What is node-http-proxy ?

node-http-proxy is a easy to use and is a configurable proxy server by Nodejitsu . This is a well proven http-proxy server and has support for Web-sockets, HTTPS, secure websockets and can serve both as a reverse or a forward proxy.

It can also act as load balancer and used for virtual host configuration. It also supports connecting middle-ware functions and has plug-ins for most of your needs. Since everything is written in javascript, it has a lot of benefits.

When should you use node-http-proxy ?

node-http-proxy is designed to proxy http request from one server to another but currently can be used for variety of other purposes too.

To elaborate, lets assume you have multiple node.js servers running on different ports on a single machine, but you want to expose only one server. You can setup node-http-proxy and reverse proxy http requests to locally running services which are not exposed to the internet.

Tell me more about node-http-proxy

As mentioned above, node-http-proxy had started as a proxy server but now it has become a battle-hardened product, which is much easier to configure(since configuration files are simple JSON files) and can be used for variety of purposes. It is also used in production at Nodejitsu.

It can handle HTTP, HTTPS, Websocket and Secure Websocket Requests. So It can be very easily used with any modern node.js frameworks like meteor.js, sails.js, geddy.js etc.

INSTALLATION INSTRUCTIONS

Pre-requisites to install nodejs and npm :

sudo apt-get install python-software-properties python g++ make

If you are using Ubuntu 12.10 or later , you will need to do the following as well:

sudo apt-get install software-properties-common

Add the PPA Repository, which is recommended by Joyent (the maintainers of Node.js):

sudo add-apt-repository ppa:chris-lea/node.js

Update the System package list:

sudo apt-get update

Install Node.js including npm:

sudo apt-get install nodejs

cd into into a suitable folder cd desiredfolder

Install node-http-proxy :

sudo npm install http-proxy

Setting Up the server with multiple domains/sub-domain using Proxy-Table

var http = require('http'),
httpProxy = require('http-proxy');

//
// In the options, below replace the 127.0.0.1 by your server's ip and port on which the corresponding server/application is running .
// You can add as many domains/sub-domains as you want in the format given below 
// You need to have that particular domain setup from
// your domain registrar using A records . 

//
var options = {
 hostnameOnly: true,
router: {
'example1.com': '127.0.0.1:9000', 
'example2.net': '127.0.0.1:9001', 
'sub.example1.com': '127.0.0.1:9002'  
    } 
};

//
// 
var proxyServer = httpProxy.createServer(options).listen(80); //This creates the actual server and passes the options

Save the above code in app.js and from the same directory start the application using

node app.js

Although in production , it is recommended to use forever to run the application.

Setting up Location based routing

For location based routes, you need to remove the hostnameOnly attribute of options and then suitably modify the domain name as shown below .

var http = require('http'),
httpProxy = require('http-proxy');

//
// In the options, below replace the 127.0.0.1 by your server's ip and port on which the corresponding server/application is running .
// You can add as many domains/sub-domains as you want in the format given below 
// You need to have that particular domain setup from
// your domain registrar using A records . 

//
var options = {
    router: {
'example1.com/route1': '127.0.0.1:9000', 
'example2.net/route2': '127.0.0.1:9001'
    }
};

//
// 
var proxyServer = httpProxy.createServer(options).listen(80); //This creates the actual server and passes the options 

If you do not care about the domains and want just request path based proxy you can do it easily by modifying the option to below option .

var options = {
    router: {
'/route1': '127.0.0.1:9000', 
'/route2': '127.0.0.1:9001'
    }
};

Proxying to HTTP from HTTPS

It is one of the most commonly-used case. suppose you have some front-facing HTTPS server, and all of your internal traffic is HTTP. In this way, you can reduce the number of servers to which your CA and other important security files are deployed and reduce the computational overhead from HTTPS traffic. You can easily do it in node-http-proxy .

var fs = require('fs'),
    http = require('http'),
    https = require('https'),
    httpProxy = require('http-proxy');

    var options = {
     https: {
        key: fs.readFileSync('path/to/your/key.pem', 'utf8'),
        cert: fs.readFileSync('path/to/your/cert.pem', 'utf8')
        }
    };

//
// Create a standalone HTTPS proxy server
//
httpProxy.createServer(8000, 'localhost', options).listen(8001);//replace 8000 by the target port and localhost by your server ip address

In the above code you can also add the proxy table to add the functionality of multiple sub-domains or for request path based routing but for multiple domains you have to use multiple certificates and you can use Server Name Indication for the purpose as shown below

Proxyfying to HTTPS from HTTPS

This is essentially same as proxyfying HTTPS to HTTP but we have to add a target attribute to the options as shown below .

var fs = require('fs'),
https = require('https'),
httpProxy = require('http-proxy');

var options = {
  https: {
key: fs.readFileSync('path/to/your/key.pem', 'utf8'),
cert: fs.readFileSync('path/to/your/cert.pem', 'utf8')
  },
  target: {
    https: true // This could also be an Object with key and cert properties
    }
};

//
// Create a standalone HTTPS proxy server
//
httpProxy.createServer(8000, 'localhost', options).listen(8001);//replace 8000 by the target port and localhost by your server ip address

Enabling Gzip compression

Using the connect-zip middleware, one can enable Gzip compression . To use a middleware in node-http-proxy , one can add middleware funtion to the createServer call as shown below .

Install connect-gzip(or any other middleware) via npm :

    $ npm install connect-gzip

Now just modify the create server call as shown below :

httpProxy.createServer(
require('connect-gzip').gzip(),
9000, 'localhost'
).listen(8000);

Text

So you have decided to try out Node.js and you have only dealt with client side JavaScript before. Everything in Node.js universe is written in JavaScript* but with slightly different dialect .Its different enough to make you confused and make you wonder if it is really JS you are reading .This article aims to get you familiar to the JavaScript in the Node.js world. Lets start now.

What is Node.js ?

Node.js is often confused with a web framework , a language but in reality it simply is platform built upon Chrome’s Javascript Engine also known as the “v8”.  

Node.js can be used to act as an awesome Web server ,TCP server, Proxy, Streaming server, Voice Mail Server, Realtime Server and even an Awesome Robot Controller .

image

Node.js  should be used for anything that deals with high I/0 (input/output) . Other CPU intensive tasks like Fibonacci calculations should be ideally left with languages like python .

Understanding Node.js execution model

Node.js follows a Non Blocking asynchronous I/O model almost entirely making it ideal for data-intensive real-time applications . lets stop here and first understand what is an asynchronous model and what benefit does it serve in node.js . 

We all have used Asynchronous Javascript before . AJAX stands for Asynchronous Javascript And XML and  yeah its the same technique we are talking here. So when we execute an asynchronous code is run , system doesn’t wait for it to even execute forget about the result , instead it registers a callback function , which is run when the original function has run and has the result . And this callback function magically has the result of the original function , all due to virtue of closure. Lets leave the closure thing for now and for now focus on asynchronous portion. 

So when we use a synchronous function like this one 

var result = db.query(“select * from T”);
// use result

 So until the query is over, in many case the system just waits for it using precious hardware resources . 

Clearly this isn’t an efficient approach in such cases and it’s in these scenarios  when asynchronous code shines and instead of blocking the process , it returns to the event loop instantly and using the result using a callback function which gets called when the original function has finished its execution . 

Asynchronous version of the above problem would be 

db.query(“select  from T”, function (result) {
  // use result
});

 Here result has the values return by the query , which can be explain using closures . You will very soon observe that the same pattern is repeatedly used in node.js world .

Understanding Closures

For those of you who don’t know , JavaScript has a lexical scope . It means that brackets don’t create a new scope .

if(x ===0) {

var b = 9;

}

console.log(b); // this is log 9 not undefined as brackets don’t create scope in JS but function do .

So 

var C = function(){

var d = 7;

};

console.log(d); this will log undefined as variable d is local variable accessible inside only inside the function .

Now we can talk about closures .

Whenever we see a function inside another function,  the inner function
has access to the variables in the outer function .Simply Accessing variables outside of your lexical scope creates a closure .

So in our asynchronous code , the callback function had access to the variables(result) that were present in the the original query function can be simply termed as closure.

Understanding the Callback Pattern

Node.js introduced the following convention:
ReadFile(filename, function (err, content) {
  if (err) {
    // handle error
    return;
  }
  // process file content
});
Currently this style has also its recommendation in: W3C Web API Design Cookbook.  
Lets explain the code above. Readfile is a function that takes two values, first is the filename which it’s supposed to read and the second is a callback anonymous function which will be called when the Readfile function has executed. 
The callback function itself has two variables out of which only one will take a value when it is run. If the original Readfile function ends with a error , the err variable will hold the error and it has to be handled in the code . And Finally if the code has executed successfully, content variable will have the result and then can be used for further manipulation. 
Its a Node.js standard and you will see this pattern getting repeated almost all the time in node.js codes. 
Now you have got hold of the javascript of node.js , you can go ahead with other tutorials and wait for another awesome tutorial by me. 
 

 

This article is part of series of tutorial on Node.js which will compiled into a Creative Common Licensed Book . To get involved in the project send a mail to bhanu423@gmail.com .

Publishing a file to Amazon S3 with a time-sensitive token using Node.js

glynnbird:

If you are publishing data to S3, then it is private by default; only you can access it. You can publish it publicly but what if you want to publish it only to people with a known link AND the link has to expire after predefined time?

Using the knox library, it’s very straightforward:

 var knox...
Source: glynnbird