Apache module development and apache module
I. Introduction
Apache HTTP Server is a modular software that allows managers to choose modules contained in the core to crop functions. You can select a module that is statically included in the httpd binary image during compilation, or compile it into a dynamic shared object DSO independent of the main httpd binary image. The DSO module can be compiled after the compilation server, you can also use Apache extension tool (apxs) to compile and Add.
Apache module development mainly uses the method of linking sub-modules to implement module development, which is a bit like the development of Linux kernel modules. To put it bluntly, a callback function is added.
Ii. install Apache apxs
Apxs is a tool for compiling and installing extension modules for Apache HTTP servers. It is used to compile one or more source programs or target code files as dynamic shared objects, so that the LoadModule Command provided by mod_so can be loaded to the Apache server at runtime.
Apxs reference: http://lamp.linux.gov.cn/Apache/ApacheMenu/programs/apxs.html
Check whether the httpd-devel package exists. If no installation is required
#rpm -qa | grep httpd #View
#yum -y install httpd-devel #install
3. Development examples
Procedure 1: Content generator developed by apache module
Execute the following command, will generate helloworld template
apxs -g -n helloworld
The generated code is as follows:
/ *
** mod_helloworld.c-Apache sample helloworld module
** [Autogenerated via `` apxs -n helloworld -g '']
**
** To play with this sample module first compile it into a
** DSO file and install it into Apache's modules directory
** by running:
**
** $ apxs -c -i mod_helloworld.c
**
** Then activate it in Apache's httpd.conf file for instance
** for the URL / helloworld in as follows:
**
** # httpd.conf
** LoadModule helloworld_module modules / mod_helloworld.so
** <Location / helloworld>
** SetHandler helloworld
** </ Location>
**
** Then after restarting Apache via
**
** $ apachectl restart
**
** you immediately can request the URL / helloworld and watch for the
** output of this module. This can be achieved for instance via:
**
** $ lynx -mime_header http: // localhost / helloworld
**
** The output should be similar to the following one:
**
** HTTP / 1.1 200 OK
** Date: Tue, 31 Mar 1998 14:42:22 GMT
** Server: Apache / 1.3.4 (Unix)
** Connection: close
** Content-Type: text / html
**
** The sample page from mod_helloworld.c
* /
#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"
/ * The sample content handler * /
static int helloworld_handler (request_rec * r)
{
if (strcmp (r-> handler, "helloworld")) {
return DECLINED;
}
r-> content_type = "text / html";
if (! r-> header_only)
ap_rputs ("The sample page from mod_helloworld.c \ n", r);
return OK;
}
static void helloworld_register_hooks (apr_pool_t * p)
{
ap_hook_handler (helloworld_handler, NULL, NULL, APR_HOOK_MIDDLE);
}
/ * Dispatch list for API hooks * /
module AP_MODULE_DECLARE_DATA helloworld_module = {
STANDARD20_MODULE_STUFF,
NULL, / * create per-dir config structures * /
NULL, / * merge per-dir config structures * /
NULL, / * create per-server config structures * /
NULL, / * merge per-server config structures * /
NULL, / * table of config file commands * /
helloworld_register_hooks / * register hooks * /
};
Compile
apxs -c mod_helloworld.c
installation
apxs -i mod_helloworld.la
Modify the configuration file httpd.conf to load the module, mainly add the following content
LoadModule helloworld_module modules / mod_helloworld.so
<Location / helloworld>
SetHandler helloworld
</ Location>
Restart the server and test
apachectl -k stop #stop
apachectl -k start #start
Enter the url in the browser, you can see the effect
http://127.0.0.1/helloworld
Program 2: Output filter developed by apache module
For the filter, there are two types of input filter and output filter, in the following order:
Request-input filter-content generator-output filter-response
All requests will pass through our filters, so we can operate on these, such as statistical traffic, data compression, etc. The following example changes all lowercase letters on the page to uppercase letters.
/ **
* @file: mod_casefilter.c
* @brief: Change all lowercase letters on the page to uppercase letters
* /
#include "httpd.h"
#include "http_config.h"
#include "apr_buckets.h"
#include "apr_general.h"
#include "apr_lib.h"
#include "util_filter.h"
#include "http_request.h"
#include <ctype.h>
static const char s_szCaseFilterName [] = "CaseFilter";
module AP_MODULE_DECLARE_DATA case_filter_module;
typedef struct
{
int bEnabled;
} CaseFilterConfig;
static void * CaseFilterCreateServerConfig (apr_pool_t * p, server_rec * s)
{
CaseFilterConfig * pConfig = apr_pcalloc (p, sizeof * pConfig);
pConfig-> bEnabled = 0;
return pConfig;
}
static void CaseFilterInsertFilter (request_rec * r)
{
CaseFilterConfig * pConfig = ap_get_module_config (r-> server-> module_config,
& case_filter_module);
if (! pConfig-> bEnabled)
return;
ap_add_output_filter (s_szCaseFilterName, NULL, r, r-> connection);
}
static apr_status_t CaseFilterOutFilter (ap_filter_t * f,
apr_bucket_brigade * pbbIn)
{
request_rec * r = f-> r;
conn_rec * c = r-> connection;
apr_bucket * pbktIn;
apr_bucket_brigade * pbbOut;
pbbOut = apr_brigade_create (r-> pool, c-> bucket_alloc);
for (pbktIn = APR_BRIGADE_FIRST (pbbIn);
pbktIn! = APR_BRIGADE_SENTINEL (pbbIn);
pbktIn = APR_BUCKET_NEXT (pbktIn))
{
const char * data;
apr_size_t len;
char * buf;
apr_size_t n;
apr_bucket * pbktOut;
if (APR_BUCKET_IS_EOS (pbktIn))
{
apr_bucket * pbktEOS = apr_bucket_eos_create (c-> bucket_alloc);
APR_BRIGADE_INSERT_TAIL (pbbOut, pbktEOS);
continue;
}
/ * read * /
apr_bucket_read (pbktIn, & data, & len, APR_BLOCK_READ);
/ * write * /
buf = apr_bucket_alloc (len, c-> bucket_alloc);
for (n = 0; n <len; ++ n)
buf [n] = apr_toupper (data [n]);
pbktOut = apr_bucket_heap_create (buf, len, apr_bucket_free,
c-> bucket_alloc);
APR_BRIGADE_INSERT_TAIL (pbbOut, pbktOut);
}
apr_brigade_cleanup (pbbIn);
return ap_pass_brigade (f-> next, pbbOut);
}
static const char * CaseFilterEnable (cmd_parms * cmd, void * dummy, int arg)
{
CaseFilterConfig * pConfig = ap_get_module_config (cmd-> server-> module_config,
& case_filter_module);
pConfig-> bEnabled = arg;
return NULL;
}
static const command_rec CaseFilterCmds [] =
{
AP_INIT_FLAG ("CaseFilter", CaseFilterEnable, NULL, RSRC_CONF,
"Run a case filter on this host"),
{NULL}
};
static void CaseFilterRegisterHooks (apr_pool_t * p)
{
ap_hook_insert_filter (CaseFilterInsertFilter, NULL, NULL, APR_HOOK_MIDDLE);
ap_register_output_filter (s_szCaseFilterName, CaseFilterOutFilter, NULL,
AP_FTYPE_RESOURCE);
}
module AP_MODULE_DECLARE_DATA case_filter_module =
{
STANDARD20_MODULE_STUFF,
NULL,
NULL,
CaseFilterCreateServerConfig,
NULL,
CaseFilterCmds,
CaseFilterRegisterHooks
};
Compile
apxs -c mod_filter.c
installation
apxs -i mod_filter.la
Configure httpd.conf and add the following:
LoadModule case_filter_module modules / mod_casefilter.so
CaseFilter on
test