基于Nginx新增实现自己的HTTP模块

来源:互联网 发布:csp是什么软件 编辑:程序博客网 时间:2024/06/05 10:56

创建文件夹 nginx-test-module , 和nginx-1.9.15同级目录。

nginx-test-module目录中创建 ngx_http_lktest_module.c 和 config

ngx_http_lktest_module.c

#include <ngx_config.h>#include <ngx_core.h>#include <ngx_http.h>//请求包体接收完后回调的函数void ngx_http_lktest_body_handler(ngx_http_request_t *r){}//HTTP的HTTP_CONTENT_PHASE阶段lktest模块介入处理http请求内容static ngx_int_t ngx_http_lktest_handler(ngx_http_request_t *r){        //必须时GET或者HEAD方法,否则返回405 Not Allowed        if(!(r->method &(NGX_HTTP_GET | NGX_HTTP_HEAD)))        {                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "weijl NGX_HTTP_NOT_ALLOWED");                return NGX_HTTP_NOT_ALLOWED;        }        //丢弃请求中的包体        ngx_int_t rc = ngx_http_discard_request_body(r);        if(rc != NGX_OK)        {                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "weijl rc=%d", rc);                return rc;        }        /*设置返回的Content_Type。注意,ngx_str_t有一个非常方便的初始化宏ngx_string,它能够把ngx_str_t的data和len成员都设置好*/        ngx_str_t type = ngx_string("text/plain");        //返回的包体内容        ngx_str_t response = ngx_string("Hello world! lk !");        ngx_str_t ress = ngx_string("<html>\r\n<head>\r\n<title>Welcome to nginx!</title>\r\n</head>\r\n<body bgcolor=\"white\" text=\"black\">\r\n<center><h1>Welcome to 192.168.0.7</h1></center>\r\n</body>\r\n</html>\r\n");        //设置返回状态码        r->headers_out.status = NGX_HTTP_OK;        //响应包是由包体内容的,须要设置Conten-Length长度        r->headers_out.content_length_n = response.len + ress.len;        //设置Content-Type        r->headers_out.content_type = type;        //发送HTTP头部        rc = ngx_http_send_header(r);        if(rc == NGX_ERROR || rc > NGX_OK || r->header_only)        {                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "weijl rc=%d", rc);                return rc;        }        //构造ngx_buf_t结构体准备发送包体        ngx_buf_t *b, *bs;        b = ngx_create_temp_buf(r->pool, response.len);        if(NULL == b)        {                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "weijl b=NULL");                return NGX_HTTP_INTERNAL_SERVER_ERROR;        }        //将Hello World拷贝到ngx_buf_t指向的内存中        ngx_memcpy(b->pos, response.data, response.len);        //注意,一定要设置好last指针        b->last = b->pos + response.len;        //声明这是最后一块缓冲区        b->last_buf = 0;        bs = ngx_create_temp_buf(r->pool, ress.len);        if(NULL == bs)        {                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "weijl bs=NULL");                return NGX_HTTP_INTERNAL_SERVER_ERROR;        }        //将ress拷贝到ngx_buf_t指向的内存中        ngx_memcpy(bs->pos, ress.data, ress.len);        //注意,一定要设置好last指针        bs->last = bs->pos + ress.len;        //声明这是最后一块缓冲区        bs->last_buf = 1;        //构造发送时的ngx_chain_t结构体        ngx_chain_t out, outs;        out.buf = b;        //设置next为NULL        out.next = &outs;        outs.buf = bs;        outs.next = NULL;        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "weijl 最后一步为发送包体。发送结束后HTTP框架会调用ngx_http_finalize_request方法结束请求\n");        //最后一步为发送包体。发送结束后HTTP框架会调用ngx_http_finalize_request方法结束请求        return ngx_http_output_filter(r, &out);}//没有什么工作必须在HTTP框架初始化时完毕,不必实现ngx_http_module_t的8个回调方法static ngx_http_module_t ngx_http_lktest_module_ctx ={        NULL,        NULL,        NULL,        NULL,        NULL,        NULL,        NULL,        NULL};//“lktest”配置项解析的回调方法static char *ngx_http_lktest(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_lktest_handler;        return NGX_CONF_OK;}//lktest配置项的处理static ngx_command_t  ngx_http_lktest_commands[] = {        {ngx_string("lktest"),        NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS,        ngx_http_lktest,//在出现配置项lktest时调用ngx_http_lktest解析        NGX_HTTP_LOC_CONF_OFFSET,        0,        NULL},        //很多其它的配置项能够在这里定义        ngx_null_command};//定义lktest模块ngx_module_t  ngx_http_lktest_module = {    NGX_MODULE_V1,    &ngx_http_lktest_module_ctx,             /* module context */    ngx_http_lktest_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};

config

ngx_addon_name=ngx_http_lktest_moduleHTTP_MODULES="$HTTP_MODULES ngx_http_lktest_module"NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_lktest_module.c"

至此,自定义模块就写好了。下面配置nginx
修改/usr/local/nginx/conf/nginx.conf

#user  nobody;worker_processes  1;#error_log  logs/error.log;#error_log  logs/error.log  notice;#error_log  logs/error.log  info;#pid        logs/nginx.pid;events {    worker_connections  1024;}http {    include       mime.types;    default_type  application/octet-stream;    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '    #                  '$status $body_bytes_sent "$http_referer" '    #                  '"$http_user_agent" "$http_x_forwarded_for"';    #access_log  logs/access.log  main;    sendfile        on;    #tcp_nopush     on;    #keepalive_timeout  0;    keepalive_timeout  65;    #gzip  on;    server {        listen       80;        server_name  localhost;        #charset koi8-r;        #access_log  logs/host.access.log  main;        location / {            root   html;            index  index.html index.htm;        }        #error_page  404              /404.html;        # redirect server error pages to the static page /50x.html        #        error_page   500 502 503 504  /50x.html;        location = /50x.html {            root   html;        }        #静态图片资源        location /image/ {            root /home/workspace/;            autoindex on;        }        #自定义模块,新加的在此        location /test {            lktest;            root html;        }        # proxy the PHP scripts to Apache listening on 127.0.0.1:80        #        #location ~ \.php$ {        #    proxy_pass   http://127.0.0.1;        #}        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000        #        #location ~ \.php$ {        #    root           html;        #    fastcgi_pass   127.0.0.1:9000;        #    fastcgi_index  index.php;        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;        #    include        fastcgi_params;        #}        # deny access to .htaccess files, if Apache's document root        # concurs with nginx's one        #        #location ~ /\.ht {        #    deny  all;        #}    }    # another virtual host using mix of IP-, name-, and port-based configuration    #    #server {    #    listen       8000;    #    listen       somename:8080;    #    server_name  somename  alias  another.alias;    #    location / {    #        root   html;    #        index  index.html index.htm;    #    }    #}    # HTTPS server    #    #server {    #    listen       443 ssl;    #    server_name  localhost;    #    ssl_certificate      cert.pem;    #    ssl_certificate_key  cert.key;    #    ssl_session_cache    shared:SSL:1m;    #    ssl_session_timeout  5m;    #    ssl_ciphers  HIGH:!aNULL:!MD5;    #    ssl_prefer_server_ciphers  on;    #    location / {    #        root   html;    #        index  index.html index.htm;    #    }    #}}rtmp {    server {            listen 1935;            chunk_size 4096;            application live {                    live on;                    record off;            }    }}

我这里参杂了rtmp的配置,具体可参考另一篇博客:http://blog.csdn.net/liukang325/article/details/53262133

主要新加

        #自定义模块,新加的在此        location /test {            lktest;            root html;        }

创建 /usr/local/nginx/html/test 文件夹,交修改权限 sudo chmod -R 777 test

配置好后,剩下的就是重新编译nginx

liukang@liukang-virtual-machine:~/RTMP/nginx-1.9.15$ sudo ./configure --prefix=/usr/local/nginx --with-http_realip_module --with-http_sub_module --with-http_flv_module --with-http_dav_module --with-http_gzip_static_module --with-http_stub_status_module --with-http_addition_module  --add-module=../nginx-rtmp-module-master --add-module=../nginx-test-moduleliukang@liukang-virtual-machine:~/RTMP/nginx-1.9.15$ sudo makeliukang@liukang-virtual-machine:~/RTMP/nginx-1.9.15$ sudo make install重启ngnixliukang@liukang-virtual-machine:~/RTMP/nginx-1.9.15$ sudo /usr/local/nginx/sbin/nginx -s stopliukang@liukang-virtual-machine:~/RTMP/nginx-1.9.15$ sudo /usr/local/nginx/sbin/nginx

浏览器中访问测试 localhost/test 即可获取自己新增的内容

原创粉丝点击