何もしないOutputfilterのサンプル
http://asp.mi.hama-med.ac.jp/web/ のソースをほとんどそのままコピー。これを元に改造していく。
いつものように、
# apxs -g -n myoutputfilter
- mod_myoutputfilter.conf
LoadModule myoutputfilter_module modules/mod_myoutputfilter.so SetOutputFilter MYOUTPUTFILTER
- myoutputfilter.c (本当に何もしないバージョン)
#include "httpd.h" #include "http_config.h" #include "http_log.h" #include "apr_strings.h" #include "apr_general.h" #include "util_filter.h" #include "apr_buckets.h" #include "http_request.h" static apr_status_t myoutputfilter_out_filter(ap_filter_t *f, apr_bucket_brigade *in_bb) { const request_rec* const r = f->r; ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r->status, r, ">>myoutputfilter_out_filter()"); if (APR_BRIGADE_EMPTY(in_bb)) return APR_SUCCESS; ap_remove_output_filter(f); ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r->status, r, "<<myoutputfilter_out_filter()"); return ap_pass_brigade(f->next, in_bb); } static void myoutputfilter_register_hooks(apr_pool_t *p) { ap_register_output_filter("MYOUTPUTFILTER", myoutputfilter_out_filter, NULL, AP_FTYPE_RESOURCE); } module AP_MODULE_DECLARE_DATA myoutputfilter_module = { STANDARD20_MODULE_STUFF, NULL, /* dir config creater */ NULL, /* dir merger --- default is to override */ NULL, /* server config */ NULL, /* merge server config */ NULL, /* command table */ myoutputfilter_register_hooks /* register hooks */ };
- myoutputfilter.c (in_bb を out_bb にコピーしているバージョン)
#include "httpd.h" #include "http_config.h" #include "http_log.h" #include "apr_strings.h" #include "apr_general.h" #include "util_filter.h" #include "apr_buckets.h" #include "http_request.h" static apr_status_t myoutputfilter_out_filter(ap_filter_t *f, apr_bucket_brigade *in_bb) { const request_rec* const r = f->r; ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r->status, r, ">>myoutputfilter_out_filter()"); if (APR_BRIGADE_EMPTY(in_bb)) return APR_SUCCESS; apr_bucket_brigade* const out_bb = apr_brigade_create(r->pool, f->c->bucket_alloc); while (!APR_BRIGADE_EMPTY(in_bb)) { apr_bucket* const e = APR_BRIGADE_FIRST(in_bb); if (APR_BUCKET_IS_EOS(e)) { APR_BUCKET_REMOVE(e); APR_BRIGADE_INSERT_TAIL(out_bb, e); break; } if (APR_BUCKET_IS_FLUSH(e)) { apr_bucket_delete(e); apr_bucket* const bkt = apr_bucket_flush_create(f->c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(out_bb, bkt); const apr_status_t rv = ap_pass_brigade(f->next, out_bb); if (rv != APR_SUCCESS) return rv; continue; } apr_size_t len; const char* data; apr_bucket_read(e, &data, &len, APR_BLOCK_READ); char* const buf = (char*)apr_palloc(r->pool, len); memcpy(buf, data, len); apr_bucket* const b = apr_bucket_pool_create(buf, len, r->pool, f->c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(out_bb, b); apr_bucket_delete(e); } ap_remove_output_filter(f); apr_brigade_cleanup(in_bb); ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r->status, r, "<<myoutputfilter_out_filter()"); return ap_pass_brigade(f->next, out_bb); } static void myoutputfilter_register_hooks(apr_pool_t *p) { ap_register_output_filter("MYOUTPUTFILTER", myoutputfilter_out_filter, NULL, AP_FTYPE_RESOURCE); } module AP_MODULE_DECLARE_DATA myoutputfilter_module = { STANDARD20_MODULE_STUFF, NULL, /* dir config creater */ NULL, /* dir merger --- default is to override */ NULL, /* server config */ NULL, /* merge server config */ NULL, /* command table */ myoutputfilter_register_hooks /* register hooks */ };