r->headers_inなどのapr_table_tのデータの扱い方

r->headers_in は apr_table_t 型で、apr_table_elts() という関数を使うと apr_array_header_t 型の値が取得できる。
これが先頭のデータになる。

const apr_array_header_t *arr = apr_table_elts(r->headers_in);

で、apr_array_header_t は下記のような構造体になってる。

struct apr_array_header_t {
    apr_pool_t *pool;
    int elt_size;
    int nelts;
    int nalloc;
    char *elts;
};

この elts は char * なんだけど、apr_table_entry_t になっているっぽい。
なので、

apr_table_entry_t *elts = (apr_table_entry_t *)arr->elts;

こうやって apr_table_entry_t * として受けとると最終的には、

for (i = 0; i < arr->nelts; i++) {
    printf("%s: %s", elts[i].key, elts[i].val);
}       

とやるとkeyとvalが出力できる。
ちなみに、arr->elts はもともと char * なので (apr_table_entry_t *) でキャストしてやらないとwarningが出ます。