Welcome! Log In Create A New Profile

Advanced

Filter not working

Posted by acacio.centeno 
Filter not working
August 05, 2013 10:15AM
I'm not sure this is the best forum section for questions about writing modules, so feel free to redirect me to a more apropriate section.

I'm reading the Emiller's guide to Nginx module development (http://www.evanmiller.org/nginx-modules-guide.html) about how to write filters. I've copied and pasted his example, the code is been called, but no extra content is being added to the request's body. I thought it could be due to the content-length, tried adding the extra bytes to it and still, no content is being added.

I'd appreciate if someone could tell me what is wrong. The full code is bellow:

#include <ngx_core.h>
#include <ngx_http.h>
#include <ngx_config.h>
#include <ngx_http_request.h>

#define _INFO(args...) do { if ((r->connection->log)->log_level >= NGX_LOG_INFO) ngx_log_error_core(NGX_LOG_INFO, r->connection->log, 0, args); } while(0);

static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;

static ngx_int_t
ngx_http_fetcher_header_filter(ngx_http_request_t* r) {
_INFO("LENGTH BEFORE [%d]", r->headers_out.content_length_n);
r->headers_out.content_length_n += sizeof("<!-- Served by Nginx -->") - 1;
_INFO("LENGTH AFTER [%d]", r->headers_out.content_length_n);

return ngx_http_next_header_filter(r);
}

static ngx_int_t
ngx_http_fetcher_filter(ngx_http_request_t* r, ngx_chain_t* in) {
ngx_chain_t *chain_link;
int chain_contains_last_buffer = 0;
ngx_int_t rc;

_INFO("LENGTH INSIDE THE BODY FILTER [%d]", r->headers_out.content_length_n);

chain_link = in;
for ( ; ; ) {
if (chain_link->buf->last_buf)
chain_contains_last_buffer = 1;
if (chain_link->next == NULL)
break;
chain_link = chain_link->next;
}

if (!chain_contains_last_buffer) {
_INFO("NOTHING TO DO");
return ngx_http_next_body_filter(r, in);
}

ngx_buf_t *b;
b = ngx_calloc_buf(r->pool);
if (b == NULL) {
return NGX_ERROR;
}

b->pos = (u_char *) "<!-- Served by Nginx -->";
b->last = b->pos + sizeof("<!-- Served by Nginx -->") - 1;

ngx_chain_t *added_link;

added_link = ngx_alloc_chain_link(r->pool);
if (added_link == NULL)
return NGX_ERROR;

added_link->buf = b;
added_link->next = NULL;

chain_link->next = added_link;

chain_link->buf->last_buf = 0;
added_link->buf->last_buf = 1;

_INFO("ALL DONE, COMMENT HAS BEEN ADDED.");

rc = ngx_http_next_body_filter(r, in);

return rc;
}

static ngx_int_t
ngx_http_fetcher_filter_init(ngx_conf_t* cf) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"Instalando o filtro");

ngx_http_next_header_filter = ngx_http_top_header_filter;
ngx_http_top_header_filter = ngx_http_fetcher_header_filter;

ngx_http_next_body_filter = ngx_http_top_body_filter;
ngx_http_top_body_filter = ngx_http_fetcher_filter;

return NGX_OK;
}

static ngx_http_module_t ngx_http_fetcher_module_ctx = {
NULL, /* preconfiguration */
ngx_http_fetcher_filter_init, /* 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 */
};

ngx_module_t ngx_http_fetcher_module = {
NGX_MODULE_V1,
&ngx_http_fetcher_module_ctx, /* module context */
NULL, /* 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
};




The log file tells me that the filter has been called and has added the new buffer to the chain:

2013/08/05 11:05:09 [info] 9766#0: *1 LENGTH BEFORE [95] while sending response to client, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost"
2013/08/05 11:05:09 [info] 9766#0: *1 LENGTH AFTER [119] while sending response to client, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost"
2013/08/05 11:05:09 [info] 9766#0: *1 LENGTH INSIDE THE BODY FILTER [119] while sending response to client, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost"
2013/08/05 11:05:09 [info] 9766#0: *1 ALL DONE, COMMENT HAS BEEN ADDED. while sending response to client, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost"
2013/08/05 11:05:11 [info] 9766#0: *1 client 127.0.0.1 closed keepalive connection
Re: Filter not working
August 05, 2013 01:23PM
For the record, I found out how to make it work; I must set the buffer I create as being in memory, or the function ngx_buf_size() returns 0. Reading it's deffinition, we can see that it's meant to do so:

#define ngx_buf_size(b) \
(ngx_buf_in_memory(b) ? (off_t) (b->last - b->pos): \
(b->file_last - b->file_pos))

But the reason behind this decision is not clear to me.
Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 199
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 500 on July 15, 2024
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready