nginx

Nginx is an open-soure web server, reverse proxy, load balancer, and web application platform that can be extended by 3rd party modules. OpenResty is web application platform based on nginx and LuaJIT which includes several modules by default.

Installation

On FreeBSD, we can simply build nginx from source, using the ports system. Select the build option LINK in make config to compile nginx with the nginx-link-function module:

# cd /usr/local/ports/www/nginx/
# make config
# make
# make install

Or, if you use packages (and the selected package repository provides an nginx port with LINK enabled) simply run:

# pkg install www/nginx
# pkg info www/nginx

Instead, we can build nginx from source, while including the nginx-link-function module at compile time. At first, we have to download and unpack the source code of the module:

# cd /tmp/
# fetch "https://github.com/Taymindis/nginx-link-function/archive/master.zip"
# unzip master.zip

After we have downloaded the source code of the latest version of nginx, we add nginx-link-function to the Makefile, and then compile and install nginx. For example:

# fetch "https://nginx.org/download/nginx-VERSION.tar.gz"
# tar xzvf nginx-VERSION.tar.gz
# cd nginx-VERSION/
# ./configure --add-module=/tmp/nginx-link-function-master/
# make -j2
# make install
# install -m 644 /tmp/nginx-link-function-master/src/ngx_link_func_module.h /usr/local/include/

We can then start and test the nginx service:

# service nginx start

Example

Fortran web application
Fig. 1: The output of the Fortran web application

The example web application library just returns static HTML content:

! webapp.f90
module webapp
    use, intrinsic :: iso_c_binding
    use :: ngx_link_func
    implicit none
    public :: ngx_hello
    public :: ngx_link_func_exit_cycle
    public :: ngx_link_func_init_cycle

    logical, save :: is_service_on = .false.
contains
    subroutine ngx_hello(ctx) bind(c)
        !! This routine fill be called by nginx, passing in the current request
        !! context.
        character(len=*), parameter :: content = &
            '<!DOCTYPE html>' // &
            '<html lang="en">' // &
            '<head>' // &
            '<meta charset="utf-8">' // &
            '<title>Fortran Web App</title>' // &
            '</head>' // &
            '<body><h1>Hello, from Fortran!</h1></body>' // &
            '</html>'
        type(ngx_link_func_ctx_t), intent(in) :: ctx

        call ngx_link_func_log_info(ctx, 'Sending response ...' // c_null_char)
        call ngx_link_func_write_resp(ctx, &
                                      int(200, kind=8), &
                                      '200 OK' // c_null_char, &
                                      NGX_LINK_FUNC_CONTENT_TYPE_HTML, &
                                      content // c_null_char, &
                                      int(len(content), kind=8))
    end subroutine ngx_hello

    ! void ngx_link_func_init_cycle(ngx_link_func_cycle_t* cyc)
    subroutine ngx_link_func_init_cycle(cyc) bind(c)
        type(ngx_link_func_cycle_t), intent(in) :: cyc

        call ngx_link_func_cyc_log_info(cyc, 'Starting the web app ...' // c_null_char)
        is_service_on = .true.
    end subroutine ngx_link_func_init_cycle

    ! void ngx_link_func_exit_cycle(ngx_link_func_cycle_t* cyc)
    subroutine ngx_link_func_exit_cycle(cyc) bind(c)
        type(ngx_link_func_cycle_t), intent(in) :: cyc

        call ngx_link_func_cyc_log_info(cyc, 'Shutting down the web app ...' // c_null_char)
        is_service_on = .false.
    end subroutine ngx_link_func_exit_cycle
end module webapp

Server Configuration

In the nginx configuration file /usr/local/etc/nginx/nginx.conf, we simply set ngx_link_func_lib to the path of our web application, and add a route that invokes ngx_link_func_call to call the routine ngx_hello inside the shared library:

# Load shared library if module is not linked statically:
load_module "/usr/local/libexec/nginx/ngx_http_link_func_module.so";

http {
    server {
        listen            80;
        server_name       localhost;
        ngx_link_func_lib "/usr/local/etc/nginx/webapp.so";

        location = / {
            ngx_link_func_call "ngx_hello";
        }
    }
}

We can then start the nginx daemon. On FreeBSD, run:

# service nginx restart

Open the URL http://127.0.0.1/ inside your web browser to access the web application (fig. 1).

References