nginx
nginx is an open-soure web server, reverse proxy, load balancer, and web application platform that can be extended through 3rd party modules. OpenResty is web application platform based on nginx and LuaJIT that includes several modules by default.
The nginx-link-function module provides an API to dynamically link nginx against a web application within the server context and to forward requests to functions in such an application. The Fortran 2003 interface library fortran-nginx includes bindings to the C API.
The Fortran application has to be compiled to a shared libary. Once a route is defined in the nginx configuration, the desired function is called on each request, and the response returned to the client.
Installation
On FreeBSD, we can build nginx from the ports collection. Select the build
option LINK
to enable the nginx-link-function module:
# cd /usr/local/ports/www/nginx/
# make config
# make
# make install
Or, if you prefer packages over ports, and the chosen package repository
provides an nginx package that has been built with LINK
, run
instead:
# pkg install www/nginx
# pkg info www/nginx | grep LINK
On all other platforms, we either compile nginx from source and include the
nginx-link-function module at compile time, or build the module
independendly as a shared library to be loaded through the nginx configuration
file at run time (load_module
). For a static library, we first
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
Then, download the
source code of the latest version
of nginx (≥ v1.21.0), add the nginx-link-function module as an
argument to the configure
script, compile, and finally 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 -j 2
# make install
# install -m 644 /tmp/nginx-link-function-master/src/ngx_link_func_module.h /usr/local/include/
In the install step, you may have to change the path
/usr/local/include/
to your system’s include directory, such as
/usr/include/
on Linux. On FreeBSD, the nginx daemon is started
with:
# service nginx start
fortran-nginx
In order to interact with the nginx-link-function module from Fortran, we need to link the fortran-nginx library that provides the requires ISO C binding interfaces. Clone the repository and execute the Makefile:
$ git clone https://github.com/interkosmos/fortran-nginx
$ cd fortran-nginx/
$ make
The Makefile will create a static library libfortran-nginx.a
,
we link our web application against statically.
Example
- Fig. 1: The output of the Fortran web application
The example web application library just returns a static HTML document. The
implementation of the routines ngx_link_func_init_cycle()
and
ngx_link_func_exit_cycle()
is mandatory. All routines callable
from outside must have the bind(c)
attribute.
! webapp.f90
module webapp
use, intrinsic :: iso_c_binding
use :: ngx_link_func
implicit none
character(len=*), parameter :: HEADER = '<!DOCTYPE html>' // &
'<html lang="en">' // &
'<head>' // &
'<meta charset="utf-8">' // &
'<title>Fortran Web App</title>' // &
'</head>' // &
'<body bgcolor="#f5f5dc">'
character(len=*), parameter :: FOOTER = '</body></html>'
logical, save :: is_service_on = .false.
public :: ngx_hello
public :: ngx_link_func_exit_cycle
public :: ngx_link_func_init_cycle
contains
subroutine ngx_hello(ctx) bind(c)
!! This routine fill be called by nginx, passing in the current request context.
use, intrinsic :: iso_fortran_env, only: compiler_options, compiler_version
type(ngx_link_func_ctx_t), intent(in) :: ctx
character(len=:), allocatable :: response
character(len=19) :: date
integer :: dt(8)
call date_and_time(values=dt)
write (date, '(i4, 5(a, i2.2))') dt(1), '/', dt(2), '/', dt(3), ' ', &
dt(5), ':', dt(6), ':', dt(7)
response = HEADER // &
'<h1>Hello, from Fortran!</h1>' // &
'<p>' // date // '<br>' // &
'Compiler: ' // compiler_version() // '<br>' // &
'Options: ' // compiler_options() // '</p>' // &
FOOTER
call ngx_link_func_log_info(ctx, 'Sending response ...' // c_null_char)
call ngx_link_func_write_resp(ctx, &
200_c_intptr_t, &
'200 OK' // c_null_char, &
NGX_LINK_FUNC_CONTENT_TYPE_HTML, &
response, &
len(response, kind=c_size_t))
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
Compile the shared library webapp.so
with:
$ gfortran13 -shared -fPIC -o webapp.so webapp.f90 libfortran-nginx.a
The library has to be copied to a directory nginx has access to, for
instance, /usr/local/etc/nginx/
, and added to the nginx
configuration file.
Server Configuration
In the nginx configuration file /usr/local/etc/nginx/nginx.conf
(FreeBSD), we 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
webapp.so
:
# 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 are now ready to 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).
Fortran Libraries
- fortran-nginx: Fortran 2003 interface bindings to nginx-link-function
References
- nginx: Official website
- OpenResty: Web platform based on nginx and LuaJIT
- nginx-link-function: 3rd party module for dynamic linking of applications in nginx server context
< FastCGI | [Index] | SQLite > |