httpd-modules-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From alin vasile <alinachegal...@yahoo.com>
Subject httpd filters to record the client network time
Date Sat, 02 Oct 2010 15:11:33 GMT
I would like to write an httpd module with output filters to record when a 
client sends the first byte of an HTTP request and when send the last. After 
looking a while through the existing filters in the httpd source code I was able 
to accomplish that but unfortunately it doesn't work for keep-alive connections; 
the client 'first byte time' would remain the 'connection establish' time. 


Any help on this would be highly appreciated!

In a sort of pseudo-code this is what I did:

<pre>
  <code>

static int pre_conn(conn_rec *c, void *csd) {
     my_config_t *config = apr_pcalloc(c->pool, sizeof(*config));
     ap_set_module_config(c->conn_config, &my_module, config);
    
     ap_add_input_filter(my_filter_name, NULL, NULL, c);
     ap_add_output_filter(my_filter_name, NULL, NULL, c);
    
    return OK;
}


/*  Output filter - records the 'last byte in' time */
static apr_status_t out_filter(ap_filter_t *f, apr_bucket_brigade *bb) {
    conn_rec *c = f->c;

    apr_bucket *b = APR_BRIGADE_LAST(bb);
    /* End of data, make sure we flush */
    if (APR_BUCKET_IS_EOS(b)) {
        APR_BRIGADE_INSERT_TAIL(bb,apr_bucket_flush_create(f->c->bucket_alloc));
        APR_BUCKET_REMOVE(b);
        apr_bucket_destroy(b);
    }

    apr_status_t ret = ap_pass_brigade(f->next, bb);

    // save 'last byte in' time

    return ret;
}

static apr_status_t in_filter_start(ap_filter_t *f, apr_bucket_brigade *bb, 
          ap_input_mode_t mode, apr_read_type_e block, apr_off_t read_bytes) {

    apr_bucket *b;
    conn_rec *c = f->c;    
    apr_status_t status;

    // save the 'first time in' byte

    status = ap_get_brigade(f->next, bb, mode, block, read_bytes);
    if (status == APR_SUCCESS) {
        for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb); b = 
APR_BUCKET_NEXT(b)) {
           ;
        }
    }
    return status;

}
</code>
</pre>

I registered my filters in the following way:

 ap_hook_pre_connection(pre_conn, NULL, NULL, APR_HOOK_MIDDLE);
 ap_register_input_filter(my_filter_name, in_filter_start,NULL, 
AP_FTYPE_CONNECTION + 2  ); ap_register_output_filter(my_filter_name, 
out_filter, NULL, AP_FTYPE_NETWORK - 1); 


Thanks,
Alin



      

Mime
View raw message