{"id":18523100,"url":"https://github.com/taymindis/nginx-link-function","last_synced_at":"2026-03-02T10:30:54.115Z","repository":{"id":48806585,"uuid":"119272966","full_name":"Taymindis/nginx-link-function","owner":"Taymindis","description":"It is a NGINX module that provides dynamic linking to your application in server context and call the function of your application in location directive","archived":false,"fork":false,"pushed_at":"2021-07-22T03:54:50.000Z","size":439,"stargazers_count":234,"open_issues_count":2,"forks_count":42,"subscribers_count":22,"default_branch":"master","last_synced_at":"2026-02-16T15:49:49.244Z","etag":null,"topics":["dynamic-link-library","dynamic-linking","embedded","golang","microservices","microservices-architecture","nginx","nginx-cfunction","nginx-server","ngx-http","test-nginx","zero-downtime"],"latest_commit_sha":null,"homepage":"https://nginx-link-function.github.io","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Taymindis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-28T15:58:15.000Z","updated_at":"2025-11-19T11:17:37.000Z","dependencies_parsed_at":"2022-09-23T21:40:45.176Z","dependency_job_id":null,"html_url":"https://github.com/Taymindis/nginx-link-function","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/Taymindis/nginx-link-function","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Taymindis%2Fnginx-link-function","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Taymindis%2Fnginx-link-function/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Taymindis%2Fnginx-link-function/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Taymindis%2Fnginx-link-function/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Taymindis","download_url":"https://codeload.github.com/Taymindis/nginx-link-function/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Taymindis%2Fnginx-link-function/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29998512,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-02T09:59:02.300Z","status":"ssl_error","status_checked_at":"2026-03-02T09:59:02.001Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dynamic-link-library","dynamic-linking","embedded","golang","microservices","microservices-architecture","nginx","nginx-cfunction","nginx-server","ngx-http","test-nginx","zero-downtime"],"created_at":"2024-11-06T17:34:15.702Z","updated_at":"2026-03-02T10:30:54.075Z","avatar_url":"https://github.com/Taymindis.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003cp align=\"center\"\u003e\u003cimg src=\"nginx-link-function-logo.png\" alt=\"nginx link function Logo\" /\u003e\u003c/p\u003e\n\n\n\u003ch1 align=\"center\"\u003enginx-link-function\u003c/h1\u003e\n\u003ch3 align=\"center\"\u003eThe Application dynamic linking with Nginx \u003c/h3\u003e\n\n\nTable of Contents\n=================\n\n* [Introduction](#introduction)\n* [How it works](#how-it-works)\n* [Usage](#usage)\n* [Installation](#installation)\n* [Sample Application Development](#sample-application-development)\n* [Test](#test)\n* [Wiki](#wiki)\n* [Support](#support)\n* [Copyright \u0026 License](#copyright--license)\n\nIntroduction\n============\n\nnginx-link-function is a nginx module which provides dynamic linking to your application in server context and call the function of your application in location directive.You could direct link your C/C++ application (or any other which accept dynamic linking) to nginx server.\n\n\nHow it works\n============\n\n![Image of nginx-link-function](nginx-link-function-architecture.png)\n\n\nUsage\n=======\n```nginx\n# nginx.conf\n\nserver {\n  listen 8888;\n  ...\n  ngx_link_func_lib \"/path/to/your/libcfuntest.so\";\n  ...\n  ...\n  location = /testCFunGreeting {\n      ngx_link_func_call \"my_app_simple_get_greeting\"; \n  }\n}\n\nserver {\n  listen 8989;\n  aio threads;\n  ...\n  ngx_link_func_lib \"/path/to/your/libcfuntest.so\"; # sharing data memory with server 1 if the path are same with server 1\n  ...\n  ...\n  location = /testCFunGreeting {\n      ngx_link_func_call \"my_app_simple_get_greeting\" \n  }\n}\n\nserver {\n  listen 8999;\n  aio threads;\n  ...\n  ngx_link_func_lib \"/path/to/your/libcfuntest2.so\"; # another application\n  ...\n  ...\n  location = /testPost {\n      add_header Allow \"GET, POST, HEAD\" always;\n      if ( $request_method !~ ^(POST)$ ) {\n        return 405;\n      }\n      ngx_link_func_call \"my_2nd_app_simple_get_token\";\n  }\n}\n\nserver {\n  listen 9888;\n  aio threads;\n  ...\n  ## Download application from cloud repo e.g. ngx_link_func_download_link_lib \u003cdownload_link\u003e \u003cdest_link_file\u003e\n  ngx_link_func_download_link_lib \"http://abc.com/repos/libcfuntest.so\" \"/etc/nginx/libcfuntest3.so\"\n  ...\n  ...\n  location = /testPost {\n      add_header Allow \"GET, POST, HEAD\" always;\n      if ( $request_method !~ ^(POST)$ ) {\n        return 405;\n      }\n      ngx_link_func_call \"my_3rd_app_simple_get_token\";\n  }\n}\n\nserver {\n  listen 9898;\n  aio threads;\n  ...\n  ## Download application from cloud repo with extra header e.g. ngx_link_func_download_link_lib \u003cdownload_link\u003e \u003cheaders\u003e \u003cdest_link_file\u003e\n  ngx_link_func_download_link_lib \"https://abc.com/repos/libcfuntest.so\" \"Accept-Language:en_US\\r\\nAuthorization:Bearer KA.eyJ2ZXJzaadlasdlaldhjHJ2h3ldjklsjaklcjkljasdklcmasaskdaJxdkL3ftjM\\r\\n\" \"/etc/nginx/libcfuntest4.so\"\n  ...\n  ...\n  location = /testPost {\n      add_header Allow \"GET, POST, HEAD\" always;\n      if ( $request_method !~ ^(POST)$ ) {\n        return 405;\n      }\n      ngx_link_func_call \"my_other_app_simple_get_token\";\n  }\n}\n```\n\nInstallation\n============\n\n```bash\nwget 'http://nginx.org/download/nginx-1.10.3.tar.gz'\ntar -xzvf nginx-1.10.3.tar.gz\ncd nginx-1.10.3/\n\n./configure --add-module=/path/to/nginx-link-function\n\nmake -j2\nsudo make install\n```\n\n#### ngx_link_func_module.h header not found when configure\n\nWhen first time configure this project, I purposely do not include this header, you may need to install it to your c header file as this header file need to share with your .so application as well.\n\n#### Example of installing header\n```bash\ninstall -m 644 /path/to/nginx-link-function/src/ngx_link_func_module.h /usr/local/include/\n```\n\n\n[Back to TOC](#table-of-contents)\n\n\nInterface that expose to client application\n============================================\n\nThis is the interface that you can use to get more details from nginx server, it all inside the ngx_link_func_module.h.\n\n```c\n\n#define ngx_link_func_content_type_plaintext \"text/plain\"\n#define ngx_link_func_content_type_html \"text/html; charset=utf-8\"\n#define ngx_link_func_content_type_json \"application/json\"\n#define ngx_link_func_content_type_jsonp \"application/javascript\"\n#define ngx_link_func_content_type_xformencoded \"application/x-www-form-urlencoded\"\n\ntypedef struct {\n  char *req_args; // Uri Args\n  u_char *req_body; // Request Body\n  size_t req_body_len; // length of body\n  void *shared_mem;\n\n  /* internal */\n  void* __r__;\n  void* __pl__;\n  void* __log__;\n} ngx_link_func_ctx_t;\n\nextern void ngx_link_func_log_debug(ngx_link_func_ctx_t *ctx, const char* msg);\nextern void ngx_link_func_log_info(ngx_link_func_ctx_t *ctx, const char* msg);\nextern void ngx_link_func_log_warn(ngx_link_func_ctx_t *ctx, const char* msg);\nextern void ngx_link_func_log_err(ngx_link_func_ctx_t *ctx, const char* msg);\nextern u_char* ngx_link_func_get_header(ngx_link_func_ctx_t *ctx, const char*key);\nextern void* ngx_link_func_get_query_param(ngx_link_func_ctx_t *ctx, const char *key);\nextern void* ngx_link_func_palloc(ngx_link_func_ctx_t *ctx, size_t size);\nextern void* ngx_link_func_pcalloc(ngx_link_func_ctx_t *ctx, size_t size);\n\nextern void ngx_link_func_write_resp(\n    ngx_link_func_ctx_t *ctx,\n    uintptr_t status_code,\n    const char* status_line,\n    const char* content_type,\n    const char* resp_content,\n    size_t resp_len\n);\n\n\n// Shared Memory and Cache Scope\nextern void ngx_link_func_shmtx_lock(void *shared_mem);\nextern void ngx_link_func_shmtx_unlock(void *shared_mem);\nextern void* ngx_link_func_shm_alloc(void *shared_mem, size_t size);\nextern void ngx_link_func_shm_free(void *shared_mem, void *ptr);\nextern void* ngx_link_func_cache_get(void *shared_mem, const char* key);\nextern void* ngx_link_func_cache_put(void *shared_mem, const char* key, void* value);\nextern void* ngx_link_func_cache_new(void *shared_mem, const char* key, size_t size);\nextern void ngx_link_func_cache_remove(void *shared_mem, const char* key);\n\n```\n\n## Interface break down details\n\n#### malloc/calloc from nginx pool\n```c\nvoid* ngx_link_func_palloc(ngx_link_func_ctx_t *ctx, size_t size);\nvoid* ngx_link_func_pcalloc(ngx_link_func_ctx_t *ctx, size_t size);\n```\n\n#### get the request header parameter from \n```c\nextern u_char* ngx_link_func_get_header(ngx_link_func_ctx_t *ctx, const char*key);\n```\n\n#### get the uri args\n```c\nctx-\u003ereq_args;\n```\n\n#### get the query parameter\n```c\nextern void* ngx_link_func_get_query_param(ngx_link_func_ctx_t *ctx, const char *key);\n```\n\n#### get the request body\n```c\nctx-\u003ereq_body;\n```\n\n#### get the request body length\n```c\nctx-\u003ereq_body_len;\n```\n\n#### loggin to nginx server\n```c\nextern void ngx_link_func_log_debug(ngx_link_func_ctx_t *ctx, const char* msg);\nextern void ngx_link_func_log_info(ngx_link_func_ctx_t *ctx, const char* msg);\nextern void ngx_link_func_log_warn(ngx_link_func_ctx_t *ctx, const char* msg);\nextern void ngx_link_func_log_err(ngx_link_func_ctx_t *ctx, const char* msg);\n```\n\n#### Response out\n```c\nextern void ngx_link_func_write_resp(\n    ngx_link_func_ctx_t *ctx,\n    uintptr_t status_code, // Status code\n    const char* status_line, // Status line\n    const char* content_type, // Response content type\n    const char* resp_content, // Response content\n    size_t resp_len // Response content length\n);\n```\n\n\nSample Application Development\n===============================\n\nFeel free to clone a sample project at\n \n[Simple Project with cmake](https://github.com/Taymindis/simple_linkfunc_app)\n\n[link function google direction](https://github.com/Taymindis/sample-ngx-linkfunc-project/tree/master/ngx-cfunc-ggl-direction)\n[linkfunc-jwt-auth](https://github.com/Taymindis/sample-ngx-linkfunc-project/tree/master/linkfunc-jwt-auth)\n\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cngx_link_func_module.h\u003e\n\n/*** build the program as .so library and copy to the preferred place for nginx to link this library ***/\n/*** gcc -shared -o libcfuntest.so -fPIC cfuntest.c ***/\n/*** cp libcfuntest.so /etc/nginx/ ***/\n\nint is_service_on = 0;\n\nvoid ngx_link_func_init_cycle(ngx_link_func_cycle_t* cycle) {\n    ngx_link_func_cyc_log(info, cycle, \"%s\", \"starting application\");\n\n    is_service_on=1;\n}\n\nvoid my_app_simple_get_greeting(ngx_link_func_ctx_t *ctx) {\n    ngx_link_func_log_info(ctx, \"Calling back and log from my_app_simple_get\");\n\n    ngx_link_func_write_resp(\n        ctx,\n        200,\n        \"200 OK\",\n        \"text/plain\",\n        \"greeting from ngx_link_func testing\",\n        sizeof(\"greeting from ngx_link_func testing\")-1\n    );\n}\n\nvoid my_app_simple_get_args(ngx_link_func_ctx_t *ctx) {\n    ngx_link_func_log_info(ctx, \"Calling back and log from my_app_simple_get_args\");\n\n    if(ctx-\u003ereq_args) {\n        ngx_link_func_write_resp(\n            ctx,\n            200,\n            \"200 OK\",\n            \"text/plain\",\n            ctx-\u003ereq_args,\n            strlen(ctx-\u003ereq_args)\n        );\n    } else {\n        ngx_link_func_write_resp(\n            ctx,\n            204,\n            \"\",\n            \"text/plain\",\n            NULL,\n            0\n        );\n    }\n}\n\nvoid my_app_simple_get_token_args(ngx_link_func_ctx_t *ctx) {\n    ngx_link_func_log_info(ctx, \"Calling back and log from my_app_simple_get_token_args\");\n\n    char * tokenArgs = (char*)ngx_link_func_get_query_param(ctx, \"token\");\n    if (! tokenArgs) {\n        ngx_link_func_write_resp(\n            ctx,\n            401,\n            \"401 unauthorized\",\n            \"text/plain\",\n            \"Token Not Found\",\n            sizeof(\"Token Not Found\")-1\n        );\n    } else {\n        ngx_link_func_write_resp(\n            ctx,\n            401,\n            \"401 unauthorized\",\n            \"text/plain\",\n            tokenArgs,\n            strlen(tokenArgs)\n        );\n    }\n}\n\nvoid my_app_simple_post(ngx_link_func_ctx_t *ctx) {\n    ngx_link_func_log_info(ctx, \"Calling back and log from my_app_simple_post\");\n\n    ngx_link_func_write_resp(\n        ctx,\n        202,\n        \"202 Accepted and Processing\",\n        \"text/plain\",\n        NULL,\n        0\n    );\n}\n\n\n\nvoid my_app_simple_get_no_resp(ngx_link_func_ctx_t *ctx) {\n    ngx_link_func_log_info(ctx, \"Calling back and log from my_app_simple_get_no_resp\");\n\n    //  return 404 \n}\n\nvoid ngx_link_func_exit_cycle(ngx_link_func_cycle_t* cyc) {\n    ngx_link_func_cyc_log(info, cyc, \"%s\\n\", \"Shutting down/reloading the Application\");\n\n    is_service_on = 0;\n}\n```\n\n#### Noted: \nThe function init and exit cycle are reserved function when started the nginx, it will call init cycle function, when stop/reload nginx, it will call exit cycle function.\n```c\nvoid ngx_link_func_init_cycle(ngx_link_func_cycle_t* cyc){}\nvoid ngx_link_func_exit_cycle(ngx_link_func_cycle_t* cyc){}\n```\n[references: The init and exit cycle hooks in application layer](https://github.com/Taymindis/nginx-link-function/wiki/The-init-and-exit-cycle-hooks-in-application-layer)\n\n\n#### Log Level\nThe log can be called, the logged message will be store where you config error log in nginx.conf\n```c\nngx_link_func_log_info(ctx, \"This is info direct message\");\nngx_link_func_log(info, ctx, \"%s\", \"This is info with formatted message\");\nngx_link_func_log_debug(ctx, \"This is debug direct message\");\nngx_link_func_log(debug, ctx, \"%s\", \"This is debug with formatted message\");\n\nngx_link_func_log_info(ctx, \"%s\", \"This is info with formatted message\"); // Wrong format\nngx_link_func_log_debug(ctx, \"%s\", \"This is info with formatted message\"); // Wrong format\n```\n\n### provide ca-cert to download your app(.so)?? please embedded this in your nginx.conf's server context.\n```c\nngx_link_func_ca_cert \"/etc/ssl/certs/ca-cert.crt\"\nngx_link_func_download_link_lib \"https://abc.com/repos/libcfuntest.so\" \"/etc/nginx/libcfuntest4.so\"\n```\n\n### provide ca-cert and extra header to download your app(.so)?? please embedded this in your nginx.conf's server context.\n```c\nngx_link_func_ca_cert \"/etc/ssl/certs/ca-cert.crt\"\nngx_link_func_download_link_lib \"https://abc.com/repos/libcfuntest.so\" \"Accept-Language:en_US\\r\\nAuthorization:Bearer KA.eyJ2ZXJzaadlasdlaldhjHJ2h3ldjklsjaklcjkljasdklcmasaskdaJxdkL3ftjM\\r\\n\" \"/etc/nginx/libcfuntest4.so\"\n\n```\n\nTest\n=====\n\nIt depends on nginx test suite libs, please refer [test-nginx](https://github.com/openresty/test-nginx) for installation.\n\n\n```bash\ncd /path/to/nginx-link-function\nexport PATH=/path/to/nginx-dirname:$PATH \nsudo prove -r t/\n```\n\n[Back to TOC](#table-of-contents)\n\nSupport\n=======\n\nPlease raise an [issue](https://github.com/Taymindis/nginx-link-function/issues) and I will fixed it as soon as I can\n\nAlternatively, you may email to minikawoon2017@gmail.com\n\nWiki\n====\n\nCheck out [wiki](https://github.com/Taymindis/nginx-link-function/wiki) for more details\n\n\n[Back to TOC](#table-of-contents)\n\nCopyright \u0026 License\n===================\n\nCopyright (c) 2018-2020, Taymindis \u003ccloudleware2015@gmail.com\u003e\n\nThis module is licensed under the terms of the BSD license.\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n[Back to TOC](#table-of-contents)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaymindis%2Fnginx-link-function","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftaymindis%2Fnginx-link-function","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaymindis%2Fnginx-link-function/lists"}