Http module handler, chain buffer and output_filter

Hey, i wonder why the server is freezing when i do a request to it and i
do
not define the “NO_PROBLEM” macro in the code.
In my ngx_html_chain_buffers_init i do a ngx_pcalloc because i thought
that
the server was freezing because of some memory missing alignment(it was
firstly static). I am just too tired at this hour for change it(ill
change
it tommorow).

I am on a debian jessie,
nginx 1.6.2 (source from the debian repo if i remember well)

PS: I am sorry if i miss some forum rules. It is my first time here.
Just
tell me what i did wrong if i did something wrong.
Thank You !
here is my code:

//#define NO_PROBLEM

#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
#include <stdio.h>
/* BEGIN html strings */
enum ngx_html_text_e {
NGX_HTML_ALL,
NGX_HTML_NB_PARTS
};

static ngx_str_t ngx_html_strings[NGX_HTML_NB_PARTS] = {
ngx_string(
“\n”
“\n”
“\t\n”
“\t\n”
“\t\n”
“\t\n”
“”
)
};
/* END html strings */
static ngx_buf_t * ngx_html_buffers;
static ngx_chain_t ngx_html_chain_buffers[NGX_HTML_NB_PARTS];
static ngx_pool_t * ngx_html_buffers_pool;

static char *
ngx_html_chain_buffers_init(ngx_log_t *log){
ngx_int_t i;
ngx_html_buffers_pool = ngx_create_pool(NGX_HTML_NB_PARTS *
sizeof(ngx_buf_t) + sizeof(ngx_pool_t), log);
//TODO TMP ALLOC
ngx_html_buffers = ngx_pcalloc(ngx_html_buffers_pool,
NGX_HTML_NB_PARTS *
sizeof(ngx_buf_t));
if(ngx_html_buffers == NULL){
return NGX_CONF_ERROR;
}
for(i = 0;i < NGX_HTML_NB_PARTS;i++){

ngx_html_buffers[i].pos = ngx_html_strings[i].data;
ngx_html_buffers[i].last = ngx_html_strings[i].data +
        ngx_html_strings[i].len;
ngx_html_buffers[i].file_pos = 0;
ngx_html_buffers[i].file_last = 0;
ngx_html_buffers[i].start = NULL;
ngx_html_buffers[i].end = NULL;
ngx_html_buffers[i].tag = NULL;
ngx_html_buffers[i].file = NULL;
ngx_html_buffers[i].shadow = NULL;
ngx_html_buffers[i].temporary = 0;
ngx_html_buffers[i].memory = 1;
ngx_html_buffers[i].mmap = 0;
ngx_html_buffers[i].recycled = 0;
ngx_html_buffers[i].in_file = 0;
ngx_html_buffers[i].flush = 0;
ngx_html_buffers[i].sync = 0;
ngx_html_buffers[i].last_buf = 0;
ngx_html_buffers[i].last_in_chain = 0;
ngx_html_buffers[i].last_shadow = 0;
ngx_html_buffers[i].temp_file = 0;
ngx_html_buffers[i].num = 0;

ngx_html_chain_buffers[i].buf = &ngx_html_buffers[i];

}
ngx_html_buffers[i].last_buf = 1;
ngx_html_buffers[i].last_in_chain = 1;
return NGX_CONF_OK;
}

static char * ngx_http_diceroll_quickcrab_com(ngx_conf_t *cf,
ngx_command_t
*cmd, void *conf);

static ngx_command_t ngx_http_diceroll_quickcrab_com_commands[] = {
{
ngx_string(“diceroll_quickcrab_com”),
NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
ngx_http_diceroll_quickcrab_com,
0,
0,
NULL
},
ngx_null_command
};

/*

  • The module context has hooks , here we have a hook for creating
  • location configuration
    /
    static ngx_http_module_t ngx_http_diceroll_quickcrab_com_module_ctx = {
    NULL, /
    preconfiguration /
    NULL, /
    postconfiguration /
    NULL, /
    create main configuration /
    NULL, /
    init main configuration /
    NULL, /
    create server configuration /
    NULL, /
    merge server configuration /
    NULL, /
    create location configuration /
    NULL /
    merge location configuration /
    };
    /
  • The module which binds the context and commands
    /
    ngx_module_t ngx_http_diceroll_quickcrab_com_module = {
    NGX_MODULE_V1,
    &ngx_http_diceroll_quickcrab_com_module_ctx, /
    module context /
    ngx_http_diceroll_quickcrab_com_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
    };
    /
  • Main handler function of the module.
    */
    static ngx_int_t
    ngx_http_diceroll_quickcrab_com_handler(ngx_http_request_t *r){
    ngx_int_t rc;
    size_t content_length_n;
    ngx_chain_t * out;
    content_length_n = 0;
    out = &ngx_html_chain_buffers[NGX_HTML_ALL];
    out->next = NULL;
    #ifdef NO_PROBLEM
    out->buf = ngx_pcalloc(r->pool,sizeof(ngx_buf_t));
    out->buf->pos = ngx_html_strings[NGX_HTML_ALL].data;
    out->buf->last = ngx_html_strings[NGX_HTML_ALL].data +
    ngx_html_strings[NGX_HTML_ALL].len;
    out->buf->memory = 1;
    out->buf->last_buf = 1;
    #endif
    content_length_n += ngx_html_strings[NGX_HTML_ALL].len;

/* we response to ‘GET’ and ‘HEAD’ requests only /
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
return NGX_HTTP_NOT_ALLOWED;
}
/
discard request body, since we don’t need it here /
rc = ngx_http_discard_request_body(r);
if (rc != NGX_OK) {
return rc;
}
/
set the ‘Content-type’ header */
r->headers_out.content_type_len = sizeof(“text/html”) - 1;
r->headers_out.content_type.data = (u_char ) “text/html”;
/
send the header only, if the request type is http ‘HEAD’ */
if (r->method == NGX_HTTP_HEAD) {
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = content_length_n;
return ngx_http_send_header(r);
}

/* set the status line /
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = content_length_n;
/
send the headers of your response /
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
return rc;
}
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
“------------------------------------------------”);
/
send the buffer chain of your response /
rc = ngx_http_output_filter(r, out);
return rc;
}
/

  • Function for the directive diceroll_quickcrab_com , it validates its
    value

  • and copies it to a static variable to be printed later
    */
    static char *
    ngx_http_diceroll_quickcrab_com(ngx_conf_t *cf, ngx_command_t *cmd, void
    *conf){
    char * rc;
    ngx_http_core_loc_conf_t *clcf;
    static unsigned already_done = 0;

    if(!already_done) {
    rc = ngx_html_chain_buffers_init(cf->log);
    if (rc != NGX_CONF_OK) return rc;
    already_done = 1;
    }

    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
    clcf->handler = ngx_http_diceroll_quickcrab_com_handler;

    return NGX_CONF_OK;
    }

Here is my nginx.conf:
worker_processes 1;
error_log logs/debug.log debug;
events {
worker_connections 4;
}
http {
server_names_hash_max_size 4;
server_names_hash_bucket_size 4;
server {
listen 127.0.0.1:80 default_server;
server_name _;
return 444;
}
server {
listen 127.0.0.1:80;
server_name localhost 127.0.0.1;
root /var/www/diceroll.quickcrab.com;
location / {
diceroll_quickcrab_com;
}
}
}

Thank you

Posted at Nginx Forum:

Does something is trying to free the buffers directly before freeing the
pool in the output filter?

Posted at Nginx Forum:

In my handler function, the buffer has the 0 value for its last_buf
property. I do not understand as i assign 1 in its initialisation.
Someone
know why does it behave like that?

Posted at Nginx Forum:

Ok i have reread my init function XD
i was affected a value in somewhere random in memory XD, i was really
tired
when i does that.

thank you for those who have read my post.

have an happy new year :smiley:

Posted at Nginx Forum:

Finally, i have to change all as i need a multithreaded environment XD

Posted at Nginx Forum: