Creating a (S)CGI app with D

Tagged: dlang, web

Published: Nov 21, 2019

I’m going to use ars.d D library suite to create an old-school style “CGI” application.

First checkout ars.d library (boost licensed):

git clone https://github.com/adamdruppe/arsd.git

Create app.d inside the arsd directory with a “hello world” program.

// (directly from the `ars.d` documentation)
import arsd.cgi;

// Instead of writing your own main(), you should write a function
// that takes a Cgi param, and use mixin GenericMain
// for maximum compatibility with different web servers.
void hello(Cgi cgi) {
    cgi.setResponseContentType("text/plain");

    if("name" in cgi.get)
        cgi.write("Hello, " ~ cgi.get["name"]);
    else
        cgi.write("Hello, world!");
}

mixin GenericMain!hello;

We compile this program with

dmd app.d cgi.d -version=scgi

We use the scgi option so that we can use it like any other app server fronted by Nginx. As you can notice this is quite spartan in approach. No build system, no library dependencies.

I ran into a problem getting the program to compile on a small VM (just 512 MB RAM). So, I followed the instructions here to turn on swap.

$ fallocate -l 1G swapfile
$ chmod 600 swapfile
$ sudo chown root:root swapfile
$ mkswap swapfile
$ sudo swapon swapfile

… and retry compiling again – dmd app.d cgi.d -version=scgi, and it works this time.

We can test this web application in the shell like this:

pradeep@vm:~/arsd$ ./app GET
Cache-Control: private, no-cache="set-cookie"
Expires: 0
Pragma: no-cache
Content-Type: text/plain

Hello, world!

We will run this application on port 8085 ( ./app --port=8085 ) and put nginx in front of it:

server {
    server_name example.com;
    location / {
        include /etc/nginx/scgi_params;
        scgi_pass localhost:8085;
    }
}

Visit http://example.com to see the "Hello, world!" message.

I will look into vibe.d next.