link: The Application dynamic linking with Nginx
Debian/Ubuntu installation
These docs apply to the APT package nginx-module-link provided by the GetPageSpeed Extras repository.
- Configure the APT repository as described in APT repository setup.
- Install the module:
sudo apt-get update
sudo apt-get install nginx-module-link
Warning
This module is not yet published as nginx-module-link in the APT repositories. Stay tuned, or email [email protected] to request it.
Native C/C++ function handlers for NGINX — load shared libraries and route requests directly to compiled code, with zero IPC overhead.
Overview
ngx_http_link_func bridges NGINX and native C/C++ applications through dynamic linking. Shared libraries (.so files) are loaded at server startup, and HTTP requests are dispatched directly to exported C functions running inside the NGINX worker process.
This means your C code has direct access to NGINX internals — request headers, URI arguments, request body, shared memory — and can write responses without serialization, sockets, or context switches.
Features
- Native function dispatch — route any location to an exported C function
- Shared memory and cache — cross-worker rbtree-based cache with mutex locking
- Thread pool offloading — AIO thread support for blocking operations
- Subrequest integration — chain with
auth_requestfor authentication flows - Remote library loading — fetch
.sofiles from HTTP/HTTPS URLs at startup - Lifecycle hooks — init and exit cycle callbacks for resource management
- Per-server properties — pass configuration values from
nginx.confto your code
Quick Start
nginx.conf:
http {
# Optional: shared memory for cross-worker cache
ngx_link_func_shm_size 1m;
server {
listen 8080;
# Load your compiled application
ngx_link_func_lib "/opt/myapp/libhandlers.so";
# Pass config values to your application
ngx_link_func_add_prop "db_host" "localhost:5432";
location /api/greeting {
ngx_link_func_call "handle_greeting";
}
location /api/users {
ngx_link_func_call "handle_users";
}
}
}
Your application (handlers.c):
#include <ngx_link_func_module.h>
void ngx_link_func_init_cycle(ngx_link_func_cycle_t *cycle) {
ngx_link_func_cyc_log(info, cycle, "%s", "Application started");
}
void handle_greeting(ngx_link_func_ctx_t *ctx) {
ngx_link_func_write_resp(
ctx, 200, "200 OK",
ngx_link_func_content_type_json,
"{\"message\":\"Hello from C\"}", 25
);
}
void handle_users(ngx_link_func_ctx_t *ctx) {
const char *token = ngx_link_func_get_query_param(ctx, "token");
if (!token) {
ngx_link_func_write_resp(
ctx, 401, "401 Unauthorized",
ngx_link_func_content_type_plaintext,
"Missing token", 13
);
return;
}
// Process authenticated request...
ngx_link_func_write_resp(
ctx, 200, "200 OK",
ngx_link_func_content_type_json,
"{\"users\":[]}", 12
);
}
void ngx_link_func_exit_cycle(ngx_link_func_cycle_t *cycle) {
ngx_link_func_cyc_log(info, cycle, "%s", "Application shutting down");
}
Build and deploy:
gcc -shared -o libhandlers.so -fPIC handlers.c
sudo cp libhandlers.so /opt/myapp/
sudo nginx -s reload
Directives
ngx_link_func_shm_size
Context: main | Default: none
Sets the shared memory zone size for cross-worker cache and data sharing.
ngx_link_func_shm_size 10m;
ngx_link_func_lib
Context: server | Default: none
Loads a shared library for the server block. Multiple server blocks can load the same library to share memory.
ngx_link_func_lib "/opt/myapp/libhandlers.so";
ngx_link_func_call
Context: location | Default: none
Routes requests to an exported C function by name.
location /api/data {
ngx_link_func_call "handle_data";
}
ngx_link_func_add_prop
Context: server | Default: none
Passes key-value properties to the application, accessible via ngx_link_func_get_prop().
ngx_link_func_add_prop "api_key" "secret123";
ngx_link_func_download_link_lib
Context: server | Default: none
Downloads a shared library from a remote URL at startup. Supports optional HTTP headers for authentication.
## Basic download
ngx_link_func_download_link_lib "https://repo.example.com/libapp.so" "/opt/myapp/libapp.so";
## With authentication headers
ngx_link_func_download_link_lib "https://repo.example.com/libapp.so"
"Authorization:Bearer TOKEN\r\n"
"/opt/myapp/libapp.so";
ngx_link_func_ca_cert
Context: server | Default: none
Sets the CA certificate for HTTPS library downloads.
ngx_link_func_ca_cert "/etc/ssl/certs/ca-certificates.crt";
ngx_link_func_add_req_header
Context: location | Default: none
Adds a request header, typically used to pass NGINX variables to subrequests.
ngx_link_func_add_req_header "X-Real-IP" "$remote_addr";
ngx_link_func_subrequest
Context: location | Default: none
Configures subrequest routing. Requires NGINX compiled with --with-http_auth_request_module.
location /protected {
ngx_link_func_subrequest "/auth";
}
Application API
Include <ngx_link_func_module.h> in your application. The header provides the complete C API.
Lifecycle Hooks
These reserved function names are called automatically by NGINX:
void ngx_link_func_init_cycle(ngx_link_func_cycle_t *cycle); // On startup
void ngx_link_func_exit_cycle(ngx_link_func_cycle_t *cycle); // On shutdown/reload
Request Context
Every handler receives ngx_link_func_ctx_t *ctx with:
| Field | Type | Description |
|---|---|---|
req_args |
char * |
Raw URI query string |
req_body |
u_char * |
Request body |
req_body_len |
size_t |
Request body length |
shared_mem |
void * |
Shared memory pointer |
Functions
| Function | Description |
|---|---|
| Response | |
ngx_link_func_write_resp(ctx, status, status_line, content_type, body, len) |
Write HTTP response |
ngx_link_func_write_resp_l(ctx, status, status_line, sl_len, ct, ct_len, body, len) |
Write response (explicit lengths) |
| Request data | |
ngx_link_func_get_uri(ctx, &str) |
Get request URI |
ngx_link_func_get_remote_addr(ctx) |
Get client remote address |
ngx_link_func_get_header(ctx, key, keylen) |
Get request header by name |
ngx_link_func_get_query_param(ctx, key) |
Get query parameter by key |
ngx_link_func_get_prop(ctx, key, keylen) |
Get server property |
| Headers | |
ngx_link_func_add_header_in(ctx, key, klen, val, vlen) |
Add input header |
ngx_link_func_add_header_out(ctx, key, klen, val, vlen) |
Add output header |
| Memory | |
ngx_link_func_palloc(ctx, size) |
Allocate from NGINX pool |
ngx_link_func_pcalloc(ctx, size) |
Allocate zeroed from NGINX pool |
ngx_link_func_strdup(ctx, src) |
Duplicate string from pool |
| Shared memory | |
ngx_link_func_shm_alloc(shm, size) |
Allocate shared memory |
ngx_link_func_shm_free(shm, ptr) |
Free shared memory |
ngx_link_func_shmtx_lock(shm) |
Acquire mutex |
ngx_link_func_shmtx_unlock(shm) |
Release mutex |
ngx_link_func_shmtx_trylock(shm) |
Try to acquire mutex |
| Cache | |
ngx_link_func_cache_get(shm, key) |
Get cached value |
ngx_link_func_cache_put(shm, key, value) |
Store cached value |
ngx_link_func_cache_new(shm, key, size) |
Allocate and cache |
ngx_link_func_cache_remove(shm, key) |
Remove from cache |
| Logging | |
ngx_link_func_log_debug/info/warn/err(ctx, msg) |
Log message |
ngx_link_func_log(level, ctx, fmt, ...) |
Log formatted message |
Content Type Constants
ngx_link_func_content_type_plaintext // "text/plain"
ngx_link_func_content_type_html // "text/html; charset=utf-8"
ngx_link_func_content_type_json // "application/json"
ngx_link_func_content_type_jsonp // "application/javascript"
ngx_link_func_content_type_xformencoded // "application/x-www-form-urlencoded"
Linux
gcc -shared -o libmyapp.so -fPIC myapp.c
macOS
clang -dynamiclib -o libmyapp.dylib -fPIC myapp.c -Wl,-undefined,dynamic_lookup ```