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 */
  
  
  

Reply via email to