NginxNginx
ModuleModule
DevelopmentDevelopment
Marian MarinovMarian Marinov
mm@siteground.commm@siteground.com
Chief System ArchitectChief System Architect
Head of the DevOps departmentHead of the DevOps department
Static vs. Dynamic modulesStatic vs. Dynamic modules
● Static modules:
– built-in
– can not be disabled
– take memory
Static vs. Dynamic modulesStatic vs. Dynamic modules
● Dynamic modules:
– can be build after Nginx is in production
– can be loaded or disabled by configuration
– when disabled, they are not loaded into memory
– they are loaded using standard dlopen on every
reread of the configuration
Static vs. Dynamic modulesStatic vs. Dynamic modules
● Dynamic modules:
– can be build after Nginx is in production
– can be loaded or disabled by configuration
– when disabled, they are not loaded into memory
– they are loaded using standard dlopen on every reread
of the configuration
load_module modules/<MODULE-NAME>.so;
How you can enable How you can enable 
third­party modules?third­party modules?
./configure --with-compat 
--add-module=/path/to/ngx-module
./configure --with-compat 
--add-dynamic-module=/path/to/ngx-
module
A brief overview of A brief overview of 
Nginx request handlingNginx request handling
● first checks the most specific prefix regardless of
listed order
● last resort is the / location
● then regular expressions in order listed in the
configuration
– first match stops the checks
● if no RE location is matched, then nginx falls
back to the most specific prefix found earlier
●
Types of modules in NginxTypes of modules in Nginx
● Handlers
● Load Balancers
● Filters
Types of modules in NginxTypes of modules in Nginx
● Handlers
● Load Balancers
● Filters
● How are the modules ordered?
Let's begin our dev workLet's begin our dev work
● config file
● ngx_http_hello_module.c file
Let's begin our dev workLet's begin our dev work
config:
ngx_addon_name=ngx_http_hello_module
HTTP_MODULES="$HTTP_MODULES
ngx_http_hello_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS
$ngx_addon_dir/ngx_http_hello_module.c"
NGX_ADDON_DEPS="$NGX_ADDON_DEPS
$ngx_addon_dir/ngx_http_hello_module.h"
Let's begin our dev workLet's begin our dev work
ngx_http_hello_module.c:
every module should include these:
#include <ngx_config.h>
#include <ngx_core.h>
Let's begin our dev workLet's begin our dev work
ngx_http_hello_module.c:
Depending on the type of module, you should also
include:
- for http modules #include “ngx_http.h”
- for mail modules #include “ngx_mail.h”
- for stream modules
#include “ngx_stream.h”
Before we continue...Before we continue...
let's look at one example let's look at one example 
modulemodule
Common return codesCommon return codes
● NGX_OK — Operation succeeded
● NGX_ERROR — Operation failed
● NGX_AGAIN — Operation incomplete; call the function
again.
● NGX_DECLINED — Operation rejected, for example,
because it is disabled in the configuration. This
is never an error.
● NGX_BUSY — Resource is not available.
● NGX_DONE — Operation complete or continued
elsewhere
● NGX_ABORT — Function was aborted. Also used as an
alternative error code.
Components of the moduleComponents of the module
● Configuration structures
● Directives
● Context
● Module definition
● Handler function
Configuration structuresConfiguration structures
● Different configuration context
– main
● ngx_http_<module>_main_conf_t
– server
● ngx_http_<module>_server_conf_t
– location
● ngx_http_<module>_location_conf_t
Module directivesModule directives
static ngx_command_t ngx_http_hello_commands[] =
{
{ ngx_string("hello"),
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_hello_loc_conf_t, name),
&ngx_http_hello_p },
ngx_null_command
};
Module directivesModule directives
NGX_HTTP_MAIN_CONF - should be used in main section
NGX_HTTP_SRV_CONF - should be used in server section
NGX_HTTP_LOC_CONF - should be used in location
section
NGX_HTTP_UPS_CONF - should be used in upstream
section
NGX_CONF_NOARGS - no arguments
NGX_CONF_TAKE1 - 1 argument
NGX_CONF_TAKE2 - 2 arguments
....
NGX_CONF_TAKE7 - 7 arguments
Module directivesModule directives
NGX_CONF_TAKE12 - 1 or 2 arguments
NGX_CONF_TAKE13 - 1 or 3 arguments
NGX_CONF_TAKE23 - 2 or 3 arguments
NGX_CONF_TAKE123 - 1, 2 or 3 arguments
NGX_CONF_TAKE1234 - 1, 2, 3 or 4 arguments
NGX_CONF_FLAG - "on" or "off"
NGX_CONF_1MORE - one or more arguments
NGX_CONF_2MORE - two or more arguments
definitions: src/core/ngx_conf_file.h
Module directivesModule directives
static ngx_command_t ngx_http_hello_commands[] =
{
{ ngx_string("hello"),
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_hello_loc_conf_t, name),
&ngx_http_hello_p },
ngx_null_command
};
Module directivesModule directives
ngx_conf_set_flag_slot ngx_conf_set_off_slot
ngx_conf_set_str_slot ngx_conf_set_num_slot
ngx_conf_set_msec_slot ngx_conf_set_sec_slot
ngx_conf_set_bufs_slot ngx_conf_set_size_slot
ngx_conf_set_enum_slot ngx_conf_set_keyval_slot
ngx_conf_set_bitmask_slot
ngx_conf_set_str_array_slot
Module directivesModule directives
static ngx_command_t ngx_http_hello_commands[] =
{
{ ngx_string("hello"),
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_hello_loc_conf_t, name),
&ngx_http_hello_p },
ngx_null_command
};
Module directivesModule directives
static ngx_command_t ngx_http_hello_commands[] =
{
{ ngx_string("hello"),
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_hello_loc_conf_t, name),
&ngx_http_hello_p },
ngx_null_command
};
Module directivesModule directives
static ngx_command_t ngx_http_hello_commands[] =
{
{ ngx_string("hello"),
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_hello_loc_conf_t, name),
&ngx_http_hello_p },
ngx_null_command
};
Module directivesModule directives
ngx_http_hello_commands[] = {
...
&ngx_http_hello_p },
...
static ngx_conf_post_handler_pt
ngx_http_hello_p = ngx_http_hello;
Module contextModule context
● Pre configuration
● Post configuration
● Creating the main conf
● Initializing the main conf
● Creating the server conf
● Merging it with the main conf
● Creating the location conf
● Merging it with the server conf
Module definitionModule definition
ngx_module_t ngx_http_hello_module = {
NGX_MODULE_V1,
&ngx_http_hello_module_ctx, // module context
ngx_http_hello_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 };
The handler functionThe handler function
static char * ngx_http_hello(ngx_conf_t *cf, void *post,
void *data) {
ngx_http_core_loc_conf_t *clcf;
clcf = ngx_http_conf_get_module_loc_conf(cf,
ngx_http_core_module);
clcf->handler = ngx_http_hello_handler;
ngx_str_t *name = data; // i.e., first field of
ngx_http_hello_loc_conf_t
if (ngx_strcmp(name->data, "") == 0)
return NGX_CONF_ERROR;
hello_string.data = name->data;
hello_string.len = ngx_strlen(hello_string.data);
return NGX_CONF_OK;
}
The handler functionThe handler function
static ngx_int_t ngx_http_hello_handler(ngx_http_request_t
*r) {
ngx_int_t rc;
ngx_buf_t *b;
ngx_chain_t out;
// we response to 'GET' and 'HEAD' requests only
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD)))
return NGX_HTTP_NOT_ALLOWED;
// discard request body, since we don't need it here
rc = ngx_http_discard_request_body(r);
if (rc != NGX_OK)
return rc;
....
StringsStrings
typedef struct {
size_t len;
u_char *data;
} ngx_str_t;
StringsStrings
ngx_strcmp() ngx_memcmp()
ngx_strncmp() ngx_memset()
ngx_strstr() ngx_memcpy()
ngx_strlen() ngx_memmove()
ngx_strchr()
src/core/ngx_string.h
StringsStrings
ngx_strcmp() ngx_memcmp()
ngx_strncmp() ngx_memset()
ngx_strstr() ngx_memcpy()
ngx_strlen() ngx_memmove()
ngx_strchr()
src/core/ngx_string.h
StringsStrings
ngx_memzero() — Fills memory with zeroes
ngx_cpymem() — Does the same as ngx_memcpy(), but
returns the final destination address. This one is
handy for appending multiple strings in a row.
ngx_movemem() — Does the same as ngx_memmove(),
but returns the final destination address.
ngx_strlchr() — Searches for a character in a
string, delimited by two pointers
src/core/ngx_string.h
StringsStrings
ngx_tolower()
ngx_toupper()
ngx_strlow()
ngx_strcasecmp()
ngx_strncasecmp()
StringsStrings
ngx_string(text) — static initializer for the
ngx_str_t type from the C string literal text
ngx_null_string — static empty string initializer
for the ngx_str_t type
ngx_str_set(str, text) — initializes string str of
ngx_str_t * type with the C string literal text
ngx_str_null(str) — initializes string str of
ngx_str_t * type with the empty string
Numeric conversionNumeric conversion
ngx_atoi(line, n) — ngx_int_t
ngx_atosz(line, n) — ssize_t
ngx_atoof(line, n) — off_t
ngx_atotm(line, n) — time_t
TimeTime
typedef struct {
time_t sec;
ngx_uint_t msec;
ngx_int_t gmtoff;
} ngx_time_t;
TimeTime
ngx_time() and ngx_timeofday() -
macros return the current time value
in seconds
They are the preferred way to access
the cached time value.
Updating the time:
ngx_time_update()
ngx_time_sigsafe_update()
TimeTime
ngx_time() and ngx_timeofday() -
macros return the current time value
in seconds
They are the preferred way to access
the cached time value.
Updating the time:
ngx_time_update()
ngx_time_sigsafe_update()
Nginx memoryNginx memory
● Pools
– easy and fast allocations
– easy deallocation at request finish
– simplify thread safety
● Shared memory
– share memory between nginx processes
– created using mmpa()
Nginx memory ­ HeapNginx memory ­ Heap
● ngx_alloc(size, log) — Allocate memory from
system heap. Allocation error and debugging
information is logged to log.
● ngx_calloc(size, log) — Allocate memory from
system heap like ngx_alloc(), but fill memory
with zeros after allocation.
● ngx_memalign(alignment, size, log) — Allocate
aligned memory from system heap.
● ngx_free(p)
Nginx memory ­ PoolNginx memory ­ Pool
● ngx_create_pool(size, log) — Create a pool with specified block
size. The pool object returned is allocated in the pool as well.
● ngx_destroy_pool(pool) — Free all pool memory, including the
pool object itself.
● ngx_palloc(pool, size) — Allocate aligned memory from the
specified pool.
● ngx_pcalloc(pool, size) — Allocate aligned memory from the
specified pool and fill it with zeroes.
● ngx_pnalloc(pool, size) — Allocate unaligned memory from the
specified pool. Mostly used for allocating strings.
● ngx_pfree(pool, p)
Marian MarinovMarian Marinov
mm@siteground.commm@siteground.com

Writing Nginx Modules