Modules in Depth

NGINX modules act as either handlers, filters or load-balancers

Components

Config Structs

Modules define up to three configuration structs, each for the main, server and location contexts of the nginx.conf file. The calling conventions for these are ngx_http_(main|srv|loc)_conf_t.

For example, if we were to write a module targeting the server context we would instead use ngx_http_X_srv_conf_t.

typedef struct {
    ngx_uint_t  methods;
    ngx_flag_t  create_full_put_path;
    ngx_uint_t  access;
} ngx_http_hello_world_loc_conf_t;

The C struct above shows a few NGINX data types that serve as wrappers to the common primitive types of the C language.

Directives

Module directives populate the elements in the configuration structs and are called directly from the appropriate context of the configuration file. The structure is an array of commands. The exact definition ngx_command_t can be found core/ngx_conf_file.h.

This structure is where we would configure whether the directives take any arguments or have restricted access to specific contexts.

static ngx_command_t  ngx_http_hello_world_commands[] = {
    { 
      ngx_string("hello_world"), /* directive */
      NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS, /* location context and takes no arguments*/
      ngx_http_hello_world_commands_set_method, /* configuration setup function */
      NGX_RS_HTTP_LOC_CONF_OFFSET,
      0, /* No offset when storing the module configuration on the struct. */
      NULL
    },
      ...
    ngx_null_command // termination
};

In my opinion, Rust wins in readability however I'll leave it for the reader to decide.

Context

The module context will house references to functions that create configurations for the module e.g. pre and post-configuration and merge them.

static ngx_http_module_t ngx_http_hello_world_module_ctx = {
    NULL, /* preconfiguration */
    NULL, /* postconfiguration */
    NULL, /* create main configuration */
    NULL, /* init main configuration */
    NULL, /* create server configuration */
    NULL, /* merge server configuration */
    NULL, /* create location configuration */
    NULL /* merge location configuration */
};

Definition

A module's definition struct glues together the context and directives in one place. Additionally, we can also configure process-level functionality at either the life or death of the thread/process.

ngx_module_t ngx_http_hello_world_module = {
    NGX_MODULE_V1,
    &ngx_http_hello_world_module_ctx, /* module context */
    ngx_http_hello_world_commands, /* module directives */
    NGX_HTTP_MODULE, /* module type */
    NULL, /* init master */
    NULL, /* init module */
    NULL, /* init process */
    NULL, /* init thread */
    NULL, /* exit thread */
    NULL, /* exit process */
    NULL, /* exit master */
    NGX_MODULE_V1_PADDING
};

Last updated