APACHE MOD 开发 Step 2 获取用户输入
1. 了解apr_table_t结构
可以把他理解为一个HASH表,可以对他进行取值赋值操作,常用的有
apr_table_add
apr_table_set
apr_table_get
例如:
char *slen=apr_table_get(r->headers_in, "Content-Length");
2. 了解request_rec
这是一个最重要的结构,定义在httpd.h第682行.
注意到handle函数的唯一的参数
static int mod_hello_method_handler (request_rec *r);你可以认为从这个结构里面你可以得到所有一切.
重要的几个结构成员
apr_pool_t *pool;
/** The connection to the client */
conn_rec *connection;
/** The virtual host for this request */
server_rec *server;
int method_number; //提交信息的类型,GET或者POST
char *args; //存放GET的参数
apr_table_t *headers_in; //提交信息的头信息的保存位置
const char *handler; //处理的类型
3. 读取HTTP头
信息在r->headers_in里面,那么就是
char *slen=apr_table_get(r->headers_in, "Content-Length");
4. 获得GET方法传递的数据
信息在r->args里面.注意,这里的数据是没有经过解析的,也就是说URL编码过的,如果你不使用类似libapreq2而自行解析的话,需要自行编码.
ap_log_rerror(APLOG_MARK, APLOG_ERR,0,r,"get query string:%s",r->args);
5. 获得POST方法传递的数据
数据在request_rec关联的bucket里面.bucket的解释将在下一步解释,那么我们简单的使用ap_get_client_block来读取吧.其实这个函数里面也是调用了bucket操作.
6. 简单的例子.
if(strcmp("hello-script",r->handler)) return DECLINED;
//get the comand.
if(r->method_number==M_GET){
ap_log_rerror(APLOG_MARK, APLOG_ERR,0,r,"get query string:%s",r->args);
}else if(r->method_number==M_POST){
handle_post (r);
}else{
return DECLINED;
}
handle_post 函数
void handle_post(request_rec *r)
{
size_t total_bytes;
int rstat=0;
char cbuf[HUGE_STRING_LEN];
rstat = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK);
if (ap_should_client_block(r)) {
int nbytes;
while ((nbytes = ap_get_client_block(r, cbuf, HUGE_STRING_LEN)) > 0){
cbuf[nbytes]='\0';
ap_rputs(cbuf,r);
total_bytes += nbytes;
}
}
}
7. 小结
现在对模块有了简单的理解,知道如何写一个模块,知道数据在哪.知道如何处理输入输出,下面要知道APAHCE内部是如何的运作,APR运行库的常用函数,然后是利用APACHE的服务框架完成更多的工作.要把APACHE看做一个SOCKET服务器,而不仅仅是一个WEB服务器.