Skip to content
Taymindis Woon edited this page Mar 28, 2021 · 22 revisions

1. Use nginx pool memory for your internal memory allocation.

char* resp = (char*)ngx_link_func_pcalloc(ctx, output.size() + 1);

strcpy(resp, output.c_str());

2. using share memory pool if you want to keep the value or share the value among the apps.

extern void* ngx_link_func_shm_alloc(void *shared_mem, size_t size);
extern void* ngx_link_func_shm_alloc_locked(void *shared_mem, size_t size);

3. Application duplicated by worker process count

As long as you have N(>1) worker process, your applications will be duplicated N times, Therefore, you need share_memory for sharing the content across multiple workers

4. Install header file before implement your application.

ngx_link_func_module.h is essential header for your application. Install it into your header folders, for e.g (/usr/local/include)

5. ngx_link_func_ctx_t *ctx is the only parameter for function creating.

void my_app_simple_post(ngx_link_func_ctx_t *ctx) {
    ngx_link_func_log_info(ctx, "Calling back and log from my_app_simple_post");

    ngx_link_func_write_resp(
        ctx,
        202,
        "202 Accepted and Processing",
        "text/plain",
        ctx->req_body
    );
}

6. ngx_link_func_init_cycle and ngx_link_func_exit_cycle are reserved function name of each application and they will be triggered when starting nginx and stopping/reload nginx

void
ngx_link_func_init_cycle(ngx_link_func_cycle_t* cycle) {
    ngx_link_func_cyc_log(info, cycle, "%s", "starting:: The stock transaction application");
}
void
ngx_link_func_exit_cycle(ngx_link_func_cycle_t* cyc) {
    ngx_link_func_cyc_log(info, cyc, "%s\n", "Shutting down or reloading stock transaction application");
}

init and exit cycle with share memory

7. not need to worry your memory will leak, every response will be duplicated the content

ngx_link_func_write_resp(
    ctx,
    200,
    NULL,
    ngx_link_func_content_type_json,
    "{'big_json_dump':'.........................'}"
    );

ngx_link_func_log(debug, ctx, "===Done Response===");

8. ngx_link_func_strdup is the best method to duplicate a copy of content, you do not need to free the content as nginx pool will handle it

void get_user_name_by_user_id(ngx_link_func_ctx_t* ctx) {
    ngx_link_func_log(info, ctx, "%s", "looking for detail");
    
    char *user_name= get_details_by_user_id((char*) ngx_link_func_get_query_param(ctx, "userId"));
    if(user_name) {
      ngx_link_func_set_resp_var(ctx, user_name, strlen(user_name));
    }else {
      ngx_link_func_set_resp_var(ctx, "NO DATA", sizeof("NO DATA") - 1);
    }
}

9. ngx_link_func_add_header_in for added on header request. ngx_link_func_add_header_out for added on output header response. For example when using auth directive

--- config
ngx_link_func_lib "/home/taymindis/github/nginx-link-function/t/libcfuntest.so";
location /backend {
    return 200 "Welcome ${arg_userName}";
}
location = /auth {
    internal;
    ngx_link_func_call "my_simple_authentication";
}
location = /my_simple_authentication {
  auth_request /auth;
  proxy_pass http://127.0.0.1:${server_port}/backend?userName=$http_userName;
}
void my_simple_authentication(ngx_link_func_ctx_t *ctx) {

    ngx_link_func_log_info(ctx, "Authenticating");
    char *userId = (char*) ngx_link_func_get_header(ctx, "userId");
    char *userPass = (char*) ngx_link_func_get_header(ctx, "userPass");
    char* userName;

    if ( userId == NULL || strlen(userId) == 0) {
AUTH_FAILED:
        ngx_link_func_write_resp(
            ctx,
            403,
            "403 Authenthication Failed",
            "text/plain",
            "",
            0
        );
    } else {
        userName = login(userId, userPass);
        /** Add input header for downstream response **/
        if (userName) {
            ngx_link_func_add_header_in(ctx, "userName", sizeof("userName")-1, userName, strlen(userName));
        } else {
            goto AUTH_FAILED;
        }

        ngx_link_func_write_resp(
            ctx,
            200,
            "200 OK",
            "text/plain",
            "OK",
            sizeof("OK")-1
        );
    }
}
curl --header "userId: foo" --header "userPass: asdasds" http://127.0.0.1:8080/my_simple_authentication

10. Nginx Mirror Module

If you want to consume 1 request and proxy to multiple server, you may use mirror

       location / {
            mirror /mirror;
            mirror_request_body off;
            proxy_set_header HOST backend.com;
             proxy_pass https://backend.com$uri$is_args$args;
        }

        location /mirror {
            internal;
            proxy_pass https://backend.com$uri$is_args$args;
            proxy_set_header X-Original-URI $request_uri;
            proxy_read_timeout 0s; # async way
            proxy_set_header HOST backend.com;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

11. use ngx_link_func_add_prop directive for application properties configuration

     server {
        ngx_link_func_add_prop private_key AbCdEf123456;
        ngx_link_func_add_prop cloud_service_api "http://......";

       

       location /requestNewStock {
         ngx_link_func_call request_new_stock_details;
       }
     }

when using it in init the application

void
ngx_link_func_init_cycle(ngx_link_func_cycle_t* cycle) {
    ngx_link_func_cyc_log(info, cycle, "%s", "starting:: ...");

    u_char *pkey =  ngx_link_func_cyc_get_prop(cycle, (char*) "private_key", sizeof("private_key") - 1);
    ....
}

or using it on requesting

void
request_new_stock_details(ngx_link_func_ctx_t* ctx) {
    ngx_link_func_log(info, ctx, "%s", "requesting:: ...");

    u_char *cloud_service_api =  ngx_link_func_get_prop(ctx, (char*) "cloud_service_api", sizeof("cloud_service_api") - 1);
    ....
}
Clone this wiki locally