Chinaunix首页 | 论坛 | 博客
  • 博客访问: 685545
  • 博文数量: 132
  • 博客积分: 10060
  • 博客等级: 上将
  • 技术积分: 1732
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-21 12:35
个人简介

迷惘的码农。

文章分类

全部博文(132)

文章存档

2013年(1)

2011年(2)

2010年(9)

2009年(41)

2008年(79)

我的朋友

分类: 系统运维

2009-10-24 23:26:36

经过了N多时间的艰苦努力,终于调通了这个Demo;
文档不多,特别是没有Manual、API,一点点摸索、调试,真累,费时费力。

主要功能就是中的过滤器一节中介绍的header过滤器和body过滤器,放在一起;
不过,后者也需要一个header过滤器,因为要设置相关的header。

另外也用到了Handler模块Creating a Hello World! Nginx Module,稍作修改,把内容类型由text/html改为text/plain;
然后在header过滤器中修改回来(text/html),并且设置了编码为UTF-8;
而body过滤器的作用是在输出的结尾添加换行标记(所以需要text/html)和一行文字。

如何编译、运行就不多说了。

上代码,先看nginx.conf的相关部分:

location /hi {
    hello;
}


这个调用hello模块,目的是作对比,输出如下:
Hello, world!


还是nginx.conf,这次是过滤器了:

location /hi_guolvqi {
    hello;
    enable_guolvqi on;
}


这里是由guolvqi(过滤器)模块处理hello模块产生的header和输出,输出如下:
Hello, world!
FIltered by "guolvqi"!


最后是过滤器实现代码:



/*
 * Copyright (C) Joshua Zhu,
 */



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


typedef struct {
        ngx_flag_t enable;
} ngx_http_guolvqi_loc_conf_t;

static u_char post_str[] = "
FIltered by \"guolvqi\"!"
;

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 void* ngx_http_guolvqi_create_loc_conf(ngx_conf_t *cf);
static char* ngx_http_guolvqi_merge_loc_conf(ngx_conf_t *cf,
    void *parent, void *child);


static ngx_int_t
ngx_http_guolvqi_filter_init(ngx_conf_t *cf);

static ngx_command_t ngx_http_guolvqi_commands[] = {
        { ngx_string("enable_guolvqi"),
                NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
                ngx_conf_set_flag_slot,
                NGX_HTTP_LOC_CONF_OFFSET,
                0,
                NULL },

        ngx_null_command
};

static ngx_http_module_t ngx_http_guolvqi_module_ctx = {
        NULL, /* preconfiguration */
        ngx_http_guolvqi_filter_init, /* postconfiguration */

        NULL, /* create main configuration */
        NULL, /* init main configuration */

        NULL, /* create server configuration */
        NULL, /* merge server configuration */

        ngx_http_guolvqi_create_loc_conf, /* create location configuration */
        ngx_http_guolvqi_merge_loc_conf /* merge location configuration */
};


ngx_module_t ngx_http_guolvqi_module = {
        NGX_MODULE_V1,
        &ngx_http_guolvqi_module_ctx, /* module context */
        ngx_http_guolvqi_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 ngx_int_t
ngx_http_guolvqi_header_filter(ngx_http_request_t *r)
{
        // ngx_int_t rc;

        ngx_http_guolvqi_loc_conf_t *conf;

        conf = ngx_http_get_module_loc_conf(r, ngx_http_guolvqi_module);

        // rc = ngx_http_discard_request_body(r);


        if(conf->enable) {
                r->headers_out.charset.len = sizeof("UTF-8") - 1;
                r->headers_out.charset.data = (u_char *)"UTF-8";

                /* set the 'Content-type' header */
                r->headers_out.content_type_len = sizeof("text/html") - 1;
                r->headers_out.content_type.len = sizeof("text/html") - 1;
                r->headers_out.content_type.data = (u_char *) "text/html";

                /* set the status line */
                r->headers_out.status = NGX_HTTP_OK; // NGX_HTTP_NOT_MODIFIED

                // r->headers_out.content_length_n = -1; // += sizeof(post_str) - 1;

                ngx_http_clear_content_length(r);
                // ngx_http_clear_accept_ranges(r);

        }

        return ngx_http_next_header_filter(r);
}

        static ngx_int_t
ngx_http_guolvqi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
        ngx_http_guolvqi_loc_conf_t *conf;
        int has_last = 0;
        ngx_buf_t b; // *b;

        ngx_chain_t nc, *cc, *last;

        if(in == NULL || r->header_only) {
                return ngx_http_next_body_filter(r, in);
        }

        conf = ngx_http_get_module_loc_conf(r, ngx_http_guolvqi_module);
        if(!conf->enable)
                return ngx_http_next_body_filter(r, in);

        for (cc = in; cc != NULL; cc = cc->next) {
                last = cc;
                if (cc->buf->last_buf) {
                        has_last = 1;
                        // cc->buf->sync = 1;

                        cc->buf->last_buf = 0;
                        // cc->buf->last_in_chain = 0;

                        // break;

                }
        }

        if (!has_last)
                return ngx_http_next_body_filter(r, in);

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


        b.pos = post_str;
        b.last = b.pos + sizeof(post_str) - 1;
        b.memory = 1;
        b.last_buf = 1;
        // b.last_in_chain = 1;


        nc.buf = &b;
        nc.next = NULL;

        last->next = &nc;

        return ngx_http_next_body_filter(r, in);
}


        static ngx_int_t
ngx_http_guolvqi_filter_init(ngx_conf_t *cf)
{
        ngx_http_next_header_filter = ngx_http_top_header_filter;
        ngx_http_top_header_filter = ngx_http_guolvqi_header_filter;

        ngx_http_next_body_filter = ngx_http_top_body_filter;
        ngx_http_top_body_filter = ngx_http_guolvqi_body_filter;

        return NGX_OK;
}

static void *
ngx_http_guolvqi_create_loc_conf(ngx_conf_t *cf)
{
    ngx_http_guolvqi_loc_conf_t *conf;

    conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_guolvqi_loc_conf_t));
    if (conf == NULL) {
        return NGX_CONF_ERROR;
    }

    conf->enable = NGX_CONF_UNSET;
    return conf;
}

static char *
ngx_http_guolvqi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
    ngx_http_guolvqi_loc_conf_t *prev = parent;
    ngx_http_guolvqi_loc_conf_t *conf = child;

    ngx_conf_merge_value(conf->enable, prev->enable, 0);

    return NGX_CONF_OK;
}



比较初级,还不完善。

BTW,
怎么不能上传图片了呢?我用qq截的图,不论保存成啥格式,上传了都无法显示,甚至不能下载;
刚才写了一半时候不小心调到别的地方了,后退回来写的东西都丢了,还好打开过文章预览,用FF的“最近关闭的标签页”功能,找了回来。

阅读(2287) | 评论(0) | 转发(0) |
0

上一篇:Nginx 挺有意思

下一篇:构建libev学到的

给主人留下些什么吧!~~