perl-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Geoffrey Young <ge...@modperlcookbook.org>
Subject Re: a new stacked handlers paradigm
Date Mon, 02 Jun 2003 20:27:59 GMT
ok, I took another stab at it.  this one is much simpler - it only touches
modperl_callback.c.  I didn't see the reason for an enum, and there's no point in moving 
the logic to lookup_handlers(), since there's nothing that lookup_handlers() knows that 
modperl_callback() didn't tell it.  I'm not too sure about whether that switch statement 
is the way to go, but it's another iteration for everyone to discuss at least.  oh, and 
the test is more self contained now, too :)

--Geoff

Index: src/modules/perl/modperl_callback.c
===================================================================
RCS file: /home/cvspublic/modperl-2.0/src/modules/perl/modperl_callback.c,v
retrieving revision 1.54
diff -u -r1.54 modperl_callback.c
--- src/modules/perl/modperl_callback.c 17 Feb 2003 09:03:16 -0000      1.54
+++ src/modules/perl/modperl_callback.c 2 Jun 2003 20:21:20 -0000
@@ -94,6 +94,7 @@
      apr_pool_t *p = NULL;
      MpAV *av, **avp;
      int i, nelts, status = OK;
+    int run_all = TRUE;
      const char *desc = NULL;
      AV *av_args = Nullav;

@@ -172,6 +173,31 @@
          break;
      };

+    /* check the type again and determine whether we're in
+     * RUN_FIRST, RUN_ALL, or VOID mode.  RUN_ALL and VOID
+     * are essentially equivalent */
+
+    switch (type) {
+      case MP_HANDLER_TYPE_PER_DIR:
+        if (idx == MP_AUTHEN_HANDLER   ||
+            idx == MP_AUTHZ_HANDLER    ||
+            idx == MP_TYPE_HANDLER     ||
+            idx == MP_RESPONSE_HANDLER)
+        {
+           run_all = FALSE;
+        }
+        break;
+      case MP_HANDLER_TYPE_PER_SRV:
+        if (idx == MP_TRANS_HANDLER) {
+           run_all = FALSE;
+        }
+        break;
+      case MP_HANDLER_TYPE_CONNECTION:
+        /* there is only one, the PerlProcessConnectionHandler */
+        run_all = FALSE;
+        break;
+    };
+
      modperl_callback_current_callback_set(desc);

      /* XXX: deal with {push,set}_handler of the phase we're currently in */
@@ -192,9 +218,22 @@
              status = modperl_errsv(aTHX_ status, r, s);
  #ifdef MP_TRACE
              if (i+1 != nelts) {
-                MP_TRACE_h(MP_FUNC, "there were %d uncalled handlers\n",
+                MP_TRACE_h(MP_FUNC, "error status %d leaves %d uncalled handlers\n",
                             nelts-i-1);
              }
+#endif
+            break;
+        }
+
+        /* follow Apache's lead and let OK terminate the phase for
+         * translation, authen, authz, type-checking, and content
+         */
+        if (status == OK && run_all == FALSE) {
+#ifdef MP_TRACE
+            if (i+1 != nelts) {
+                MP_TRACE_h(MP_FUNC, "OK ends the %s stack, leaving %d uncalled handlers\n",
+                           desc, nelts-i-1);
+             }
  #endif
              break;
          }
Index: t/hooks/TestHooks/init.pm
===================================================================
RCS file: /home/cvspublic/modperl-2.0/t/hooks/TestHooks/init.pm,v
retrieving revision 1.4
diff -u -r1.4 init.pm
--- t/hooks/TestHooks/init.pm   31 Mar 2003 01:50:52 -0000      1.4
+++ t/hooks/TestHooks/init.pm   2 Jun 2003 20:21:20 -0000
@@ -8,7 +8,7 @@
  use APR::Table ();
  use Apache::RequestRec ();

-use Apache::Const -compile => 'OK';
+use Apache::Const -compile => qw(OK DECLINED);

  sub first {
      my $r = shift;
@@ -35,7 +35,7 @@

      $r->notes->set(ok3 => $ok + 1);

-    Apache::OK;
+    Apache::DECLINED;
  }

  sub response {
Index: t/hooks/TestHooks/push_handlers.pm
===================================================================
RCS file: /home/cvspublic/modperl-2.0/t/hooks/TestHooks/push_handlers.pm,v
retrieving revision 1.5
diff -u -r1.5 push_handlers.pm
--- t/hooks/TestHooks/push_handlers.pm  18 Apr 2003 06:18:57 -0000      1.5
+++ t/hooks/TestHooks/push_handlers.pm  2 Jun 2003 20:21:20 -0000
@@ -39,7 +39,7 @@
  }

  sub end { return Apache::DONE }
-sub say { shift->print(shift,"\n"); return Apache::OK }
+sub say { shift->print(shift,"\n"); return Apache::DECLINED }

  sub conf {
      # this one is configured from httpd.conf
Index: t/hooks/TestHooks/stacked_handlers.pm
===================================================================
RCS file: /home/cvspublic/modperl-2.0/t/hooks/TestHooks/stacked_handlers.pm,v
retrieving revision 1.5
diff -u -r1.5 stacked_handlers.pm
--- t/hooks/TestHooks/stacked_handlers.pm       18 Apr 2003 06:18:57 -0000      1.5
+++ t/hooks/TestHooks/stacked_handlers.pm       2 Jun 2003 20:21:20 -0000
@@ -28,7 +28,7 @@
      $r->content_type('text/plain');
      $r->print("one\n");

-    return Apache::OK;
+    return Apache::DECLINED;
  }

  sub two {
@@ -36,7 +36,7 @@

      $r->print("two\n");

-    return Apache::OK;
+    return Apache::DECLINED;
  }

  sub three {
--- /dev/null   Tue May  5 16:32:27 1998
+++ t/hooks/stacked_handlers2.t Mon Jun  2 16:18:22 2003
@@ -0,0 +1,34 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestRequest;
+use Apache::Test;
+use Apache::TestUtil;
+
+my $module   = "TestHooks::stacked_handlers2";
+Apache::TestRequest::module($module);
+
+my $config   = Apache::Test::config();
+my $hostport = Apache::TestRequest::hostport($config);
+my $path     = Apache::TestRequest::module2path($module);
+
+my $location = "http://$hostport/$path";
+
+t_debug("connecting to $location");
+
+plan tests => 1;
+
+my $expected = q!ran 2 PerlPostReadRequestHandler handlers
+ran 1 PerlTransHandler handlers
+ran 4 PerlHeaderParserHandler handlers
+ran 2 PerlAccessHandler handlers
+ran 2 PerlAuthenHandler handlers
+ran 2 PerlAuthzHandler handlers
+ran 1 PerlTypeHandler handlers
+ran 2 PerlFixupHandler handlers
+ran 2 PerlResponseHandler handlers
+ran 2 PerlOutputFilterHandler handlers!;
+
+chomp(my $received = GET_BODY_ASSERT $location);
+
+ok t_cmp($expected, $received, "stacked_handlers");

--- /dev/null   Tue May  5 16:32:27 1998
+++ t/hooks/TestHooks/stacked_handlers2.pm      Mon Jun  2 16:17:30 2003
@@ -0,0 +1,177 @@
+package TestHooks::stacked_handlers2;
+
+# this test exercises the execution of the stacked handlers
+# connection, translation, authen, authz, type, and response
+# phases should end for the first handler that returns OK
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::RequestRec ();
+use Apache::RequestIO ();
+use Apache::Filter ();
+
+use APR::Table;
+
+use Apache::Const -compile => qw(OK DECLINED AUTH_REQUIRED SERVER_ERROR);
+
+sub ok {
+
+  callback(shift);
+
+  return Apache::OK
+}
+
+sub declined {
+
+  callback(shift);
+
+  return Apache::DECLINED
+}
+
+sub auth_required {
+
+  callback(shift);
+
+  return Apache::AUTH_REQUIRED
+}
+
+sub server_error {
+
+  callback(shift);
+
+  return Apache::SERVER_ERROR
+}
+
+sub callback {
+
+  my $obj = shift;
+
+  my ($r, $callback);
+
+  if ($obj->isa('Apache::Filter')) {
+    $r = $obj->r;
+    $callback = 'PerlOutputFilterHandler';
+  }
+  else {
+    $r = $obj
+  }
+
+  $callback ||= Apache::current_callback;
+
+  my $count = $r->notes->get($callback) || 0;
+
+  $r->notes->set($callback, ++$count);
+}
+
+sub handler {
+
+    my $r = shift;
+
+    $r->content_type('text/plain');
+
+    callback($r);
+
+    foreach my $callback (qw(PerlPostReadRequestHandler
+                             PerlTransHandler
+                             PerlHeaderParserHandler
+                             PerlAccessHandler
+                             PerlAuthenHandler
+                             PerlAuthzHandler
+                             PerlTypeHandler
+                             PerlFixupHandler
+                             PerlResponseHandler)) {
+
+        my $count = $r->notes->get($callback) || 0;
+
+        $r->print("ran $count $callback handlers\n");
+    }
+
+    return Apache::OK;
+}
+
+sub passthru {
+    my $filter = shift;
+
+    unless ($filter->ctx) {
+       callback($filter);
+       $filter->ctx({seen => 1});
+    }
+
+    while ($filter->read(my $buffer, 1024)) {
+        $filter->print($buffer);
+    }
+
+    Apache::OK;
+}
+
+sub filter {
+    my $filter = shift;
+
+    unless ($filter->ctx) {
+        callback($filter);
+        $filter->ctx({seen => 1});
+    }
+
+    while ($filter->read(my $buffer, 1024)) {
+        $filter->print($buffer);
+    }
+
+    if ($filter->seen_eos) {
+        my $count = $filter->r->notes->get('PerlOutputFilterHandler') || 0;
+
+        $filter->print("ran $count PerlOutputFilterHandler handlers\n");
+    }
+
+    Apache::OK;
+}
+
+1;
+__DATA__
+# create a new virtual host so we can test (almost all) all the hooks
+<NoAutoConfig>
+<VirtualHost TestHooks::stacked_handlers2>
+
+  PerlModule TestHooks::stacked_handlers2
+
+  # all 2 run
+  PerlPostReadRequestHandler TestHooks::stacked_handlers2::ok 
TestHooks::stacked_handlers2::ok
+
+  # 1 run, 1 left behind
+  PerlTransHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::error
+
+  <Location /TestHooks__stacked_handlers2>
+      # all 4 run
+      PerlHeaderParserHandler TestHooks::stacked_handlers2::ok 
TestHooks::stacked_handlers2::declined
+      PerlHeaderParserHandler TestHooks::stacked_handlers2::declined 
TestHooks::stacked_handlers2::ok
+
+      # all 2 run
+      PerlAccessHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::ok
+
+      # 2 run, 1 left behind
+      PerlAuthenHandler TestHooks::stacked_handlers2::declined 
TestHooks::stacked_handlers2::ok
+      PerlAuthenHandler TestHooks::stacked_handlers2::auth_required
+
+      # 2 run, 1 left behind
+      PerlAuthzHandler TestHooks::stacked_handlers2::declined 
TestHooks::stacked_handlers2::ok
+      PerlAuthzHandler TestHooks::stacked_handlers2::auth_required
+
+      # 1 run, 1 left behind
+      PerlTypeHandler  TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers3::error
+
+      # all 2 run
+      PerlFixupHandler TestHooks::stacked_handlers2::ok TestHooks::stacked_handlers2::ok
+
+      # 2 run, 2 left behind
+      PerlResponseHandler TestHooks::stacked_handlers2::declined 
TestHooks::stacked_handlers2
+      PerlResponseHandler TestHooks::stacked_handlers2::ok 
TestHooks::stacked_handlers2::error
+
+      SetHandler modperl
+      AuthType Basic
+      Require valid-user
+
+      PerlOutputFilterHandler TestHooks::stacked_handlers2::passthru 
TestHooks::stacked_handlers2::filter
+  </Location>
+
+</VirtualHost>
+</NoAutoConfig>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Mime
View raw message