http module handler, chain buffer and output_filter

xdiaod nginx-forum at nginx.us
Tue Dec 30 04:11:54 UTC 2014


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(
		"<!DOCTYPE html>\n"
		"<html>\n"
			"\t<head>\n"
			"\t</head>\n"
			"\t<body>\n"
			"\t</body>\n"
		"</html>"
	)
};
/* 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: http://forum.nginx.org/read.php?2,255866,255866#msg-255866



More information about the nginx mailing list