Stas Bekman wrote:
Craig Shelley wrote:

I'll take a look at it. But you didn't supply a complete bug report as explained http://perl.apache.org/bugs/. Please do so.

I think I've got this figured out.


the problem is with the r->main logic in mpxs_ap_run_sub_req.

with that logic, what ends up happening is that the data currently being operated on is explicity flushed. this is bad within a (streaming) filter where you are expected to call $f->print yourself, as the data is sent without your permission (you may be operating on it or not want to send it at all). it also seemed to cause infinite loop in my tests because the filter was seeing the same data over and over again.

I can't really understand the reason behind the code anyway, since I can't see anywhere in core where such logic is applied before ap_run_sub_request - everyone seems to call without regard to where in the data stream they happen to be, so I don't get why mod_perl should be any different. indeed commenting it out fixes the problem for me.

however, removing that logic causes api/lookup_uri2.t to fail, but I suspect this is an issue with puts() rather than the subrequest mechanism - changing puts() to print() makes everything work just fine. does puts() write directly to the wire, bypassing filters?

anyway, attached is a patch against current cvs - fixes and a few filtering subrequest tests. note that the patch does not mention the removal of xs/Apache/SubRequest/Apache__SubRequest.h, which is no longer needed, so I guess you should remove that file by hand before compiling.

craig - note that this patch affects the autogenerated code, so in order to get it to work you'll need to apply it, then run make realclean, perl Makefile.PL, etc.


--Geoff
Index: t/response/TestAPI/lookup_uri2.pm
===================================================================
RCS file: /home/cvspublic/modperl-2.0/t/response/TestAPI/lookup_uri2.pm,v
retrieving revision 1.3
diff -u -r1.3 lookup_uri2.pm
--- t/response/TestAPI/lookup_uri2.pm   27 Apr 2003 04:19:18 -0000      1.3
+++ t/response/TestAPI/lookup_uri2.pm   26 Aug 2003 19:55:50 -0000
@@ -11,7 +11,7 @@
 sub myplan {
     my $r = shift;
 
-    $r->puts("1..3\nok 1\n");
+    $r->print("1..3\nok 1\n");
 
     Apache::OK;
 }
@@ -19,7 +19,7 @@
 sub ok3 {
     my $r = shift;
 
-    $r->puts("ok 3\n");
+    $r->print("ok 3\n");
 
     Apache::OK;
 }
@@ -35,7 +35,7 @@
 
     subrequest($r, 'myplan');
 
-    $r->puts("ok 2\n");
+    $r->print("ok 2\n");
 
     subrequest($r, 'ok3');
 
Index: xs/maps/apache_functions.map
===================================================================
RCS file: /home/cvspublic/modperl-2.0/xs/maps/apache_functions.map,v
retrieving revision 1.64
diff -u -r1.64 apache_functions.map
--- xs/maps/apache_functions.map        12 Jun 2003 23:27:03 -0000      1.64
+++ xs/maps/apache_functions.map        26 Aug 2003 19:55:51 -0000
@@ -95,7 +95,7 @@
 
 PACKAGE=Apache::SubRequest   ISA=Apache::RequestRec
  ap_destroy_sub_req  | | r | DESTROY
- ap_run_sub_req      | mpxs_ | | run
+ ap_run_sub_req      | | r | run
 
 MODULE=Apache::RequestIO   PACKAGE=Apache::RequestRec
  ap_discard_request_body
Index: xs/tables/current/ModPerl/FunctionTable.pm
===================================================================
RCS file: /home/cvspublic/modperl-2.0/xs/tables/current/ModPerl/FunctionTable.pm,v
retrieving revision 1.119
diff -u -r1.119 FunctionTable.pm
--- xs/tables/current/ModPerl/FunctionTable.pm  20 Aug 2003 23:20:14 -0000      1.119
+++ xs/tables/current/ModPerl/FunctionTable.pm  26 Aug 2003 19:55:56 -0000
@@ -6170,24 +6170,6 @@
     ]
   },
   {
-    'return_type' => 'int',
-    'name' => 'mpxs_ap_run_sub_req',
-    'attr' => [
-      'static',
-      '__inline__'
-    ],
-    'args' => [
-      {
-        'type' => 'PerlInterpreter *',
-        'name' => 'my_perl'
-      },
-      {
-        'type' => 'request_rec *',
-        'name' => 'r'
-      }
-    ]
-  },
-  {
     'return_type' => 'apr_size_t',
     'name' => 'mpxs_ap_rvputs',
     'attr' => [

--- /dev/null   2003-01-30 05:24:37.000000000 -0500
+++ t/filter/TestFilter/out_str_sub_core.pm     2003-08-26 15:51:40.000000000 -0400
@@ -0,0 +1,78 @@
+package TestFilter::out_str_sub_core;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache::RequestRec ();
+use Apache::RequestIO ();
+use Apache::SubRequest ();
+
+use Apache::Filter ();
+
+use Apache::Const -compile => qw(OK);
+
+# include the contents of a subrequest
+# in the filter, a la mod_include's 
+# <!--#include virtual="/subrequest" -->
+
+sub include {
+
+    my $filter = shift;
+
+    unless ($filter->ctx) {
+        # don't forget to remove the C-L header
+        $filter->r->headers_out->unset('Content-Length');
+
+        $filter->ctx(1);
+    }
+
+    while ($filter->read(my $buffer, 1024)){
+
+        if ($buffer eq "<tag>\n") {
+            my $sub = $filter->r->lookup_uri('/core_subrequest/subrequest.txt');
+            my $rc = $sub->run;
+        }
+        else {
+           # send all other data along unaltered
+           $filter->print($buffer);
+        }
+
+    }
+
+    # add our own at the end
+    if ($filter->seen_eos) {
+        $filter->print("filter\n");
+        $filter->ctx(1);
+    }
+
+    return Apache::OK;
+}
+
+sub response {
+
+    my $r = shift;
+
+    $r->content_type('text/plain');
+
+    $r->print("content\n");
+    $r->rflush;
+    $r->print("<tag>\n");
+    $r->rflush;
+    $r->print("more content\n");
+
+    Apache::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule              TestFilter::out_str_sub_core
+PerlResponseHandler     TestFilter::out_str_sub_core::response
+PerlOutputFilterHandler TestFilter::out_str_sub_core::include
+
+Alias /core_subrequest @DocumentRoot@/filter
+<Location /core_subrequest>
+  SetHandler default-handler
+</Location>

--- /dev/null   2003-01-30 05:24:37.000000000 -0500
+++ t/filter/TestFilter/out_str_sub_perl.pm     2003-08-26 15:52:08.000000000 -0400
@@ -0,0 +1,88 @@
+package TestFilter::out_str_sub_perl;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache::RequestRec ();
+use Apache::RequestIO ();
+use Apache::SubRequest ();
+
+use Apache::Filter ();
+
+use Apache::Const -compile => qw(OK);
+
+# include the contents of a subrequest
+# in the filter, a la mod_include's 
+# <!--#include virtual="/subrequest" -->
+
+sub include {
+
+    my $filter = shift;
+
+    unless ($filter->ctx) {
+        # don't forget to remove the C-L header
+        $filter->r->headers_out->unset('Content-Length');
+
+        $filter->ctx(1);
+    }
+
+    while ($filter->read(my $buffer, 1024)){
+
+        if ($buffer eq "<tag>\n") {
+            my $sub = $filter->r->lookup_uri('/perl_subrequest');
+            my $rc = $sub->run;
+        }
+        else {
+           # send all other data along unaltered
+           $filter->print($buffer);
+        }
+
+    }
+
+    # add our own at the end
+    if ($filter->seen_eos) {
+        $filter->print("filter\n");
+        $filter->ctx(1);
+    }
+
+    return Apache::OK;
+}
+
+sub subrequest {
+
+    my $r = shift;
+
+    $r->content_type('text/plain');
+    $r->print("perl subrequest\n");
+
+    return Apache::OK;
+}
+
+sub response {
+
+    my $r = shift;
+
+    $r->content_type('text/plain');
+
+    $r->print("content\n");
+    $r->rflush;
+    $r->print("<tag>\n");
+    $r->rflush;
+    $r->print("more content\n");
+
+    Apache::OK;
+}
+1;
+__DATA__
+SetHandler modperl
+PerlModule              TestFilter::out_str_sub_perl
+PerlResponseHandler     TestFilter::out_str_sub_perl::response
+PerlOutputFilterHandler TestFilter::out_str_sub_perl::include
+
+<Location /perl_subrequest>
+  SetHandler modperl
+  PerlResponseHandler   TestFilter::out_str_sub_perl::subrequest
+</Location>

--- /dev/null   2003-01-30 05:24:37.000000000 -0500
+++ t/filter/out_str_sub_core.t 2003-08-26 15:49:44.000000000 -0400
@@ -0,0 +1,21 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1;
+
+my $location = '/TestFilter__out_str_sub_core';
+
+my $content1    = "content\n";
+my $content2    = "more content\n";
+my $filter      = "filter\n";
+my $subrequest  = "core subrequest\n";
+
+my $expected = join '', $content1, $subrequest, $content2, $filter;
+my $received = GET_BODY $location;
+
+ok t_cmp($expected, $received, 
+    "testing filter-originated lookup_uri() call to core served URI");

--- /dev/null   2003-01-30 05:24:37.000000000 -0500
+++ t/filter/out_str_sub_perl.t 2003-08-26 15:49:54.000000000 -0400
@@ -0,0 +1,21 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 1;
+
+my $location = '/TestFilter__out_str_sub_perl';
+
+my $content1    = "content\n";
+my $content2    = "more content\n";
+my $filter      = "filter\n";
+my $subrequest  = "perl subrequest\n";
+
+my $expected = join '', $content1, $subrequest, $content2, $filter;
+my $received = GET_BODY $location;
+
+ok t_cmp($expected, $received, 
+    "testing filter-originated lookup_uri() call to modperl-served URI");

-- 
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html

Reply via email to