Skip to content
nginx-socketify edited this page Nov 9, 2018 · 22 revisions

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

char* resp = (char*)ngx_http_c_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_http_c_func_shm_alloc(void *shared_mem, size_t size);
extern void* ngx_http_c_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_http_c_func_module.h is essential header for your application. Install it into your header folders, for e.g (/usr/local/include)

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

void my_app_simple_post(ngx_http_c_func_ctx_t *ctx) {
    ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_post");

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

6. ngx_http_c_func_init and ngx_http_c_func_exit are reserved function name of each application and they will be triggered when starting nginx and stopping nginx

void ngx_http_c_func_init(ngx_http_c_func_ctx_t* ctx) {
    ngx_http_c_func_log(info, ctx, "%s", "Starting The Application");
    is_service_on=1;
}
void ngx_http_c_func_exit(ngx_http_c_func_ctx_t* ctx) {
    ngx_http_c_func_log(info, ctx, "%s\n", "Shutting down The Application");
    is_service_on = 0;
}

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

ngx_http_c_func_write_resp(
    ctx,
    200,
    NULL,
    ngx_http_c_func_content_type_json,
    "{'big_json_dump':'.........................'}"
    );

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

8. ngx_http_c_func_set_resp_var is the method when you just want to store your content to your desired variable which specified in nginx.conf like ngx_http_c_func_call "get_user_name_by_user_id" respTo=respUserName;

void get_user_name_by_user_id(ngx_http_c_func_ctx_t* ctx) {
    ngx_http_c_func_log(info, ctx, "%s", "looking for detail");
    
    char *resp_content;
    char *user_name= get_details_by_user_id((char*) ngx_http_c_func_get_query_param(ctx, "userId"));
    if(user_name) {
      resp_content= (char*)ngx_http_c_func_pcalloc(ctx, sizeof(char) * (strlen(user_name)+1));
      strcpy(resp_content, user_name)
    }else {      
      resp_content= (char*)ngx_http_c_func_pcalloc(ctx, sizeof("NO DATA")));
      strcpy(resp_content, "NO DATA");
    }
    
    ngx_http_c_func_set_resp_var(ctx, resp_content, strlen(user_name));
}

For e.g. If you want to get the user name from you application, and use this user name proxy pass to other server, respTo= might be your choice.

location /getProfile {
 ngx_http_c_func_call get_user_name_by_user_id respTo=userName;
 proxy_pass http://my_next_server/getProfileByName?userName=$userName;
}

9. ngx_http_c_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_http_c_func_ctx_t* ctx) {
    ngx_http_c_func_log(info, ctx, "%s", "looking for detail");
    
    char *user_name= get_details_by_user_id((char*) ngx_http_c_func_get_query_param(ctx, "userId"));
    if(user_name) {
      ngx_http_c_func_set_resp_var(ctx, user_name, strlen(user_name));
    }else {
      ngx_http_c_func_set_resp_var(ctx, "NO DATA", sizeof("NO DATA") - 1);
    }
}

10. ngx_http_c_func_add_header_in for added on header request. ngx_http_c_func_add_header_out for added on output header response. For example when using auth directive

--- config
ngx_http_c_func_link_lib "/home/taymindis/github/nginx-c-function/t/libcfuntest.so";
location /backend {
    return 200 "Welcome ${arg_userName}";
}
location = /auth {
    internal;
    ngx_http_c_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_http_c_func_ctx_t *ctx) {

    ngx_http_c_func_log_info(ctx, "Authenticating");
    char *userId = (char*) ngx_http_c_func_get_header(ctx, "userId");
    char *userPass = (char*) ngx_http_c_func_get_header(ctx, "userPass");
    char* userName;

    if ( userId == NULL || strlen(userId) == 0) {
AUTH_FAILED:
        ngx_http_c_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_http_c_func_add_header_in(ctx, "userName", sizeof("userName")-1, userName, strlen(userName));
        } else {
            goto AUTH_FAILED;
        }

        ngx_http_c_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