2. nginx第一个模块详解(hello world/)

抛去那些琐碎的对nginx的介绍,直接开始第一个nginx http的程序。

"hello world",此模块中包括get、post的处理,


1. 首先 mkdir "path"/ngx_http_hello_world

cd  "path"/ngx_http_hello_workd

2. 新建文件: vi   config

如下:

ngx_addon_name=ngx_http_hello_world_module
HTTP_MODULES="$HTTP_MODULES ngx_http_hello_world_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_hello_world_module.c"

3. 新建.c 文件: vi ngx_http_hello_world_module.c


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


static char *ngx_http_hello_world(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);


static ngx_command_t  ngx_http_hello_world_commands[] = {

ngx_string("hello_world"),
    NGX_HTTP_LOC_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_NOARGS,
    ngx_http_hello_world,
    0,
    0,
    NULL },


    ngx_null_command
};


static ngx_http_module_t  ngx_http_hello_world_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 */
};




ngx_module_t ngx_http_hello_world_module = {
  NGX_MODULE_V1,
  &ngx_http_hello_world_module_ctx, /* module context */
  ngx_http_hello_world_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编码 转 UTF-8,因为我这里接受到的消息体是URL编码,如果不是可以不用这个函数
void urldecode1(char *p)  
{  
printf("strlen(p): %d\n",(int)strlen(p));
int i=0;  
while(*(p+i))  
{  
  if ((*p=*(p+i)) == '%')  
  {  
   *p=*(p+i+1) >= 'A' ? ((*(p+i+1) & 0XDF) - 'A') + 10 : (*(p+i+1) - '0');  
   *p=(*p) * 16;  
   *p+=*(p+i+2) >= 'A' ? ((*(p+i+2) & 0XDF) - 'A') + 10 : (*(p+i+2) - '0');  
   i+=2;  
  }  
  else if (*(p+i)=='+')  
  {  
   *p=' ';  
  }  
  p++;  
}  
*p='\0';  

}  


//将post方法中的消息正文取出
static char *ngx_http_get_body(ngx_http_request_t *r,int length)
{
char *data_buf;


if(rb->temp_file == NULL)
{
data_buf = (char *)malloc(length+1);

ngx_chain_t* bufs = r->request_body->bufs;
ngx_buf_t* buf = NULL;

int buf_length;
int all_length = 0;
while(bufs)
{
printf("<%d>\n",__LINE__);
buf = bufs->buf;
bufs = bufs->next;

buf_length = buf->last - buf->pos;
printf("buf_length: %d\n",buf_length);
if(all_length + buf_length > length)
{
memcpy(data_buf+all_length,buf->pos,length - all_length);
all_length = length;

urldecode1((char *)buf->pos);
break;
}

memcpy(data_buf+all_length,buf->pos,buf_length);
all_length += buf_length;
}
if(all_length)
data_buf[all_length] = '\0';
}

return data_buf;
}

//正在的处理函数
static void ngx_http_hello_world_handler(ngx_http_request_t *r)
{

ngx_http_request_body_t   *rb;
rb = r->request_body;


if(rb->temp_file != NULL)
{
printf("rb->temp_file != NULL\n");
while(a)
{
a = read(rb->temp_file->file.fd,data_buf,1024);
b += a;
printf("b: %d\n",b);
}
}

char   *ngx_hello_world = "hello world";
char *data_buf;
ngx_buf_t     *b; //返回所需
  ngx_chain_t   out;

if(r->method == NGX_HTTP_HEAD)  
  {
  printf("r->method == NGX_HTTP_HEAD\n");  
  }
  if(r->method == NGX_HTTP_GET)
  {
    printf("r->method == NGX_HTTP_GET\n");  
  }
  if(r->method == NGX_HTTP_POST)   //请求方法为post,则有content消息体
  {
    printf("r->method == NGX_HTTP_POST\n");
    int length = atoi( (char*)(r->headers_in.content_length->value.data));

/*
*传输数据不超过10K,超过10k,nginx会自动post的content(消息体)存放到临时文件
*rb->temp_file->file.fd(文件描述符)
*read(rb->temp_file->file.fd,data_buf,1024);  可以循环读出来数据
*/

if(rb->temp_file == NULL)   
{
data_buf = ngx_http_get_body(r,length);
urldecode1(data_buf);  //url - utf-8
}

/*######################*/
/*##### 功能处理函数 ###*/
/*######################*/  

  }
  
  r->headers_out.content_type.len = sizeof("text/html") - 1;  
  r->headers_out.content_type.data = (u_char *) "text/html";  //如果是"text/plain",在浏览器访问时会直接下载一个文件


  b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));


  out.buf = b;
  out.next = NULL;

  b->pos = (u_char *)ngx_hello_world;   //返回的数据,这里随便给的“hello world”
  b->last = (u_char *)ngx_hello_world + strlen(ngx_hello_world);
  b->memory = 1;
  b->last_buf = 1;


  r->headers_out.status = NGX_HTTP_OK;// 发送状态码
  r->headers_out.content_length_n = strlen(ngx_hello_world);// 发送内容长度
    
  ngx_http_send_header(r);   
  ngx_http_output_filter(r, &out);
  
  ngx_http_finalize_request(r, 0);
  
}

//调用nginx中的函数ngx_http_read_client_request_body(),
static ngx_int_t ngx_http_hello_world_urlquery_handler(ngx_http_request_t *r)
{
printf("%s() \n",__func__);

ngx_int_t rc = NGX_DONE;
   rc = ngx_http_read_client_request_body(r, ngx_http_hello_world_handler);   //post方法是,读取content(消息体)
   if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
     return rc;
   }


   return NGX_DONE;
}


//回调
static char *ngx_http_hello_world(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
  ngx_http_core_loc_conf_t  *clcf;


  clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
  clcf->handler = ngx_http_hello_world_urlquery_handler;


  return NGX_CONF_OK;
}

自己看此代码,几个回调函数结合,并不复杂。

4.  下载nginx源码,可在官网下载,我的资源中也有,大家可以去下载

tar xvf  nginx-1.6.1.tar.zxf

cd nginx-1.6.1

./configure -add-module="path"/ngx_http_hello_world --prefix="path" ( --add-module=  的意思是挂载模块,--prefix= 的意思是的可执行文件的存放目录)

make && make install

5. 修改配置文件

a. cd 到 “--prefix=”所指定的目录,有目录


b. vi conf/nginx.conf

c. 修改为

daemon off; #关闭daemon模式
worker_processes 1;
events {
    worker_connections 1024;
}

http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    server {
        listen 10000; #端口
        server_name localhost;
        location / {
            root html;
            index index.html index.htm;
                }
                location /hello {  

hello_world

                }
        }
}

6.cd sbin

  ./nginx

  在浏览器输入 localhost/hello

  输出: hello world


注: 结合网上很多资料,并加以注释,使更加易懂,原创,转载注明出处。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值