hello,
I have created module which contains the function set_crc32.
You can find the source of it below:
I've tested it on the Ubuntu and the function set_crc32 returned the value without any errors:
You can find the invoking set_crc32 below.
However when I tried to run it on the FreeBSD 7.1 x64
I got the error:
worker process 53751 exited on signal 11
Please, help me. Does anyone know what I need to do?
I read the documents about signal 11. It means segmentation fault.
Did I work incorrect with r->pool ?
How do I need to free the memory?
The documentation says I do not need to use ngx_free to free the memory.
What is the right way?
------ Configure file ------------------------
server {
listen 80;
server_name localhost;
# Check if our special is not already set
if ($http_cookie !~ ^.*crc32_value=\d+.*$ ) {
set $crc2_num1 "127.0.1.2";
set_crc32 $crc32_num $crc2_num1 "55";
set $crc32_value $crc32_num; # We will use that later to set the outgoing cookie
set $crc32_cookie "crc32_value=$crc32_value; $http_cookie"; # This will be sent to the upstream - simulated cookie
}
location / {
proxy_set_header Cookie $crc32_cookie; # Make sure we have the correct cookie passed to the upstream
add_header Set-Cookie "crc32_value=$crc32_value"; # Make it stick with the client
root html;
index index.html index.htm;
if (!-f $request_filename) {
proxy_pass http://localhost;
break;
}
}
}
------ Module source ---------------------
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
static char *ngx_http_crc32_set_crc32(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static ngx_int_t ngx_http_crc32_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_crc32_set_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
static ngx_command_t ngx_http_set_crc32_commands[] = {
{ ngx_string("set_crc32"),
NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE3,
ngx_http_crc32_set_crc32,
0,
0,
NULL },
ngx_null_command
};
static ngx_http_module_t ngx_http_set_crc32_module_ctx = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
ngx_module_t ngx_http_set_crc32_module = {
NGX_MODULE_V1,
&ngx_http_set_crc32_module_ctx, /* module context */
ngx_http_set_crc32_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
static char * ngx_http_crc32_set_crc32(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_str_t *value;
ngx_http_variable_t *vReturnValue;
ngx_http_variable_t *vIpAddress;
unsigned char *buff;
// get command parameters
value = cf->args->elts;
// read first parameter - returned value
if (value[1].data[0] != '$') {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid the first parameter(returned variable) name. It should begin with $ \"%V\"", &value[1]);
return NGX_CONF_ERROR;
}
// read second parameter
if (value[2].data[0] != '$') {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid the secord parameter name. It should begin with $ \"%V\"", &value[2]);
return NGX_CONF_ERROR;
}
// read second parameter
if (value[3].data[0] == '$') {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid the third parameter name. It should not begin with $ \"%V\"", &value[3]);
return NGX_CONF_ERROR;
}
value[1].len--;
value[1].data++;
vReturnValue = ngx_http_add_variable(cf, &value[1], 0);
value[2].len--;
value[2].data++;
vIpAddress = ngx_http_add_variable(cf, &value[2], 0);
if (vReturnValue == NULL) {
return NGX_CONF_ERROR;
}
if (vIpAddress == NULL) {
return NGX_CONF_ERROR;
}
if (vReturnValue->get_handler == NULL ){
vReturnValue->get_handler = ngx_http_crc32_variable;
// read third parameter
buff = ngx_palloc(cf->pool, value[3].len + 1);
ngx_cpystrn(buff, value[3].data, value[3].len + 1);
vReturnValue->data = (uintptr_t)buff;
}
else {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "The value for Returned Variable already defined: \"%V\". Please, do not initialize returned variable before call set_crc32.", &value[1]);
return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
}
static ngx_int_t ngx_http_crc32_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data)
{
ngx_str_t ipAddress = {ngx_strlen(r->variables[1].data), (unsigned char *) r->variables[1].data };
ngx_str_t ext = { ngx_strlen(data), (unsigned char *)data };
char* buff = ngx_palloc(r->pool, ipAddress.len + ext.len + 1);
sprintf(buff, "%s%s", ipAddress.data, ext.data);
ngx_uint_t ucrc32;
ucrc32 = ngx_crc32_short((u_char*)buff, strlen(buff));
v->data=ngx_palloc(r->pool, 10);
ngx_sprintf(v->data, "%d", ucrc32);
v->data[9] = 0;
v->len = 9;
/* Set all required params */
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
return NGX_OK;
}