这是由前面的一个最简单的例子修改而成的。
前面的例子是从配置文件中读取内容,并显示。
这个例子是从url变量中读取内容并显示。
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
static char* ngx_echo_readconf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static void* ngx_echo_create_loc_conf(ngx_conf_t *cf);
static char* ngx_echo_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child);
ngx_int_t ngx_http_hi_module_init(ngx_conf_t *cf);
typedef struct {
ngx_str_t ecdata;
ngx_flag_t enable;
} ngx_echo_loc_conf_t;
// 读取配置文件内容 echo -> ecdata
// 1、ngx_echo_readconf是程序第一步
static ngx_command_t ngx_echo_commands[] = {
{ ngx_string("echo"),
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_echo_readconf,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_echo_loc_conf_t, ecdata),
NULL },
ngx_null_command
};
static ngx_http_module_t ngx_echo_module_ctx = {
NULL, /* preconfiguration */
ngx_http_hi_module_init, /* postconfiguration 从配置文件中读取key定义 */
NULL, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
NULL, /* merge server configuration */
ngx_echo_create_loc_conf, /* create location configuration */
ngx_echo_merge_loc_conf /* merge location configuration */
};
//////////////////////
// 定义模块 //
//////////////////////
ngx_module_t ngx_http_hi_module = {
NGX_MODULE_V1,
&ngx_echo_module_ctx, /* module context */
ngx_echo_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
};
// 获得URL参数
static ngx_int_t ngx_http_key_index;
static ngx_str_t ngx_http_key_value = ngx_string("key");
ngx_http_variable_value_t *key_vv;
static ngx_int_t
ngx_http_hi_module_variable_not_found(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
v->not_found = 1;
return NGX_OK;
}
static ngx_int_t
ngx_http_hi_module_add_variable(ngx_conf_t *cf, ngx_str_t *name) {
ngx_http_variable_t *v;
v = ngx_http_add_variable(cf, name, NGX_HTTP_VAR_CHANGEABLE);
if (v == NULL) {
return NGX_ERROR;
}
v->get_handler = ngx_http_hi_module_variable_not_found;
return ngx_http_get_variable_index(cf, name);
}
//////////////////////
// 主要的处理函数
//////////////////////
static ngx_int_t
ngx_echo_handler(ngx_http_request_t *r)
{
printf("called:ngx_echo_handler/n");
////////////////////////////////////////////
// 读取URL里面具体的key变量的值
////////////////////////////////////////////
key_vv = ngx_http_get_indexed_variable(r,
ngx_http_key_index);
// printf("read URL key idx:%d/n",ngx_http_key_index);
// printf("read URL key:%s/n",key_vv->data);
ngx_int_t rc;
ngx_buf_t *b;
ngx_chain_t out;
ngx_echo_loc_conf_t *cglcf;
cglcf = ngx_http_get_module_loc_conf(r, ngx_http_hi_module);
// 限制请求的方法
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
return NGX_HTTP_NOT_ALLOWED;
}
if (r->headers_in.if_modified_since) {
return NGX_HTTP_NOT_MODIFIED;
}
r->headers_out.content_type.len = sizeof("text/html") - 1;
r->headers_out.content_type.data = (u_char *) "text/html";
r->headers_out.status = NGX_HTTP_OK; // 发送状态码
// r->headers_out.content_length_n = cglcf->ecdata.len;
r->headers_out.content_length_n = key_vv->len; // 发送内容长度
if (r->method == NGX_HTTP_HEAD) {
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
return rc;
}
}
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
if (b == NULL) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate response buffer.");
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
////////////////////////////////////////////
// 定义输出
////////////////////////////////////////////
out.buf = b;
out.next = NULL;
// b->pos = cglcf->ecdata.data;
// b->last = cglcf->ecdata.data+(cglcf->ecdata.len);
////////////////////////////////////////////
// 给输出复制
////////////////////////////////////////////
b->pos = key_vv->data;
b->last = key_vv->data+(key_vv->len);
b->memory = 1;
b->last_buf = 1;
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
return rc;
}
return ngx_http_output_filter(r, &out); // 交给过滤器
}
//////////////////////
// 读取配置 echo
//////////////////////
static char *
ngx_echo_readconf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
printf("called:ngx_echo_readconf/n");
ngx_http_core_loc_conf_t *clcf;
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf->handler = ngx_echo_handler; // 2、主要的处理函数:ngx_echo_handler是程序第二步
ngx_conf_set_str_slot(cf,cmd,conf);
return NGX_CONF_OK;
}
static void *
ngx_echo_create_loc_conf(ngx_conf_t *cf)
{
printf("called:ngx_echo_create_loc_conf/n");
ngx_echo_loc_conf_t *conf;
conf = ngx_pcalloc(cf->pool, sizeof(ngx_echo_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
}
conf->ecdata.len=0;
conf->ecdata.data=NULL;
conf->enable = NGX_CONF_UNSET;
return conf;
}
static char *
ngx_echo_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
printf("called:ngx_echo_merge_loc_conf/n");
ngx_echo_loc_conf_t *prev = parent;
ngx_echo_loc_conf_t *conf = child;
ngx_conf_merge_str_value(conf->ecdata, prev->ecdata, 10);
ngx_conf_merge_value(conf->enable, prev->enable, 0);
return NGX_CONF_OK;
}
//////////////////////
// 从配置文件中读取key定义
//////////////////////
ngx_int_t
ngx_http_hi_module_init(ngx_conf_t *cf)
{
printf("called:ngx_http_hi_module_init/n");
// 读key参数
if ((ngx_http_key_index = ngx_http_hi_module_add_variable(
cf, &ngx_http_key_value)) == NGX_ERROR)
{
return NGX_ERROR;
}
return NGX_OK;
}
下面是配置文件
worker_processes 1;
daemon off;
master_process off;
error_log /tmp/error.log debug;
pid /tmp/nginx_demo.pid;
events {
worker_connections 1024;
}
http {
#include /etc/nginx/mime.types;
sendfile on;
keepalive_timeout 65;
tcp_nodelay on;
server {
listen 8100;
server_name localhost;
access_log /tmp/access.log;
error_log /tmp/error.log debug;
location /hello {
set $key $arg_key;
echo "abcd";
}
}
}
访问方法
http://10.1.6.100:8100/hello?key=012sadf