ngxin开发笔记_配置项

ngxin开发笔记_配置项

模块的配置项即nginx.conf中的指令,HTTP模块指令可以分为三个级别:

  • main级,直接写在http{}块中的指令
  • server级,写在server{}块中的指令
  • location级,写在location{}块中的指令

配置项定义模板

在自定义模块中使用配置项,需要配置ngx_module_t的commands属性以及ctx属性,并需要定义一个结构体用于存放配置信息。

常用的模板如下:

/* 存放配置信息的自定义结构体 */
typedef struct
{
    ngx_flag_t        my_flag;
} ngx_http_mytest_conf_t;

/* 模块声明 */
ngx_module_t  ngx_http_mytest_module =
{
    NGX_MODULE_V1,
    &ngx_http_mytest_module_ctx,           /* module context */
    ngx_http_mytest_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_http_module_t  ngx_http_mytest_module_ctx =
{
    ngx_http_mytest_pre_conf,          /* preconfiguration */
    ngx_http_mytest_post_conf,         /* postconfiguration */
    ngx_http_mytest_create_main_conf,  /* create main configuration */
    ngx_http_mytest_init_main_conf,    /* init main configuration */
    ngx_http_mytest_create_srv_conf,   /* create server configuration */
    ngx_http_mytest_merge_srv_conf,    /* merge server configuration */
    ngx_http_mytest_create_loc_conf,   /* create location configuration */
    ngx_http_mytest_merge_loc_conf     /* merge location configuration */
};

/* 自定义的配置项 */
static ngx_command_t  ngx_http_mytest_commands[] =
{
    {
        ngx_string("test_flag"),
        NGX_HTTP_LOC_CONF | NGX_CONF_FLAG,
        ngx_conf_set_flag_slot,
        NGX_HTTP_LOC_CONF_OFFSET,
        offsetof(ngx_http_mytest_conf_t, my_flag),
        NULL
    },
    ngx_null_command
};

配置项信息

配置项信息通过ngx_command_t类型指定

struct ngx_command_s {
    ngx_str_t             name;
    ngx_uint_t            type;
    char               *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    ngx_uint_t            conf;
    ngx_uint_t            offset;
    void                 *post;
};
  • name 命令名称
  • type 设置配置项允许在哪些配置块中使用、配置项携带的参数个数、参数形式信息。具体可以参考ngx_conf_file.h和P116 表4-1。常用选项如下
  /*
   *        AAAA  number of arguments
   *      FF      command flags
   *    TT        command type, i.e. HTTP "location" or "server" command
   */
  #define NGX_HTTP_MAIN_CONF        0x02000000
  #define NGX_HTTP_SRV_CONF         0x04000000
  #define NGX_HTTP_LOC_CONF         0x08000000

  #define NGX_CONF_BLOCK       0x00000100
  #define NGX_CONF_FLAG        0x00000200
  #define NGX_CONF_ANY         0x00000400
  #define NGX_CONF_1MORE       0x00000800
  #define NGX_CONF_2MORE       0x00001000

  #define NGX_CONF_NOARGS      0x00000001
  #define NGX_CONF_TAKE1       0x00000002
  #define NGX_CONF_TAKE2       0x00000004
  #define NGX_CONF_TAKE3       0x00000008
  #define NGX_CONF_TAKE4       0x00000010
  • set属性指定配置项解析函数,ngx提供了12个常用的解析函数如下所示,解析的格式可以参考P118 表4-2 。也可以实现自定义的解析函数。
char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_str_array_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
  • conf 用于指定配置项的偏移,与后文的create_xxx_conf回调函数有关。例如配置项是通过create_loc_conf函数创建的,此处的配置就应该为NGX_HTTP_LOC_CONF_OFFSET。

可选参数如下:

#define NGX_HTTP_MAIN_CONF_OFFSET  offsetof(ngx_http_conf_ctx_t, main_conf)
#define NGX_HTTP_SRV_CONF_OFFSET   offsetof(ngx_http_conf_ctx_t, srv_conf)
#define NGX_HTTP_LOC_CONF_OFFSET   offsetof(ngx_http_conf_ctx_t, loc_conf)
  • offset 用于指定配置项关联的结构体字段的偏移,一般使用offsetof宏设置。
  • post指针,传递给set函数的参数,具体含义根据set函数而定。

配置项创建与合并

配置项创建与合并主要通过ngx_http_module_t的回调函数实现。

typedef struct {
    ngx_int_t   (*preconfiguration)(ngx_conf_t *cf);
    ngx_int_t   (*postconfiguration)(ngx_conf_t *cf);
    void       *(*create_main_conf)(ngx_conf_t *cf);
    char       *(*init_main_conf)(ngx_conf_t *cf, void *conf);
    void       *(*create_srv_conf)(ngx_conf_t *cf);
    char       *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);
    void       *(*create_loc_conf)(ngx_conf_t *cf);
    char       *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
} ngx_http_module_t;

其中preconfigurationpostconfiguration相对好理解,在配置项创建整体前后分别回调。

create_main_confcreate_srv_confcreate_loc_conf三个函数的回调次数与nginx中具体的配置有关。以如下配置为例:

http {
    test_str SUPERMAN;
    server {
        server_name HOST1;
        location /HOST1_loc1 {
            test_str    loc1_BANANA;
        }
        location /HOST1_loc2 {
        }
    }
    server {
        server_name HOST2;
        test_str CAR;
        location /index {
            test_str FOCUS;
        }
        location /test {
            test_str    PLANE;
        }
        location = /50x.html {
        }
    }
}

HTTP模块遇到http{}配置块时将调用create_main_conf、create_srv_conf、create_loc_conf三个函数,遇到server{}块时将调用create_srv_conf、create_loc_con两个函数、遇到location{}块时将调用create_loc_con函数。所以以上配置create_main_conf将被调用1次,create_srv_conf被调用3次,create_loc_conf被调用8次。一般HTTP模块都仅使用loc级的配置。

create_xxx_conf函数中一般的内容为创建自定义配置结构体,并设置初始值。常见如下:

static void *
ngx_http_sub_create_conf(ngx_conf_t *cf)
{
    ngx_http_sub_loc_conf_t  *slcf;

    slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_sub_loc_conf_t));
    if (slcf == NULL) {
        return NULL;
    }

    slcf->once = NGX_CONF_UNSET;
    slcf->last_modified = NGX_CONF_UNSET;

    return slcf;
}

上文中提到在http{}和server{}中都会调用create_loc_conf,那么在具体处理请求时将使用那个级别的的配置,则由init_main_conf、merge_srv_conf、merge_loc_conf回调函数决定。已merge_loc_conf为例

(merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);

prev指针为父级配置的结构体,conf为子级配置的结构体。一个常用的思路时:如果子级没有配置则复用父级的,常用方式如下:

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

    ngx_conf_merge_str_value(conf->my_str, prev->my_str, "defaultstr");
    return NGX_CONF_OK;
}

ngx_conf_merge_str_value是合并str类型的宏,其他宏还包括

#define ngx_conf_merge_value(conf, prev, default)
#define ngx_conf_merge_ptr_value(conf, prev, default)
#define ngx_conf_merge_uint_value(conf, prev, default)
#define ngx_conf_merge_msec_value(conf, prev, default)
#define ngx_conf_merge_sec_value(conf, prev, default)
#define ngx_conf_merge_size_value(conf, prev, default)
#define ngx_conf_merge_off_value(conf, prev, default)
#define ngx_conf_merge_str_value(conf, prev, default)
#define ngx_conf_merge_bufs_value(conf, prev, default_num, default_size)
#define ngx_conf_merge_bitmask_value(conf, prev, default)

注意merge_loc_conf与create_loc_conf类似,在三个级别中会被调用多次,以上文的配置示例来说,merge_loc_conf会被调用7次,比create_loc_conf少1次,因为http{}不需要merge。

【此处的设计逻辑个人还没想理解十分明白,初步理解分三层配置用于一个模块中http{}srv{}loc{}需要定义使用不同conf_t结构体的场景,反复调用create函数是为了实现可以选择是否复用(merge)父级的功能。】

配置项获取

一般可以通过ngx_http_request_t r变量或者ngx_conf_t cf变量获取配置项的内容。常用的接口如下

#define ngx_http_get_module_main_conf(r, module)
#define ngx_http_get_module_srv_conf(r, module)
#define ngx_http_get_module_loc_conf(r, module)

#define ngx_http_conf_get_module_main_conf(cf, module)
#define ngx_http_conf_get_module_srv_conf(cf, module)
#define ngx_http_conf_get_module_loc_conf(cf, module)

示例代码如下:

static ngx_int_t
ngx_http_addition_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
    ...
    ngx_http_addition_conf_t  *conf;
    ...
    conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module);
}
时间: 2024-10-30 16:26:49

ngxin开发笔记_配置项的相关文章

九、Android学习笔记_ Android开发中使用软引用和弱引用防止内存溢出

在<Effective Java 2nd Edition>中,第6条"消除过期的对象引用"提到,虽然Java有 垃圾回收机制,但是只要是自己管理的内存,就应该警惕内存泄露的问题,例如的对象池.缓存中的过期对象都有可能引发内存泄露的问题.书中还提到可以用 WeakHashMap来作为缓存的容器可以有效解决这一问题.之前也确实遇到过类似问题,但是没有接触过"弱引用"相关的问题,于是查阅了一些资料. <Java 理论与实践: 用弱引用堵住内存泄漏>

微信订阅号开发笔记(二)

微信开发的流程其实很简单 o(∩_∩)o 哈哈!在微信网站的编辑操作 额,就不说了.虽然有人问过.下面是我的微信开发过程,简单记录下. 成为开发者 材料:1.自己的服务器资源,百度的BAE,新浪的SAE都不错. 2.懂那么点编程语言. 3.注册微信公众号. 上面的都有了之后,就可以自己动手开发了.哇咔咔,好兴奋.有木有. 在登录进去之后,怎么成为开发者?不知道,自己看去. 开始coding吧. 1.验证 if (! empty ( $_GET ['echostr'] ) && ! empt

[开发笔记]-未找到与约束ContractName Microsoft.VisualStudio.Text.ITextDocumentFactoryService...匹配的导出【转载自:酷小孩】

原文地址:http://www.cnblogs.com/babycool/p/3199158.html 今天打算用VisualStudio2012做一个js效果页面测试的时候,打开VS2012新建项目,但是并没有像之前那样顺利的创建页面,而是弹出了一个错误窗口. 我的系统是win8专业版 64位 ,同时安装了VS2010和VS2012.然后我又试了一下VS2010,新建项目.新建网站等等,一切正常. 额,看来这个问题就是只和VS2012有关系了. 百度一番之后,找到了两篇文章: vs2012建立

微信公众平台开发笔记

从寒假自己就開始拿微信公众平台开发当练手,到如今断断续续已经挺久了,仅仅只是忙于其它事写代码的时间还是非常少,但总体的框架已经搭起来了.公众微信号就不用给了,我不求粉,仅仅是来总结一下技术问题,再拖非常多东西都忘掉了.= = 粗略算了一下,代码量已经接近 2000 行,可是提取出来的技术问题好像没多少....囧...只是好歹也码了这么多,做个纪念也是应该的....O(∩_∩)O哈哈~ 1. SAE 数据库的连接.须要主机名和port,以后的使用是一样的. @ $db = new mysqli(S

十五、Android学习笔记_授权过程

1.需要申请App Key和App Secret.不同的开发平台有不同的接入方式,可以参考文档,然后将这两个值放进去. 2.通过OAuth类实现认证,它会自动跳转到认证界面,进行授权,成功之后需要处理回调接口. 3.在第二步调用回调接口时,它会返回用户的基本信息,比如用户id.此时需要将用户id信息保存起来,为后面登录做准备.回调接口的写法就为myapp://AuthorizeActivity,其中scheme全部为小写字母. <activity android:name="com.wei

李兴华JavaWeb开发笔记

李兴华JavaWeb开发笔记 1.Java语法-基础 环境变量-JAVA_HOME, PATH, ClassPath 变量名 作用 举例 JAVA_HOME 指向JDK目录 C:\Program Files\Java\jdk1.7.0_21 PATH 指向java.exe目录. %JAVA_HOME%\bin; %JAVA_HOME%\jre\bin CLASSPATH 执行.jar文件.zip文件..class文件所在目录. (程序要用到哪些.class文件,) %JAVA_HOME%\lib

上课笔记_使用DWR实现自动补全 类似百度搜索框的自动显示效果

使用DWR实现自动补全 自动补全:是指用户在文本框中输入前几个字母或汉字的时候,自动在存放数据的文件或数据库中将所有以这些字母或汉字开头的数据提示给用户供用户选择 在日常上网过程中,我们经常使用搜索引擎,当我们输入想要检索的关键字时,搜索引擎会提示我们相关的关键字 训练要点: 掌握使用DWR框架开发Ajax程序 使用MyEclipse 10.0 + MySql5.0 新建数据库:可以手动随便新建一个测试用的 DROP TABLE IF EXISTS `books`; CREATE TABLE `

安卓开发笔记——高仿新浪微博文字处理(实现关键字高亮,自定义表情替换并加入点击事件实现)

先让大家看下效果图,这个是我自己在闲暇时间仿写的新浪微博客户端: 今天来讲讲如何实现上图的效果,这里需要用到SpannableString这个工具类,如果你对这个类并不熟悉,可以先看下我之前写的2篇文章: <安卓开发笔记——个性化TextView(新浪微博)>:http://www.cnblogs.com/lichenwei/p/4411607.html <安卓开发笔记——丰富多彩的TextView>:http://www.cnblogs.com/lichenwei/p/46120

[开发笔记]-MarkDown语法

马克飞象MarkDown在线编辑器 http://maxiang.info/?basic 1. H1--H6 相应数量的# 2. 底线形式 = H1(最高阶标题)和- H2(第二阶标题) 3. 段落和换行 使用一个或多个 空行 分隔内容段来生成段落 (<p>) 在行末输入2个或以上 空格 再回车来生成换行(<br>) 4. 强调 被1个*或_包围起来的文字将会被<em>标签包围 被2个*或_包围起来的文字将会被<strong>标签包围 注:如果你的 * 和