: This article mainly introduces the compilation of the hello module. if you are interested in the PHP Tutorial, refer to it. To learn about high-performance concurrent servers, I plan to study the implementation of Nginx. According to the convention, a hello world program should be written at the beginning, so the next step is to introduce how to compile a simple HTTP Module under the Nginx framework to print "Hello World".
Processing of defining hello configuration items
First, we need to define a commands array to define the configuration file parameters of the module. Each array element belongs to the ngx_command_t type, and the end of the array ends with ngx_null_command.
Nginx first traverses all modules when parsing a configuration item in the configuration file. for each module, it traverses the commands array. Each ngx_command_t struct defines a configuration item that you are interested in. The structure is defined as follows:
Struct ngx_command_s {/* configuration item name */ngx_str_t name;/* specify the location where the configuration item can appear */ngx_uint_t type;/* After the configuration item specified in name appears, the set method will be called to process the configuration item parameters */char * (* set) (ngx_conf_t * cf, ngx_command_t * cmd, void * conf); ngx_uint_t conf; /* offset in the configuration file */ngx_uint_t offset;/* the processing process after the configuration item is read. it must be a pointer to the ngx_conf_post_t structure */void * post ;}; # define ngx_null_command {ngx_null_string, 0, NULL, 0, 0, NULL}
After learning about the commands array, we define the hello configuration item processing:
static ngx_command_t ngx_http_hello_commands[] = { { ngx_string("hello"), NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS, ngx_http_hello, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, ngx_null_command};
Ngx_http_hello is a set member in the ngx_command_t structure. when the hello configuration item appears in a configuration block, Nginx will call the ngx_http_hello method. The following is the implementation of ngx_http_hello:
Staticchar * ngx_http_hello (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 hello configuration item belongs */clcf = cf, ngx_http_core_module ); /* When the HTTP Framework processes user requests in the NGX_HTTP_CONTENT_PHASE stage * if the requested host domain name and URI match the configuration block of the hello configuration item *, the ngx_http_hello_handler method is called to process the request */ clcf-> handler = ngx_http_hello_handler; return NGX_CONF_ OK ;}
Define the hello module
It is easy to define an HTTP module, as long as the ngx_moodule_t struct is defined as follows:
ngx_module_t ngx_http_hello_module = { NGX_MODULE_V1, &ngx_http_hello_module_ctx, /* module context */ ngx_http_hello_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};
The hello module will be added to the ngx_modules global array during compilation.
Wherengx_http_hello_commands
Is the processing of the hello configuration item defined in the previous section.
Because we define the HTTP Moduletype
SetNGX_HTTP_MODULE
.
Another important Membervoid* ctx
For the HTTP Module, the ctx pointer must pointngx_http_module_t
Interface.
The HTTP Framework defines eight stages described by the ngx_http_module_t interface when reading and reloading the configuration file. when the HTTP Framework starts, it calls the corresponding method in ngx_http_module_t at each stage. If you do not need to do anything, you can define it as NULL. Because the hello module does not need to do any work, the definition is as follows:
static ngx_http_module_t ngx_http_hello_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 */};
Process user requests
The last step is to process user requests. here we need a little HTTP knowledge. For more information, see the HTTP protocol. We implementngx_http_hello_handler
Method to process user requests. the method is defined as follows:
static ngx_int_tngx_http_hello_handler(ngx_http_request_t *r)
Wherengx_http_request_t
Struct contains all the information of the request (such as the method, URI, protocol version number, and header). In addition, it also contains many other members, such as the memory pool and response header.
Because we only process the GET and HEAD methods, we need to make the following judgment:
if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD))) { return NGX_HTTP_NOT_ALLOWED; }
Next, because we do not need a packet body in the request, we need to discard the packet body as follows:
ngx_int_t rc = ngx_http_discard_request_body(r);if (rc != NGX_OK) { return rc;}
Then, set the returned response package. The Returned package contains only one "Hello World" string:
ngx_str_type = ngx_string("text/plain");ngx_str_response = ngx_string("Hello World");r->headers_out.status = NGX_HTTP_OK;r->headers_out.content_length_n = response.len;r->headers_out.content_type = type;
Finally, the packet header and package body of the response packet are sent:
rc = ngx_http_send_header(r); if (rc == NGX_ERR || rc > NGX_OK || r->header_only) { return rc; } ngx_buf_t *b; b = ngx_create_temp_buf(r->pool, response.len); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_memcpy(b->pos, response.data, response.len); b->last = b->pos + response.len; b->last_buf = 1; ngx_chain_t out; out.buf = b; out.next = NULL; /* send the buffer chain of your response */return ngx_http_output_filter(r, &out);
The complete code can be viewed here: hello_module
Compile and run
Createconfig
File to add the following lines:
ngx_addon_name=ngx_http_hello_moduleHTTP_MODULES="$HTTP_MODULES ngx_http_hello_module"NGX_ADDON_SRCS="$NGX_ADDON_SRCS$ngx_addon_dir/ngx_http_hello_module.c"
Then go to the Nginx source code root directory and runconfigure
Remember to include the "-add-module" parameter and connect the path of the HTTP module code we have compiled after the parameter:
./configure --prefix=/usr/local/nginx --add-module=/code/nginx-1.8.0/src/http/hello_module
After configure is run, usemake
Command to compile. after the compilation is successful, entermake install
Complete the installation.
Modify/usr/local/nginx/conf/nginx.conf
, Add:
http{ ... server { ... location /hello { hello; } ... } ...}
Run Nginx and enterIP/hello
The displayed "Hello World string" is displayed.
Reference
Understanding Nginx in depth