helloworld
config
ngx_addon_name=ngx_http_mytest_module HTTP_MODULES="$HTTP_MODULES ngx_http_mytest_module" NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest_module.c"
ngx_http_mytest_module.c
#include <ngx_config.h> #include <ngx_core.h> #include <ngx_http.h> #define HELLO 42 static char * ngx_http_mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r); static ngx_command_t ngx_http_mytest_commands[] = { { ngx_string("mytest"), NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS, ngx_http_mytest, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, ngx_null_command }; static ngx_http_module_t ngx_http_mytest_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_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 char * ngx_http_mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_core_loc_conf_t *clcf; //First find the configuration block to which the mytest configuration item belongs, clcf seems to be the data in the location block //Structure, in fact, it can be a main, srv or loc level configuration item, that is to say, in each //http{} and server{} also have an ngx_http_core_loc_conf_t structure clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); //When the http framework processes user requests to the NGX_HTTP_CONTENT_PHASE stage, if //The requested host domain name and URI match the configuration block where the mytest configuration item is located, and we will be called //The implemented ngx_http_mytest_handler method handles this request clcf->handler = ngx_http_mytest_handler; return NGX_CONF_OK; } static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r) { int watchpoint = 12; printf("this is ngx_hello %d \n",HELLO); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0," haoning error \n"); //Must be GET or HEAD method, otherwise return 405 Not Allowed if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD))) { return NGX_HTTP_NOT_ALLOWED; } //Discard the body of the request ngx_int_t rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { return rc; } //Set the returned Content-Type. Note that ngx_str_t has a handy initialization macro //ngx_string, it can set the data and len members of ngx_str_t ngx_str_t type = ngx_string("text/plain"); //returned package body content ngx_str_t response = ngx_string("Hello World!"); //Set the return status code r->headers_out.status = NGX_HTTP_OK; //The response packet has body content, so you need to set the Content-Length length r->headers_out.content_length_n = response.len; //Set Content-Type r->headers_out.content_type = type; //send http header rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { return rc; } //Construct the ngx_buf_t structure to prepare to send the packet body ngx_buf_t * b; b = ngx_create_temp_buf(r->pool, response.len); watchpoint = 42; if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } //Copy Hello World to the memory pointed to by ngx_buf_t ngx_memcpy (b-> pos, response.data, response.len); //Note, be sure to set the last pointer b->last = b->pos + response.len; //declare this is the last buffer b->last_buf = 1; //Construct the ngx_chain_t structure when sending ngx_chain_t out; //Assign ngx_buf_t out.buf = b; //Set next to NULL out.next = NULL; //The last step to send the packet body, the http framework will call the ngx_http_finalize_request method //end request return ngx_http_output_filter(r, &out); }
./configure --prefix=/usr/local/nginx --add-module=/opt/chapter3/helloworld
make
./configure --prefix=/usr/local/nginx --add-module=/opt/chapter3/helloworld
#./configure --with-debug --prefix=/usr/local/nginx --add-module=/opt/chapter3/helloworld
#CFLAGS="-g3 -O0" ./configure --prefix=/usr/local/nginx --with-debug --add-module=/opt/chapter3/helloworld
#./configure --with-cc-opt='-ggdb3 -O0' --prefix=/usr/local/nginx --with-debug
make
#make CFLAGS="-ggdb3 -O0"
grep -nR hello *
/opt/nginx-1.13.3/objs/addon/helloworld
vim /usr/local/nginx/conf/nginx.conf
location /hello {
mytest;
}
###########
curl localhost/hello
If you bring -ggdb3 or -g3
info macro ,
if you don't need to l
gdb /usr/local/nginx/sbin/nginx
or gdb -p `nginx worker process`
set args -c /usr/local/nginx/conf/nginx.conf b ngx_cycle.c: 1264 b ngx_http_mytest_module.c:63 set follow-fork-mode child
Switch to the subprocess
r
info macro
to find the worker process of nginx
gdb -q -p `pidof nginx`