SVR.JS can now do SCGI!

SVR.JS can now do SCGI!

Published on: August 11, 2023

We have previously made SVR.JS run PHP-CGI and WordPress. Now SVR.JS - a web server software running on Node.JS can connect to SCGI (Simple Common Gateway Interface) servers. We have developed a new mod to do that, OrangeCircle (SCGI client written in JavaScript running on SVR.JS). SCGI (Simple Common Gateway Interface) is a protocol to interface web applications with HTTP servers, which is an alternative to CGI. It is similar to FastCGI, but it is easier to parse and implement. SCGI doesn't have interpreter invoking overhead, unlike CGI. This post will instruct you, how to set up SCGI web applications on SVR.JS.

Setting up SCGI on server-side

First of all, download and install SVR.JS web server. You can also use create-svrjs-server tool or SVR.JS installer to install SVR.JS.

After setting up SVR.JS, download and install OrangeCircle to mods directory.

After installing OrangeCircle SCGI client, create orangecircle-config.json file in SVR.JS installation directory, and configure it like this:

{
  "path": "/helloworld",
  "host": "127.0.0.1",
  "port": 4000
}

Adjust your mount path, SCGI server host and port settings according to your needs.

After setting up and configuring SCGI client, run SVR.JS using node svr.js or bun run svr.js and visit SCGI page (for example http://localhost/helloworld). You will then see this error page: This is because we didn't set up SCGI server yet. But we have set up SCGI client! We need to just set up SCGI server...

503 Service Unavailable page displayed when trying to connect to SCGI server

503 Service Unavailable page displayed when trying to connect to SCGI server

Setting up SCGI server

To set up SCGI server, first create scgi-server directory outside SVR.JS installation directory, and change your working directory to new one. Then install SCGI server module using npm install scgi-server (scgi-server package is deprecated; we're using it just for example SCGI application) command. After installing SCGI server module, create index.js file with those contents:

var SCGIServer = require('scgi-server');

var server = SCGIServer(4000);
server.on('request', function(error, socket, headers, data) {
    if (error) {
        console.error("received invalid scgi request");
        return;
    }
    socket.write("Status: 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n");
    socket.write("<h1>Hello, World!</h1>");
    socket.end();
});

This SCGI server will send "Hello World" message to the web server, which will send it to your web browser. Run it using node index.js or bun run index.js.

If you see this error:

/home/ubuntu/scgi-server/index.js:4  
server.on('request', function(error, socket, headers, data) {  
       ^  
  
TypeError: server.on is not a function  
    at Object.<anonymous> (/home/ubuntu/scgi-server/index.js:4:8)  
    at Module._compile (internal/modules/cjs/loader.js:778:30)  
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)  
    at Module.load (internal/modules/cjs/loader.js:653:32)  
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)  
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)  
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)  
    at startup (internal/bootstrap/node.js:283:19)  
    at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)

Then open node_modules/scgi-server/index.js file and replace this line:

var self = this  
EventEmitter.call(this)

with this one:

var self = new EventEmitter()

Restart the SCGI server, and the error shoudn't occur again.

After starting up SCGI server, visit SCGI page again, and you'll see "Hello World" message:

SCGI "Hello World"

SCGI "Hello World"

We have finally set up SCGI!

SCGI is language-indepedent web application protocol, so you can write SCGI server in JavaScript (Node.JS; scgi-server module, deprecated), Python (scgi module), Perl (SCGI package), PHP (see this gist) and many more programming languages!