apache2 流程控制

_hook 数据结构
 1 
 2  //  从 ap_hook 到 ap_run
 3  //  宏 AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_connection,(conn_rec *c, void *csd),(c, csd),OK,DECLINED ); 的具体实现
 4  //  connection.c
 5      AP_DECLARE( void ) ap_hook_pre_connection(ap_HOOK_pre_connection_t  * pf,  const   char   *   const   * aszPre,  const   char   *   const   * aszSucc, int  nOrder)
 6      { 
 7          ap_LINK_pre_connection_t  * pHook; 
 8           if ( ! _hooks.link_pre_connection)
 9          {
10              _hooks.link_pre_connection = apr_array_make(apr_hook_global_pool, 1 , sizeof (ap_LINK_pre_connection_t)); 
11              apr_hook_sort_register( " pre_connection " , & _hooks.link_pre_connection); 
12          } 
13          pHook = apr_array_push(_hooks.link_pre_connection); 
14          pHook -> pFunc = pf; 
15          pHook -> aszPredecessors = aszPre; 
16          pHook -> aszSuccessors = aszSucc; 
17          pHook -> nOrder = nOrder; 
18          pHook -> szName = apr_hook_debug_current; 
19           if (apr_hook_debug_enabled) 
20              apr_hook_debug_show( " pre_connection " ,aszPre,aszSucc); 
21      } 
22      AP_DECLARE(apr_array_header_t  * ) ap_hook_get_pre_connection( void
23      { 
24           return  _hooks.link_pre_connection; 
25      }
26      AP_DECLARE( int ) ap_run_pre_connection (conn_rec  * c,  void   * csd)
27      { 
28          ap_LINK_pre_connection_t  * pHook;  int  n;  int  rv; 
29           if ( ! _hooks.link_pre_connection) 
30               return  OK; 
31          pHook = (ap_LINK_pre_connection_t  * )_hooks.link_pre_connection -> elts; 
32           for (n = 0  ; n  <  _hooks.link_pre_connection -> nelts ;  ++ n)
33          { 
34              rv = pHook[n].pFunc (c, csd); 
35               if (rv  !=  OK  &&  rv  !=  DECLINED)  return  rv;
36          } 
37           return  OK; 
38      };

 

解码解释:

第5行 ap_hook_pre_connection 的第一个参数 pf 数据类型为 ap_HOOK_pre_connection_t ,实际是一个函数指针。也是用宏定义的:

//  宏 AP_DECLARE_HOOK(int,pre_connection,(conn_rec *c, void *csd))展开
//  http_connection.h
typedef  int  ap_HOOK_pre_connection_t (conn_rec  * c,  void   * csd);

AP_DECLARE(
void ) ap_hook_pre_connection(ap_HOOK_pre_connection_t  * pf,  const   char   *   const   * aszPre,  const   char   *   const   * aszSucc,  int  nOrder); 
AP_DECLARE(
int ) ap_run_pre_connection (conn_rec  * c,  void   * csd); 
AP_DECLARE(apr_array_header_t 
* ) ap_hook_get_pre_connection( void ); 
typedef 
struct  ap_LINK_pre_connection_t 
{    
    ap_HOOK_pre_connection_t 
* pFunc; 
    
const   char   * szName; 
    
const   char   *   const   * aszPredecessors; 
    
const   char   *   const   * aszSuccessors; 
    
int  nOrder;
} ap_LINK_pre_connection_t;

 

第7 行的 _hook 定义于 connection.c ,它是一个由宏定义的文件级的变量。 

ExpandedBlockStart.gif 从 hook 到 run--宏的展开
展开 ap_hook_宏和 ap_run宏 
/* *
 * 展开 apache2 的 ap_hook_宏和  ap_run宏
 * 使用 gcc -E -I/usr/local/apache2/include macos.h 可得到实际的c 代码
 * by fancp 2011-1-10 p_168@163.com
 * 
 **************************************************
*/
#include 
< ap_config.h >

APR_HOOK_STRUCT(
    APR_HOOK_LINK(create_request_bin)
)

AP_DECLARE_HOOK(
int ,create_request_bin,(conn_rec  * c,  void   * csd))


AP_IMPLEMENT_HOOK_RUN_ALL(
int , create_request_bin,
                          (request_rec_bin 
* r), (r), OK, DECLINED)

 



ap_filter_rec_t 数据结构
/* **************************************
 * 
 * util_filter.h
 **************************************
*/
struct  ap_filter_rec_t {
    
/* * The registered name for this filter  */
    
const   char   * name;

    
/* * The function to call when this filter is invoked.  */
    ap_filter_func filter_func;

    
/* * The function to call directly before the handlers are invoked
     * for a request.  The init function is called once directly
     * before running the handlers for a request or subrequest.  The
     * init function is never called for a connection filter (with
     * ftype >= AP_FTYPE_CONNECTION).  Any use of this function for
     * filters for protocols other than HTTP is specified by the
     * module supported that protocol.
     
*/
    ap_init_filter_func filter_init_func;

    
/* * The type of filter, either AP_FTYPE_CONTENT or AP_FTYPE_CONNECTION.  
     * An AP_FTYPE_CONTENT filter modifies the data based on information 
     * found in the content.  An AP_FTYPE_CONNECTION filter modifies the 
     * data based on the type of connection.
     
*/
    ap_filter_type ftype;

    
/* * The next filter_rec in the list  */
    
struct  ap_filter_rec_t  * next;

    
/* * Providers for this filter  */
    ap_filter_provider_t 
* providers;

    
/* * Trace level for this filter  */
    
int  debug;

    
/* * Protocol flags for this filter  */
    unsigned 
int  proto_flags;
};

 

 
/*
 * Read data from the next filter in the filter stack.  Data should be
 * modified in the bucket brigade that is passed in.  The core allocates the
 * bucket brigade, modules that wish to replace large chunks of data or to
 * save data off to the side should probably create their own temporary
 * brigade especially for that use.
 
*/
AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t 
* next,
                                        apr_bucket_brigade 
* bb,
                                        ap_input_mode_t mode,
                                        apr_read_type_e block,
                                        apr_off_t readbytes)
{
    
if  (next) {
        
return  next -> frec -> filter_func.in_func(next, bb, mode, block,
                                               readbytes);
    }
    
return  AP_NOBODY_READ;
}

 

 

转载于:https://www.cnblogs.com/diylab/archive/2011/02/16/1931691.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值