You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by jc...@apache.org on 2017/06/23 17:50:31 UTC

svn commit: r1799689 - in /httpd/test/framework/trunk/t: conf/proxy.conf.in htdocs/modules/proxy/fcgi/ htdocs/modules/proxy/fcgi/index.php modules/proxy_fcgi.t

Author: jchampion
Date: Fri Jun 23 17:50:31 2017
New Revision: 1799689

URL: http://svn.apache.org/viewvc?rev=1799689&view=rev
Log:
proxy_fcgi: add regression test for PR61202

Also refactor the FCGI backend daemon and envvar-echo request into a
callable subroutine.

Added:
    httpd/test/framework/trunk/t/htdocs/modules/proxy/fcgi/
    httpd/test/framework/trunk/t/htdocs/modules/proxy/fcgi/index.php   (with props)
Modified:
    httpd/test/framework/trunk/t/conf/proxy.conf.in
    httpd/test/framework/trunk/t/modules/proxy_fcgi.t

Modified: httpd/test/framework/trunk/t/conf/proxy.conf.in
URL: http://svn.apache.org/viewvc/httpd/test/framework/trunk/t/conf/proxy.conf.in?rev=1799689&r1=1799688&r2=1799689&view=diff
==============================================================================
--- httpd/test/framework/trunk/t/conf/proxy.conf.in (original)
+++ httpd/test/framework/trunk/t/conf/proxy.conf.in Fri Jun 23 17:50:31 2017
@@ -63,6 +63,12 @@
         ProxyFCGISetEnvIf true !REMOTE_ADDR
       </Location>
     </IfVersion>
+
+    <Directory @SERVERROOT@/htdocs/modules/proxy/fcgi>
+      <FilesMatch \.php$>
+        SetHandler proxy:fcgi://127.0.0.1:${FCGI_PORT}
+      </FilesMatch>
+    </Directory>
   </VirtualHost>
 </IfModule>
 

Added: httpd/test/framework/trunk/t/htdocs/modules/proxy/fcgi/index.php
URL: http://svn.apache.org/viewvc/httpd/test/framework/trunk/t/htdocs/modules/proxy/fcgi/index.php?rev=1799689&view=auto
==============================================================================
--- httpd/test/framework/trunk/t/htdocs/modules/proxy/fcgi/index.php (added)
+++ httpd/test/framework/trunk/t/htdocs/modules/proxy/fcgi/index.php Fri Jun 23 17:50:31 2017
@@ -0,0 +1,3 @@
+<?php
+  /* This does nothing; it's just a placeholder. */
+?>

Propchange: httpd/test/framework/trunk/t/htdocs/modules/proxy/fcgi/index.php
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: httpd/test/framework/trunk/t/modules/proxy_fcgi.t
URL: http://svn.apache.org/viewvc/httpd/test/framework/trunk/t/modules/proxy_fcgi.t?rev=1799689&r1=1799688&r2=1799689&view=diff
==============================================================================
--- httpd/test/framework/trunk/t/modules/proxy_fcgi.t (original)
+++ httpd/test/framework/trunk/t/modules/proxy_fcgi.t Fri Jun 23 17:50:31 2017
@@ -5,12 +5,13 @@ use Apache::Test;
 use Apache::TestRequest;
 use Apache::TestUtil;
 
-plan tests => 7,
+my $have_fcgisetenvif = have_min_apache_version('2.4.26');
+
+plan tests => (7 * $have_fcgisetenvif) + 2,
      need (
         'mod_proxy_fcgi',
         'FCGI',
-        'IO::Select',
-        need_min_apache_version('2.4.26')
+        'IO::Select'
      );
 
 require FCGI;
@@ -76,6 +77,55 @@ sub run_fcgi_handler($$)
     return $pid;
 }
 
+# Convenience wrapper for run_fcgi_handler() that will echo back the envvars in
+# the response. Returns the child PID; exits on failure.
+sub launch_envvar_echo_daemon($)
+{
+    my $fcgi_port = shift;
+
+    return run_fcgi_handler($fcgi_port, sub {
+        # Echo all the envvars back to the client.
+        print("Content-Type: text/plain\r\n\r\n");
+        foreach my $key (sort(keys %ENV)) {
+            print($key, "=", $ENV{$key}, "\n");
+        }
+    });
+}
+
+# Runs a single request using launch_envvar_echo_daemon(), then returns a
+# hashref containing the environment variables that were echoed by the FCGI
+# backend.
+#
+# Calling this function will run one test that must be accounted for in the test
+# plan.
+sub run_fcgi_envvar_request($$)
+{
+    my $fcgi_port = shift;
+    my $uri       = shift;
+
+    # Launch the FCGI process.
+    my $child = launch_envvar_echo_daemon($fcgi_port);
+
+    # Hit the backend.
+    my $r = GET($uri);
+    ok t_cmp($r->code, 200, "proxy to FCGI backend works");
+
+    # Split the returned envvars into a dictionary.
+    my %envs = ();
+
+    foreach my $line (split /\n/, $r->content) {
+        t_debug("> $line"); # log the response lines for debugging
+
+        my @components = split /=/, $line, 2;
+        $envs{$components[0]} = $components[1];
+    }
+
+    # Rejoin the child FCGI process.
+    waitpid($child, 0);
+
+    return \%envs;
+}
+
 #
 # MAIN
 #
@@ -85,39 +135,24 @@ sub run_fcgi_handler($$)
 # for the proxy_fcgi vhost is one greater than the reserved FCGI_PORT, but
 # depending on the test conditions, that may not always be the case...
 my $fcgi_port = Apache::Test::vars('proxy_fcgi_port') - 1;
+my $envs;
 
-# Launch the FCGI process.
-my $child = run_fcgi_handler($fcgi_port, sub {
-    # Echo all the envvars back to the client.
-    print("Content-Type: text/plain\r\n\r\n");
-    foreach my $key (sort(keys %ENV)) {
-        print($key, "=", $ENV{$key}, "\n");
-    }
-});
-
-# Hit the backend.
-my $r = GET("/fcgisetenv?query");
-ok t_cmp($r->code, 200, "proxy to FCGI backend");
-
-# Split the returned envvars into a dictionary.
-my %envs = ();
-
-foreach my $line (split /\n/, $r->content) {
-    t_debug("> $line"); # log the response lines for debugging
-
-    my @components = split /=/, $line, 2;
-    $envs{$components[0]} = $components[1];
+if ($have_fcgisetenvif) {
+    # ProxyFCGISetEnvIf tests. Query the backend.
+    $envs = run_fcgi_envvar_request($fcgi_port, "/fcgisetenv?query");
+
+    # Check the response values.
+    my $docroot = Apache::Test::vars('documentroot');
+
+    ok t_cmp($envs->{'QUERY_STRING'},     'test_value', "ProxyFCGISetEnvIf can override an existing variable");
+    ok t_cmp($envs->{'TEST_NOT_SET'},     undef,        "ProxyFCGISetEnvIf does not set variables if condition is false");
+    ok t_cmp($envs->{'TEST_EMPTY'},       '',           "ProxyFCGISetEnvIf can set empty values");
+    ok t_cmp($envs->{'TEST_DOCROOT'},     $docroot,     "ProxyFCGISetEnvIf can replace with request variables");
+    ok t_cmp($envs->{'TEST_CGI_VERSION'}, 'v1.1',       "ProxyFCGISetEnvIf can replace with backreferences");
+    ok t_cmp($envs->{'REMOTE_ADDR'},      undef,        "ProxyFCGISetEnvIf can unset var");
 }
 
-# Check the response values.
-my $docroot = Apache::Test::vars('documentroot');
-
-ok t_cmp($envs{'QUERY_STRING'},     'test_value', "ProxyFCGISetEnvIf can override an existing variable");
-ok t_cmp($envs{'TEST_NOT_SET'},     undef,        "ProxyFCGISetEnvIf does not set variables if condition is false");
-ok t_cmp($envs{'TEST_EMPTY'},       '',           "ProxyFCGISetEnvIf can set empty values");
-ok t_cmp($envs{'TEST_DOCROOT'},     $docroot,     "ProxyFCGISetEnvIf can replace with request variables");
-ok t_cmp($envs{'TEST_CGI_VERSION'}, 'v1.1',       "ProxyFCGISetEnvIf can replace with backreferences");
-ok t_cmp($envs{'REMOTE_ADDR'},      undef,        "ProxyFCGISetEnvIf can unset var");
+# Regression test for PR61202.
+$envs = run_fcgi_envvar_request($fcgi_port, "/modules/proxy/fcgi/index.php");
 
-# Rejoin the child FCGI process.
-waitpid($child, 0);
+ok t_cmp($envs->{'SCRIPT_NAME'}, '/modules/proxy/fcgi/index.php', "Server sets correct SCRIPT_NAME by default");



Re: svn commit: r1799689 - in /httpd/test/framework/trunk/t: conf/proxy.conf.in htdocs/modules/proxy/fcgi/ htdocs/modules/proxy/fcgi/index.php modules/proxy_fcgi.t

Posted by Jacob Champion <ch...@gmail.com>.
On 06/23/2017 01:22 PM, Jim Jagielski wrote:
> This is cool. Thx. It's inline with what I was hoping to do.

No problem!

> I'm curious though Since we never actually *run* php-fpm on the
> PHP script, we never see what PHP actually determines are these
> parameters, right?

So like you said on IRC: the entire point of PHP-FPM mode is to work 
with PHP as it exists today. But "work" means different things to 
different people. Some people just want the scripts to *run*; other 
people need the values of the envvars to remain exactly compatible 
because they use them within their scripts.

So the regression test for a default, unset BackendType doesn't really 
need to run FPM, because we can't change the envvar values we send by 
default anyway. (Because that would potentially break, and has already 
broken, users who are using those values for some other reason.) What we 
need to check instead is that the unset BackendType behaves exactly as 
2.4.20 did, so that no users upgrading from pre-2.4.20 are broken by our 
latest release.

I don't see a need for an FPM mode at moment, because the 2.4.20 
behavior that should become the default in 2.4.27 *seemed* to work for 
the vast majority of people. (I was the person who filed the proxy: 
prefix bug, and I have a better solution to that now with Eric's 
ProxyFCGISetEnvIf.) But we shipped FPM mode and I can't very well remove 
it. If you want FPM mode to do something differently from 2.4.20's 
behavior, it'd be good to explain what that is and why you want it.

(All that said, an integration test with FPM would be great to have on 
top of the regression test for obvious reasons. It just serves a 
different purpose.)

--Jacob

Re: svn commit: r1799689 - in /httpd/test/framework/trunk/t: conf/proxy.conf.in htdocs/modules/proxy/fcgi/ htdocs/modules/proxy/fcgi/index.php modules/proxy_fcgi.t

Posted by Jim Jagielski <ji...@jaguNET.com>.
This is cool. Thx. It's inline with what I was hoping to do.

I'm curious though Since we never actually *run* php-fpm on the
PHP script, we never see what PHP actually determines are these
parameters, right?

> On Jun 23, 2017, at 1:50 PM, jchampion@apache.org wrote:
> 
> Author: jchampion
> Date: Fri Jun 23 17:50:31 2017
> New Revision: 1799689
> 
> URL: http://svn.apache.org/viewvc?rev=1799689&view=rev
> Log:
> proxy_fcgi: add regression test for PR61202
> 
> Also refactor the FCGI backend daemon and envvar-echo request into a
> callable subroutine.
> 
> Added:
>    httpd/test/framework/trunk/t/htdocs/modules/proxy/fcgi/
>    httpd/test/framework/trunk/t/htdocs/modules/proxy/fcgi/index.php   (with props)
> Modified:
>    httpd/test/framework/trunk/t/conf/proxy.conf.in
>    httpd/test/framework/trunk/t/modules/proxy_fcgi.t
> 
> Modified: httpd/test/framework/trunk/t/conf/proxy.conf.in
> URL: http://svn.apache.org/viewvc/httpd/test/framework/trunk/t/conf/proxy.conf.in?rev=1799689&r1=1799688&r2=1799689&view=diff
> ==============================================================================
> --- httpd/test/framework/trunk/t/conf/proxy.conf.in (original)
> +++ httpd/test/framework/trunk/t/conf/proxy.conf.in Fri Jun 23 17:50:31 2017
> @@ -63,6 +63,12 @@
>         ProxyFCGISetEnvIf true !REMOTE_ADDR
>       </Location>
>     </IfVersion>
> +
> +    <Directory @SERVERROOT@/htdocs/modules/proxy/fcgi>
> +      <FilesMatch \.php$>
> +        SetHandler proxy:fcgi://127.0.0.1:${FCGI_PORT}
> +      </FilesMatch>
> +    </Directory>
>   </VirtualHost>
> </IfModule>
> 
> 
> Added: httpd/test/framework/trunk/t/htdocs/modules/proxy/fcgi/index.php
> URL: http://svn.apache.org/viewvc/httpd/test/framework/trunk/t/htdocs/modules/proxy/fcgi/index.php?rev=1799689&view=auto
> ==============================================================================
> --- httpd/test/framework/trunk/t/htdocs/modules/proxy/fcgi/index.php (added)
> +++ httpd/test/framework/trunk/t/htdocs/modules/proxy/fcgi/index.php Fri Jun 23 17:50:31 2017
> @@ -0,0 +1,3 @@
> +<?php
> +  /* This does nothing; it's just a placeholder. */
> +?>
> 
> Propchange: httpd/test/framework/trunk/t/htdocs/modules/proxy/fcgi/index.php
> ------------------------------------------------------------------------------
>    svn:eol-style = native
> 
> Modified: httpd/test/framework/trunk/t/modules/proxy_fcgi.t
> URL: http://svn.apache.org/viewvc/httpd/test/framework/trunk/t/modules/proxy_fcgi.t?rev=1799689&r1=1799688&r2=1799689&view=diff
> ==============================================================================
> --- httpd/test/framework/trunk/t/modules/proxy_fcgi.t (original)
> +++ httpd/test/framework/trunk/t/modules/proxy_fcgi.t Fri Jun 23 17:50:31 2017
> @@ -5,12 +5,13 @@ use Apache::Test;
> use Apache::TestRequest;
> use Apache::TestUtil;
> 
> -plan tests => 7,
> +my $have_fcgisetenvif = have_min_apache_version('2.4.26');
> +
> +plan tests => (7 * $have_fcgisetenvif) + 2,
>      need (
>         'mod_proxy_fcgi',
>         'FCGI',
> -        'IO::Select',
> -        need_min_apache_version('2.4.26')
> +        'IO::Select'
>      );
> 
> require FCGI;
> @@ -76,6 +77,55 @@ sub run_fcgi_handler($$)
>     return $pid;
> }
> 
> +# Convenience wrapper for run_fcgi_handler() that will echo back the envvars in
> +# the response. Returns the child PID; exits on failure.
> +sub launch_envvar_echo_daemon($)
> +{
> +    my $fcgi_port = shift;
> +
> +    return run_fcgi_handler($fcgi_port, sub {
> +        # Echo all the envvars back to the client.
> +        print("Content-Type: text/plain\r\n\r\n");
> +        foreach my $key (sort(keys %ENV)) {
> +            print($key, "=", $ENV{$key}, "\n");
> +        }
> +    });
> +}
> +
> +# Runs a single request using launch_envvar_echo_daemon(), then returns a
> +# hashref containing the environment variables that were echoed by the FCGI
> +# backend.
> +#
> +# Calling this function will run one test that must be accounted for in the test
> +# plan.
> +sub run_fcgi_envvar_request($$)
> +{
> +    my $fcgi_port = shift;
> +    my $uri       = shift;
> +
> +    # Launch the FCGI process.
> +    my $child = launch_envvar_echo_daemon($fcgi_port);
> +
> +    # Hit the backend.
> +    my $r = GET($uri);
> +    ok t_cmp($r->code, 200, "proxy to FCGI backend works");
> +
> +    # Split the returned envvars into a dictionary.
> +    my %envs = ();
> +
> +    foreach my $line (split /\n/, $r->content) {
> +        t_debug("> $line"); # log the response lines for debugging
> +
> +        my @components = split /=/, $line, 2;
> +        $envs{$components[0]} = $components[1];
> +    }
> +
> +    # Rejoin the child FCGI process.
> +    waitpid($child, 0);
> +
> +    return \%envs;
> +}
> +
> #
> # MAIN
> #
> @@ -85,39 +135,24 @@ sub run_fcgi_handler($$)
> # for the proxy_fcgi vhost is one greater than the reserved FCGI_PORT, but
> # depending on the test conditions, that may not always be the case...
> my $fcgi_port = Apache::Test::vars('proxy_fcgi_port') - 1;
> +my $envs;
> 
> -# Launch the FCGI process.
> -my $child = run_fcgi_handler($fcgi_port, sub {
> -    # Echo all the envvars back to the client.
> -    print("Content-Type: text/plain\r\n\r\n");
> -    foreach my $key (sort(keys %ENV)) {
> -        print($key, "=", $ENV{$key}, "\n");
> -    }
> -});
> -
> -# Hit the backend.
> -my $r = GET("/fcgisetenv?query");
> -ok t_cmp($r->code, 200, "proxy to FCGI backend");
> -
> -# Split the returned envvars into a dictionary.
> -my %envs = ();
> -
> -foreach my $line (split /\n/, $r->content) {
> -    t_debug("> $line"); # log the response lines for debugging
> -
> -    my @components = split /=/, $line, 2;
> -    $envs{$components[0]} = $components[1];
> +if ($have_fcgisetenvif) {
> +    # ProxyFCGISetEnvIf tests. Query the backend.
> +    $envs = run_fcgi_envvar_request($fcgi_port, "/fcgisetenv?query");
> +
> +    # Check the response values.
> +    my $docroot = Apache::Test::vars('documentroot');
> +
> +    ok t_cmp($envs->{'QUERY_STRING'},     'test_value', "ProxyFCGISetEnvIf can override an existing variable");
> +    ok t_cmp($envs->{'TEST_NOT_SET'},     undef,        "ProxyFCGISetEnvIf does not set variables if condition is false");
> +    ok t_cmp($envs->{'TEST_EMPTY'},       '',           "ProxyFCGISetEnvIf can set empty values");
> +    ok t_cmp($envs->{'TEST_DOCROOT'},     $docroot,     "ProxyFCGISetEnvIf can replace with request variables");
> +    ok t_cmp($envs->{'TEST_CGI_VERSION'}, 'v1.1',       "ProxyFCGISetEnvIf can replace with backreferences");
> +    ok t_cmp($envs->{'REMOTE_ADDR'},      undef,        "ProxyFCGISetEnvIf can unset var");
> }
> 
> -# Check the response values.
> -my $docroot = Apache::Test::vars('documentroot');
> -
> -ok t_cmp($envs{'QUERY_STRING'},     'test_value', "ProxyFCGISetEnvIf can override an existing variable");
> -ok t_cmp($envs{'TEST_NOT_SET'},     undef,        "ProxyFCGISetEnvIf does not set variables if condition is false");
> -ok t_cmp($envs{'TEST_EMPTY'},       '',           "ProxyFCGISetEnvIf can set empty values");
> -ok t_cmp($envs{'TEST_DOCROOT'},     $docroot,     "ProxyFCGISetEnvIf can replace with request variables");
> -ok t_cmp($envs{'TEST_CGI_VERSION'}, 'v1.1',       "ProxyFCGISetEnvIf can replace with backreferences");
> -ok t_cmp($envs{'REMOTE_ADDR'},      undef,        "ProxyFCGISetEnvIf can unset var");
> +# Regression test for PR61202.
> +$envs = run_fcgi_envvar_request($fcgi_port, "/modules/proxy/fcgi/index.php");
> 
> -# Rejoin the child FCGI process.
> -waitpid($child, 0);
> +ok t_cmp($envs->{'SCRIPT_NAME'}, '/modules/proxy/fcgi/index.php', "Server sets correct SCRIPT_NAME by default");
> 
>