link : Liaison dynamique d'applications avec Nginx
Installation
Vous pouvez installer ce module sur n'importe quelle distribution basée sur RHEL, incluant, sans s'y limiter :
- RedHat Enterprise Linux 7, 8, 9 et 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 et Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-link
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-link
Activez le module en ajoutant ce qui suit au début de /etc/nginx/nginx.conf :
load_module modules/ngx_http_link_func_module.so;
Ce document décrit nginx-module-link v3.2.6 publié le 12 août 2026.
Gestionnaires de fonctions C/C++ natifs pour NGINX — chargez des bibliothèques partagées et acheminez les requêtes directement vers du code compilé, sans surcoût d'IPC.
Aperçu
ngx_http_link_func fait le pont entre NGINX et les applications natives C/C++ via la liaison dynamique. Les bibliothèques partagées (fichiers .so) sont chargées au démarrage du serveur, et les requêtes HTTP sont distribuées directement aux fonctions C exportées s'exécutant à l'intérieur du processus worker NGINX.
Cela signifie que votre code C a un accès direct aux internes de NGINX — en-têtes de requête, arguments d'URI, corps de requête, mémoire partagée — et peut écrire des réponses sans sérialisation, sockets ni changements de contexte.
Fonctionnalités
- Distribution de fonctions natives — acheminez n'importe quel location vers une fonction C exportée
- Mémoire partagée et cache — cache inter-workers basé sur un rbtree avec verrouillage par mutex
- Déport vers un pool de threads — prise en charge des threads AIO pour les opérations bloquantes
- Intégration de sous-requêtes — chaînez avec
auth_requestpour les flux d'authentification - Chargement de bibliothèques distantes — récupérez des fichiers
.sodepuis des URL HTTP/HTTPS au démarrage - Hooks de cycle de vie — callbacks d'initialisation et de sortie de cycle pour la gestion des ressources
- Propriétés par serveur — transmettez des valeurs de configuration depuis
nginx.confà votre code
Démarrage rapide
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";
}
}
}
Votre 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");
}
Compiler et déployer :
gcc -shared -o libhandlers.so -fPIC handlers.c
sudo cp libhandlers.so /opt/myapp/
sudo nginx -s reload
Directives
ngx_link_func_shm_size
Contexte : main | Défaut : aucun
Définit la taille de la zone de mémoire partagée pour le cache inter-workers et le partage de données.
ngx_link_func_shm_size 10m;
ngx_link_func_lib
Contexte : server | Défaut : aucun
Charge une bibliothèque partagée pour le bloc server. Plusieurs blocs server peuvent charger la même bibliothèque pour partager la mémoire.
ngx_link_func_lib "/opt/myapp/libhandlers.so";
ngx_link_func_call
Contexte : location | Défaut : aucun
Achemine les requêtes vers une fonction C exportée par son nom.
location /api/data {
ngx_link_func_call "handle_data";
}
ngx_link_func_add_prop
Contexte : server | Défaut : aucun
Transmet des propriétés clé-valeur à l'application, accessibles via ngx_link_func_get_prop().
ngx_link_func_add_prop "api_key" "secret123";
ngx_link_func_download_link_lib
Contexte : server | Défaut : aucun
Télécharge une bibliothèque partagée depuis une URL distante au démarrage. Prend en charge des en-têtes HTTP optionnels pour l'authentification.
## 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
Contexte : server | Défaut : aucun
Définit le certificat CA pour les téléchargements de bibliothèques via HTTPS.
ngx_link_func_ca_cert "/etc/ssl/certs/ca-certificates.crt";
ngx_link_func_add_req_header
Contexte : location | Défaut : aucun
Ajoute un en-tête de requête, généralement utilisé pour transmettre des variables NGINX aux sous-requêtes.
ngx_link_func_add_req_header "X-Real-IP" "$remote_addr";
ngx_link_func_subrequest
Contexte : location | Défaut : aucun
Configure le routage des sous-requêtes. Nécessite que NGINX soit compilé avec --with-http_auth_request_module.
location /protected {
ngx_link_func_subrequest "/auth";
}
API de l'application
Incluez <ngx_link_func_module.h> dans votre application. Cet en-tête fournit l'API C complète.
Hooks de cycle de vie
Ces noms de fonctions réservés sont appelés automatiquement par 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
Contexte de requête
Chaque gestionnaire reçoit ngx_link_func_ctx_t *ctx avec :
| Champ | Type | Description |
|---|---|---|
req_args |
char * |
Chaîne de requête brute de l'URI |
req_body |
u_char * |
Corps de la requête |
req_body_len |
size_t |
Longueur du corps de la requête |
shared_mem |
void * |
Pointeur vers la mémoire partagée |
Fonctions
| Fonction | Description |
|---|---|
| Réponse | |
ngx_link_func_write_resp(ctx, status, status_line, content_type, body, len) |
Écrire une réponse HTTP |
ngx_link_func_write_resp_l(ctx, status, status_line, sl_len, ct, ct_len, body, len) |
Écrire une réponse (longueurs explicites) |
| Données de requête | |
ngx_link_func_get_uri(ctx, &str) |
Obtenir l'URI de la requête |
ngx_link_func_get_remote_addr(ctx) |
Obtenir l'adresse distante du client |
ngx_link_func_get_header(ctx, key, keylen) |
Obtenir un en-tête de requête par nom |
ngx_link_func_get_query_param(ctx, key) |
Obtenir un paramètre de requête par clé |
ngx_link_func_get_prop(ctx, key, keylen) |
Obtenir une propriété du serveur |
| En-têtes | |
ngx_link_func_add_header_in(ctx, key, klen, val, vlen) |
Ajouter un en-tête d'entrée |
ngx_link_func_add_header_out(ctx, key, klen, val, vlen) |
Ajouter un en-tête de sortie |
| Mémoire | |
ngx_link_func_palloc(ctx, size) |
Allouer depuis le pool NGINX |
ngx_link_func_pcalloc(ctx, size) |
Allouer et initialiser à zéro depuis le pool NGINX |
ngx_link_func_strdup(ctx, src) |
Dupliquer une chaîne depuis le pool |
| Mémoire partagée | |
ngx_link_func_shm_alloc(shm, size) |
Allouer de la mémoire partagée |
ngx_link_func_shm_free(shm, ptr) |
Libérer de la mémoire partagée |
ngx_link_func_shmtx_lock(shm) |
Acquérir le mutex |
ngx_link_func_shmtx_unlock(shm) |
Libérer le mutex |
ngx_link_func_shmtx_trylock(shm) |
Tenter d'acquérir le mutex |
| Cache | |
ngx_link_func_cache_get(shm, key) |
Obtenir une valeur en cache |
ngx_link_func_cache_put(shm, key, value) |
Stocker une valeur en cache |
ngx_link_func_cache_new(shm, key, size) |
Allouer et mettre en cache |
ngx_link_func_cache_remove(shm, key) |
Retirer du cache |
| Journalisation | |
ngx_link_func_log_debug/info/warn/err(ctx, msg) |
Journaliser un message |
ngx_link_func_log(level, ctx, fmt, ...) |
Journaliser un message formaté |
Constantes de type de contenu
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 ```