dougm       01/07/15 15:33:50

  Modified:    src/modules/perl mod_perl.c modperl_filter.c
                        modperl_filter.h modperl_types.h
               t/filter/TestFilter input_body.pm input_msg.pm
               xs/Apache/Filter Apache__Filter.h
  Log:
  support connection-level output filters
  (filter handler attribute names/semantics are still not final)
  
  Revision  Changes    Path
  1.60      +9 -4      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.59
  retrieving revision 1.60
  diff -u -r1.59 -r1.60
  --- mod_perl.c        2001/07/13 16:49:35     1.59
  +++ mod_perl.c        2001/07/15 22:33:48     1.60
  @@ -264,7 +264,9 @@
   
   static int modperl_hook_pre_connection(conn_rec *c)
   {
  -    return modperl_input_filter_register_connection(c);
  +    modperl_input_filter_register_connection(c);
  +    modperl_output_filter_register_connection(c);
  +    return OK;
   }
   
   static void modperl_hook_post_config(apr_pool_t *pconf, apr_pool_t *plog,
  @@ -297,7 +299,7 @@
       /* if 'PerlOptions +GlobalRequest' is outside a container */
       modperl_global_request_cfg_set(r);
   
  -    return modperl_input_filter_register_request(r);
  +    return OK;
   }
   
   static int modperl_hook_header_parser(request_rec *r)
  @@ -305,7 +307,7 @@
       /* if 'PerlOptions +GlobalRequest' is inside a container */
       modperl_global_request_cfg_set(r);
   
  -    return modperl_input_filter_register_request(r);
  +    return OK;
   }
   
   void modperl_register_hooks(apr_pool_t *p)
  @@ -321,8 +323,11 @@
   
       ap_hook_handler(modperl_response_handler_cgi,
                       NULL, NULL, APR_HOOK_MIDDLE);
  +
  +    ap_hook_insert_filter(modperl_output_filter_register_request,
  +                          NULL, NULL, APR_HOOK_LAST);
   
  -    ap_hook_insert_filter(modperl_output_filter_register,
  +    ap_hook_insert_filter(modperl_input_filter_register_request,
                             NULL, NULL, APR_HOOK_LAST);
   
       ap_register_output_filter(MODPERL_OUTPUT_FILTER_NAME,
  
  
  
  1.21      +92 -49    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.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- modperl_filter.c  2001/05/08 21:08:27     1.20
  +++ modperl_filter.c  2001/07/15 22:33:48     1.21
  @@ -75,12 +75,13 @@
   
   /* generic filter routines */
   
  +#define MP_FILTER_POOL(f) f->r ? f->r->pool : f->c->pool
  +
   modperl_filter_t *modperl_filter_new(ap_filter_t *f,
                                        apr_bucket_brigade *bb,
                                        modperl_filter_mode_e mode)
   {
  -    apr_pool_t *p = mode == MP_INPUT_FILTER_MODE ?
  -        f->c->pool : f->r->pool;
  +    apr_pool_t *p = MP_FILTER_POOL(f);
       modperl_filter_t *filter = apr_pcalloc(p, sizeof(*filter));
   
       filter->mode = mode;
  @@ -152,12 +153,20 @@
   
   MP_INLINE static apr_status_t send_eos(ap_filter_t *f)
   {
  -    apr_bucket_brigade *bb = apr_brigade_create(f->r->pool);
  +    apr_bucket_brigade *bb = apr_brigade_create(MP_FILTER_POOL(f));
       apr_bucket *b = apr_bucket_eos_create();
       APR_BRIGADE_INSERT_TAIL(bb, b);
       return ap_pass_brigade(f->next, bb);
   }
   
  +MP_INLINE static apr_status_t send_flush(ap_filter_t *f)
  +{
  +    apr_bucket_brigade *bb = apr_brigade_create(MP_FILTER_POOL(f));
  +    apr_bucket *b = apr_bucket_flush_create();
  +    APR_BRIGADE_INSERT_TAIL(bb, b);
  +    return ap_pass_brigade(f->next, bb);
  +}
  +
   /* unrolled APR_BRIGADE_FOREACH loop */
   
   #define MP_FILTER_SENTINEL(filter) \
  @@ -172,6 +181,9 @@
   #define MP_FILTER_IS_EOS(filter) \
   APR_BUCKET_IS_EOS(filter->bucket)
   
  +#define MP_FILTER_IS_FLUSH(filter) \
  +APR_BUCKET_IS_FLUSH(filter->bucket)
  +
   MP_INLINE static int get_bucket(modperl_filter_t *filter)
   {
       if (!filter->bb) {
  @@ -253,6 +265,11 @@
               filter->eos = 1;
               break;
           }
  +        else if (MP_FILTER_IS_FLUSH(filter)) {
  +            MP_TRACE_f(MP_FUNC, "received FLUSH bucket\n");
  +            filter->flush = 1;
  +            break;
  +        }
   
           num_buckets++;
   
  @@ -298,7 +315,7 @@
       }
   #endif
   
  -    if (filter->eos && (len == 0)) {
  +    if ((filter->eos || filter->flush) && (len == 0)) {
           /* if len > 0 then $filter->write will flush */
           modperl_output_filter_flush(filter);
       }
  @@ -313,12 +330,14 @@
           return filter->rc;
       }
   
  -    if (filter->eos) {
  -        MP_TRACE_f(MP_FUNC, "sending EOS bucket\n");
  -        filter->rc = send_eos(filter->f);
  +    if (filter->eos || filter->flush) {
  +        MP_TRACE_f(MP_FUNC, "sending %s bucket\n",
  +                   filter->eos ? "EOS" : "FLUSH");
  +        filter->rc = filter->eos ?
  +            send_eos(filter->f) : send_flush(filter->f);
           apr_brigade_destroy(filter->bb);
           filter->bb = NULL;
  -        filter->eos = 0;
  +        filter->flush = filter->eos = 0;
       }
   
       return filter->rc;
  @@ -387,87 +406,74 @@
       }
   }
   
  -void modperl_output_filter_register(request_rec *r)
  -{
  -    MP_dDCFG;
  -    MpAV *av;
  +typedef ap_filter_t * (*filter_add_t) (const char *, void *,
  +                                       request_rec *, conn_rec *);
   
  -    if ((av = dcfg->handlers_per_dir[MP_OUTPUT_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(r->pool, sizeof(*ctx));
  -            ctx->handler = handlers[i];
  -            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)
  +static int modperl_filter_register_connection(conn_rec *c,
  +                                              int idx,
  +                                              const char *name,
  +                                              filter_add_t addfunc,
  +                                              const char *type)
   {
       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])) {
  +    if ((av = dcfg->handlers_per_dir[idx])) {
           modperl_handler_t **handlers = (modperl_handler_t **)av->elts;
           int i;
   
           for (i=0; i<av->nelts; i++) {
               modperl_filter_ctx_t *ctx;
   
  -            if (!(handlers[i]->attrs & MP_INPUT_FILTER_MESSAGE)) {
  +            if (!(handlers[i]->attrs & MP_FILTER_CONNECTION_HANDLER)) {
                   MP_TRACE_f(MP_FUNC,
  -                           "%s is not an InputFilterMessage handler\n",
  +                           "%s is not an FilterConnection handler\n",
                              handlers[i]->name);
                   continue;
               }
   
               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);
  +            addfunc(name, (void*)ctx, NULL, c);
           }
   
           return OK;
       }
   
  -    MP_TRACE_h(MP_FUNC, "no InputFilter handlers configured (connection)\n");
  +    MP_TRACE_h(MP_FUNC, "no %s handlers configured (connection)\n", type);
   
       return DECLINED;
   }
   
  -int modperl_input_filter_register_request(request_rec *r)
  +static int modperl_filter_register_request(request_rec *r,
  +                                           int idx,
  +                                           const char *name,
  +                                           filter_add_t addfunc,
  +                                           const char *type,
  +                                           ap_filter_t *filters)
   {
       MP_dDCFG;
       MpAV *av;
   
  -    if ((av = dcfg->handlers_per_dir[MP_INPUT_FILTER_HANDLER])) {
  +    if ((av = dcfg->handlers_per_dir[idx])) {
           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;
  +            ap_filter_t *f = filters;
   
               while (f) {
                   const char *name = f->frec->name;
   
  -                if (*name == 'M' && strEQ(name, MODPERL_INPUT_FILTER_NAME)) {
  +                if (*name == 'M' && strEQ(name, name)) {
                       modperl_handler_t *ctx_handler = 
                           ((modperl_filter_ctx_t *)f->ctx)->handler;
   
                       if (modperl_handler_equal(ctx_handler, handlers[i])) {
  -                        /* skip if modperl_input_filter_register_connection
  +                        /* skip if modperl_filter_register_connection
                            * already registered this handler
                            * XXX: set a flag in the modperl_handler_t instead
                            */
  @@ -481,24 +487,61 @@
   
               if (registered) {
                   MP_TRACE_f(MP_FUNC,
  -                        "%s InputFilter already registered\n",
  -                        handlers[i]->name);
  +                        "%s %s already registered\n",
  +                        handlers[i]->name, type);
                   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);
  +            addfunc(name, (void*)ctx, r, NULL);
           }
   
           return OK;
       }
   
  -    MP_TRACE_h(MP_FUNC, "no InputFilter handlers configured (%s)\n",
  -               r->uri);
  +    MP_TRACE_h(MP_FUNC, "no %s handlers configured (%s)\n",
  +               type, r->uri);
   
       return DECLINED;
  +}
  +
  +void modperl_output_filter_register_connection(conn_rec *c)
  +{
  +    modperl_filter_register_connection(c,
  +                                       MP_OUTPUT_FILTER_HANDLER,
  +                                       MODPERL_OUTPUT_FILTER_NAME,
  +                                       ap_add_output_filter,
  +                                       "OutputFilter");
  +}
  +
  +void modperl_output_filter_register_request(request_rec *r)
  +{
  +    modperl_filter_register_request(r,
  +                                    MP_OUTPUT_FILTER_HANDLER,
  +                                    MODPERL_OUTPUT_FILTER_NAME,
  +                                    ap_add_output_filter,
  +                                    "OutputFilter",
  +                                    r->connection->output_filters);
  +}
  +
  +void modperl_input_filter_register_connection(conn_rec *c)
  +{
  +    modperl_filter_register_connection(c,
  +                                       MP_INPUT_FILTER_HANDLER,
  +                                       MODPERL_INPUT_FILTER_NAME,
  +                                       ap_add_input_filter,
  +                                       "InputFilter");
  +}
  +
  +void modperl_input_filter_register_request(request_rec *r)
  +{
  +    modperl_filter_register_request(r,
  +                                    MP_INPUT_FILTER_HANDLER,
  +                                    MODPERL_INPUT_FILTER_NAME,
  +                                    ap_add_input_filter,
  +                                    "InputFilter",
  +                                    r->connection->input_filters);
   }
   
   void modperl_brigade_dump(apr_bucket_brigade *bb, FILE *fp)
  
  
  
  1.9       +7 -5      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.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- modperl_filter.h  2001/05/07 02:05:01     1.8
  +++ modperl_filter.h  2001/07/15 22:33:48     1.9
  @@ -4,8 +4,8 @@
   #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
  +#define MP_FILTER_CONNECTION_HANDLER 0x01
  +#define MP_FILTER_REQUEST_HANDLER    0x02
   
   /* simple buffer api */
   MP_INLINE apr_status_t modperl_wbucket_pass(modperl_wbucket_t *b,
  @@ -32,8 +32,10 @@
   apr_status_t modperl_output_filter_handler(ap_filter_t *f,
                                              apr_bucket_brigade *bb);
   
  -void modperl_output_filter_register(request_rec *r);
  +void modperl_output_filter_register_connection(conn_rec *c);
   
  +void modperl_output_filter_register_request(request_rec *r);
  +
   MP_INLINE apr_status_t modperl_output_filter_flush(modperl_filter_t *filter);
   
   MP_INLINE apr_ssize_t modperl_output_filter_read(pTHX_
  @@ -53,8 +55,8 @@
                                             ap_input_mode_t mode,
                                             apr_size_t *readbytes);
   
  -int modperl_input_filter_register_connection(conn_rec *c);
  +void modperl_input_filter_register_connection(conn_rec *c);
   
  -int modperl_input_filter_register_request(request_rec *r);
  +void modperl_input_filter_register_request(request_rec *r);
   
   #endif /* MODPERL_FILTER_H */
  
  
  
  1.44      +1 -0      modperl-2.0/src/modules/perl/modperl_types.h
  
  Index: modperl_types.h
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_types.h,v
  retrieving revision 1.43
  retrieving revision 1.44
  diff -u -r1.43 -r1.44
  --- modperl_types.h   2001/05/22 20:57:30     1.43
  +++ modperl_types.h   2001/07/15 22:33:48     1.44
  @@ -180,6 +180,7 @@
   
   typedef struct {
       int eos;
  +    int flush;
       ap_filter_t *f;
       char *leftover;
       apr_ssize_t remaining;
  
  
  
  1.5       +1 -1      modperl-2.0/t/filter/TestFilter/input_body.pm
  
  Index: input_body.pm
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/t/filter/TestFilter/input_body.pm,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- input_body.pm     2001/04/24 02:26:17     1.4
  +++ input_body.pm     2001/07/15 22:33:49     1.5
  @@ -12,7 +12,7 @@
   use APR::Brigade ();
   use APR::Bucket ();
   
  -sub handler : InputFilterBody {
  +sub handler : FilterRequestHandler {
       my($filter, $bb, $mode, $readbytes) = @_;
   
       if ($bb->empty) {
  
  
  
  1.6       +1 -1      modperl-2.0/t/filter/TestFilter/input_msg.pm
  
  Index: input_msg.pm
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/t/filter/TestFilter/input_msg.pm,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- input_msg.pm      2001/04/25 02:02:19     1.5
  +++ input_msg.pm      2001/07/15 22:33:49     1.6
  @@ -13,7 +13,7 @@
   my $from_url = '/input_filter.html';
   my $to_url = '/TestFilter::input_msg::response';
   
  -sub handler : InputFilterMessage {
  +sub handler : FilterConnectionHandler {
       my($filter, $bb, $mode, $readbytes) = @_;
   
       if ($bb->empty) {
  
  
  
  1.12      +15 -17    modperl-2.0/xs/Apache/Filter/Apache__Filter.h
  
  Index: Apache__Filter.h
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/xs/Apache/Filter/Apache__Filter.h,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- Apache__Filter.h  2001/05/07 02:05:02     1.11
  +++ Apache__Filter.h  2001/07/15 22:33:50     1.12
  @@ -100,24 +100,22 @@
           char *pv = SvPV(ST(i), len);
           char *attribute = pv;
   
  +        if (strnEQ(pv, "Filter", 6)) {
  +            pv += 6;
  +        }
  +
           switch (*pv) {
  -          case 'I':
  -            if (strnEQ(pv, "InputFilter", 11)) {
  -                pv += 11;
  -                switch (*pv) {
  -                  case 'B':
  -                    if (strEQ(pv, "Body")) {
  -                        *attrs |= MP_INPUT_FILTER_BODY;
  -                        trace_attr();
  -                        continue;
  -                    }
  -                  case 'M':
  -                    if (strEQ(pv, "Message")) {
  -                        *attrs |= MP_INPUT_FILTER_MESSAGE;
  -                        trace_attr();
  -                        continue;
  -                    }
  -                }
  +          case 'C':
  +            if (strEQ(pv, "ConnectionHandler")) {
  +                *attrs |= MP_FILTER_CONNECTION_HANDLER;
  +                trace_attr();
  +                continue;
  +            }
  +          case 'R':
  +            if (strEQ(pv, "RequestHandler")) {
  +                *attrs |= MP_FILTER_REQUEST_HANDLER;
  +                trace_attr();
  +                continue;
               }
             default:
               XPUSHs_mortal_pv(attribute);
  
  
  

Reply via email to