dougm 01/04/19 10:44:22
Modified: src/modules/perl mod_perl.c modperl_filter.c
modperl_filter.h
Log:
register/run PerlInputFilterHandlers
Revision Changes Path
1.48 +30 -2 modperl-2.0/src/modules/perl/mod_perl.c
Index: mod_perl.c
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/mod_perl.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -r1.47 -r1.48
--- mod_perl.c 2001/04/12 16:15:19 1.47
+++ mod_perl.c 2001/04/19 17:44:15 1.48
@@ -221,6 +221,11 @@
*/
}
+static int modperl_hook_pre_connection(conn_rec *c)
+{
+ return modperl_input_filter_register_connection(c);
+}
+
static void modperl_hook_post_config(apr_pool_t *pconf, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s)
{
@@ -246,10 +251,23 @@
return OK;
}
+static int modperl_hook_post_read_request(request_rec *r)
+{
+ return modperl_input_filter_register_request(r);
+}
+
+static int modperl_hook_header_parser(request_rec *r)
+{
+ return modperl_input_filter_register_request(r);
+}
+
void modperl_register_hooks(apr_pool_t *p)
{
ap_hook_open_logs(modperl_hook_init, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_post_config(modperl_hook_post_config, NULL, NULL,
+ APR_HOOK_MIDDLE);
+
ap_hook_handler(modperl_response_handler, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_insert_filter(modperl_output_filter_register,
@@ -259,11 +277,21 @@
modperl_output_filter_handler,
AP_FTYPE_CONTENT);
+ ap_register_input_filter(MODPERL_INPUT_FILTER_NAME,
+ modperl_input_filter_handler,
+ AP_FTYPE_CONTENT);
+
+ ap_hook_pre_connection(modperl_hook_pre_connection,
+ NULL, NULL, APR_HOOK_FIRST);
+
ap_hook_create_request(modperl_hook_create_request, NULL, NULL,
APR_HOOK_MIDDLE);
- ap_hook_post_config(modperl_hook_post_config, NULL, NULL,
- APR_HOOK_MIDDLE);
+ ap_hook_post_read_request(modperl_hook_post_read_request, NULL, NULL,
+ APR_HOOK_FIRST);
+
+ ap_hook_header_parser(modperl_hook_header_parser, NULL, NULL,
+ APR_HOOK_FIRST);
modperl_register_handler_hooks();
}
1.12 +121 -3 modperl-2.0/src/modules/perl/modperl_filter.c
Index: modperl_filter.c
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- modperl_filter.c 2001/04/18 04:37:46 1.11
+++ modperl_filter.c 2001/04/19 17:44:17 1.12
@@ -79,7 +79,7 @@
return filter;
}
-int modperl_run_filter(modperl_filter_t *filter)
+int modperl_run_filter(modperl_filter_t *filter, ap_input_mode_t mode)
{
AV *args = Nullav;
int status;
@@ -88,7 +88,7 @@
request_rec *r = filter->f->r;
conn_rec *c = filter->f->c;
- server_rec *s = r ? r->server : NULL;
+ server_rec *s = r ? r->server : c->base_server;
apr_pool_t *p = r ? r->pool : c->pool;
MP_dINTERP_SELECT(r, c, s);
@@ -98,6 +98,10 @@
"APR::Brigade", filter->bb,
NULL);
+ if (filter->mode == MP_INPUT_FILTER_MODE) {
+ av_push(args, newSViv(mode));
+ }
+
if ((status = modperl_callback(aTHX_ handler, p, s, args)) != OK) {
status = modperl_errsv(aTHX_ status, r, s);
}
@@ -319,7 +323,7 @@
}
else {
filter = modperl_filter_new(f, bb, MP_OUTPUT_FILTER_MODE);
- status = modperl_run_filter(filter);
+ status = modperl_run_filter(filter, 0);
}
switch (status) {
@@ -332,6 +336,32 @@
}
}
+apr_status_t modperl_input_filter_handler(ap_filter_t *f,
+ apr_bucket_brigade *bb,
+ ap_input_mode_t mode)
+{
+ modperl_filter_t *filter;
+ int status;
+
+ if (APR_BRIGADE_IS_EOS(bb)) {
+ /* XXX: see about preventing this in the first place */
+ MP_TRACE_f(MP_FUNC, "first bucket is EOS, skipping callback\n");
+ return APR_SUCCESS;
+ }
+ else {
+ filter = modperl_filter_new(f, bb, MP_INPUT_FILTER_MODE);
+ status = modperl_run_filter(filter, mode);
+ }
+
+ switch (status) {
+ case OK:
+ case DECLINED:
+ return APR_SUCCESS;
+ default:
+ return status; /*XXX*/
+ }
+}
+
void modperl_output_filter_register(request_rec *r)
{
MP_dDCFG;
@@ -348,7 +378,95 @@
ap_add_output_filter(MODPERL_OUTPUT_FILTER_NAME,
(void*)ctx, r, r->connection);
}
+
+ return;
+ }
+
+ MP_TRACE_h(MP_FUNC, "no OutputFilter handlers configured (%s)\n",
+ r->uri);
+}
+
+int modperl_input_filter_register_connection(conn_rec *c)
+{
+ modperl_config_dir_t *dcfg =
+ modperl_config_dir_get_defaults(c->base_server);
+ MpAV *av;
+
+ if ((av = dcfg->handlers_per_dir[MP_INPUT_FILTER_HANDLER])) {
+ modperl_handler_t **handlers = (modperl_handler_t **)av->elts;
+ int i;
+
+ for (i=0; i<av->nelts; i++) {
+ modperl_filter_ctx_t *ctx =
+ (modperl_filter_ctx_t *)apr_pcalloc(c->pool, sizeof(*ctx));
+ ctx->handler = handlers[i];
+ ap_add_input_filter(MODPERL_INPUT_FILTER_NAME,
+ (void*)ctx, NULL, c);
+ }
+
+ return OK;
}
+
+ MP_TRACE_h(MP_FUNC, "no InputFilter handlers configured (connection)\n");
+
+ return DECLINED;
+}
+
+int modperl_input_filter_register_request(request_rec *r)
+{
+ MP_dDCFG;
+ MpAV *av;
+
+ if ((av = dcfg->handlers_per_dir[MP_INPUT_FILTER_HANDLER])) {
+ modperl_handler_t **handlers = (modperl_handler_t **)av->elts;
+ int i;
+
+ for (i=0; i<av->nelts; i++) {
+ modperl_filter_ctx_t *ctx;
+ int registered = 0;
+ ap_filter_t *f = r->connection->input_filters;
+
+ while (f) {
+ const char *name = f->frec->name;
+
+ if (*name == 'M' && strEQ(name, MODPERL_INPUT_FILTER_NAME)) {
+ modperl_handler_t *ctx_handler =
+ ((modperl_filter_ctx_t *)f->ctx)->handler;
+
+ if (modperl_mgv_equal(ctx_handler->mgv_cv,
+ handlers[i]->mgv_cv)) {
+ /* skip if modperl_input_filter_register_connection
+ * already registered this handler
+ * XXX: set a flag in the modperl_handler_t instead
+ */
+ registered = 1;
+ break;
+ }
+ }
+
+ f = f->next;
+ }
+
+ if (registered) {
+ MP_TRACE_f(MP_FUNC,
+ "%s InputFilter already registered\n",
+ handlers[i]->name);
+ continue;
+ }
+
+ ctx = (modperl_filter_ctx_t *)apr_pcalloc(r->pool, sizeof(*ctx));
+ ctx->handler = handlers[i];
+ ap_add_input_filter(MODPERL_INPUT_FILTER_NAME,
+ (void*)ctx, r, r->connection);
+ }
+
+ return OK;
+ }
+
+ MP_TRACE_h(MP_FUNC, "no InputFilter handlers configured (%s)\n",
+ r->uri);
+
+ return DECLINED;
}
void modperl_brigade_dump(apr_bucket_brigade *bb, FILE *fp)
1.3 +14 -1 modperl-2.0/src/modules/perl/modperl_filter.h
Index: modperl_filter.h
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- modperl_filter.h 2001/01/20 21:19:08 1.2
+++ modperl_filter.h 2001/04/19 17:44:17 1.3
@@ -2,7 +2,11 @@
#define MODPERL_FILTER_H
#define MODPERL_OUTPUT_FILTER_NAME "MODPERL_OUTPUT"
+#define MODPERL_INPUT_FILTER_NAME "MODPERL_INPUT"
+#define MP_INPUT_FILTER_MESSAGE 0x01
+#define MP_INPUT_FILTER_BODY 0x02
+
/* simple buffer api */
MP_INLINE apr_status_t modperl_wbucket_pass(modperl_wbucket_t *b,
const char *buf, apr_ssize_t len);
@@ -19,7 +23,7 @@
apr_bucket_brigade *bb,
modperl_filter_mode_e mode);
-int modperl_run_filter(modperl_filter_t *filter);
+int modperl_run_filter(modperl_filter_t *filter, ap_input_mode_t mode);
MP_INLINE modperl_filter_t *modperl_sv2filter(pTHX_ SV *sv);
@@ -41,5 +45,14 @@
apr_ssize_t *len);
void modperl_brigade_dump(apr_bucket_brigade *bb, FILE *fp);
+
+/* input filters */
+apr_status_t modperl_input_filter_handler(ap_filter_t *f,
+ apr_bucket_brigade *bb,
+ ap_input_mode_t mode);
+
+int modperl_input_filter_register_connection(conn_rec *c);
+
+int modperl_input_filter_register_request(request_rec *r);
#endif /* MODPERL_FILTER_H */