Re: httpd: single FastCGI script handling all requests

2018-03-07 Thread Diogo Galvao

On 03/06/18 16:39, Diogo Galvao wrote:

The following patch makes it possible to handle all FastCGI requests
with a single script so it can route clean URLs itself.

Was it already possible some other way?



It's already possible to achieve the same result with the root option:

server "example.com" {
listen on * port 80
root "/htdocs/example.com"
location "*" {
fastcgi socket "/run/php-fpm.sock"
root "/htdocs/example.com/router.php"
}
}

So below is a small addition to httpd.conf.5 to make it more obvious to
future users, in case you find it relevant.

Sorry for the noise.


Index: httpd.conf.5
===
RCS file: /cvs/src/usr.sbin/httpd/httpd.conf.5,v
retrieving revision 1.89
diff -u -p -u -p -r1.89 httpd.conf.5
--- httpd.conf.54 Jan 2018 20:38:12 -   1.89
+++ httpd.conf.57 Mar 2018 22:59:17 -
@@ -468,6 +468,16 @@ root directory of
 .Nm httpd .
 If not specified, it defaults to
 .Pa /htdocs .
+.It Ar script
+When served by FastCGI, the
+.Ic root
+option may be the pathname to the single script within the
+.Xr chroot 2
+root directory that's responsible for handling all requests. In this case,
+the actual path requested by the client is made available to the FastCGI
+handler in the
+.Ic PATH_INFO
+variable.
 .It Ic strip Ar number
 Strip
 .Ar number




Re: httpd: single FastCGI script handling all requests

2018-03-07 Thread Diogo Galvao

On 03/07/18 05:36, Hiltjo Posthuma wrote:


Hi,

I wonder if it can't be done simpler with some wrapper program/script
that sets $SCRIPT_FILENAME to your router PHP script beforehand?

It it would then it would require no changes to httpd and be more useful
in other cases aswell.



Hi.

Thanks for the idea.

As I understand it, this wrapper would be another FastCGI server
that receives requests from httpd through its own socket, modifies
$SCRIPT_FILENAME, then forwards it to php-fpm. Unless it replaces
php-fpm altogether. Either way, if this really is the alternative then
I'm not sure it's any simpler than that diff.

I'll do some more research to see if it's possible to get the same
result of that diff with httpd as is.



Re: httpd: single FastCGI script handling all requests

2018-03-07 Thread Hiltjo Posthuma
On Tue, Mar 06, 2018 at 04:39:04PM -0300, Diogo Galvao wrote:
> The following patch makes it possible to handle all FastCGI requests
> with a single script so it can route clean URLs itself.
> 
> Was it already possible some other way?
> 
> And, regardless of this patch, is it even a feature you'd
> like to see in base? Any suggestion for a better implementation?
> 
> 
> server "example.com" {
>   listen on * port 80
>   root "/htdocs/example.com"
> 
>   location "/robots.txt" {
>   pass
>   }
>   location "/favicon.ico" {
>   pass
>   }
>   location "*" {
>   fastcgi {
>   socket "/run/php-fpm.sock"
>   with "/htdocs/example.com/router.php"
>   }
> }
> }
> 
> 
> Index: httpd.conf.5
> ===
> RCS file: /cvs/src/usr.sbin/httpd/httpd.conf.5,v
> retrieving revision 1.89
> diff -u -p -u -p -r1.89 httpd.conf.5
> --- httpd.conf.5  4 Jan 2018 20:38:12 -   1.89
> +++ httpd.conf.5  6 Mar 2018 19:11:56 -
> @@ -272,7 +272,12 @@ Disable the directory index.
>  .Xr httpd 8
>  will neither display nor generate a directory index.
>  .El
> -.It Oo Ic no Oc Ic fastcgi Op Ic socket Ar socket
> +.It Xo
> +.Op Ic no
> +.Ic fastcgi
> +.Op Ic socket Ar socket
> +.Op Ic with Ar script
> +.Xc
>  Enable FastCGI instead of serving files.
>  The
>  .Ar socket
> @@ -282,6 +287,14 @@ root directory of
>  .Xr httpd 8
>  and defaults to
>  .Pa /run/slowcgi.sock .
> +.Pp
> +If provided,
> +.Ar script
> +is a local path name within the
> +.Xr chroot 2
> +root directory of
> +.Xr httpd 8
> +that is used as the SCRIPT_FILENAME for all requests.
>  .Pp
>  The FastCGI handler will be given the following variables:
>  .Pp
> Index: httpd.h
> ===
> RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v
> retrieving revision 1.135
> diff -u -p -u -p -r1.135 httpd.h
> --- httpd.h   7 Feb 2018 03:28:05 -   1.135
> +++ httpd.h   6 Mar 2018 19:11:56 -
> @@ -397,13 +397,14 @@ SPLAY_HEAD(client_tree, client);
>  #define SRVFLAG_SERVER_MATCH 0x0020
>  #define SRVFLAG_SERVER_HSTS  0x0040
>  #define SRVFLAG_DEFAULT_TYPE 0x0080
> +#define SRVFLAG_FCGISCRIPT   0x0100
>  #define SRVFLAG_BITS \
>   "\10\01INDEX\02NO_INDEX\03AUTO_INDEX\04NO_AUTO_INDEX"   \
>   "\05ROOT\06LOCATION\07FCGI\10NO_FCGI\11LOG\12NO_LOG\13SOCKET"   \
>   "\14SYSLOG\15NO_SYSLOG\16TLS\17ACCESS_LOG\20ERROR_LOG"  \
>   "\21AUTH\22NO_AUTH\23BLOCK\24NO_BLOCK\25LOCATION_MATCH" \
> - "\26SERVER_MATCH\27SERVER_HSTS\30DEFAULT_TYPE"
> + "\26SERVER_MATCH\27SERVER_HSTS\30DEFAULT_TYPE\31FCGISCRIPT"
>  #define TCPFLAG_NODELAY  0x01
>  #define TCPFLAG_NNODELAY 0x02
> @@ -467,6 +468,7 @@ struct server_config {
>   char index[PATH_MAX];
>   char root[PATH_MAX];
>   char socket[PATH_MAX];
> + char fcgiscript[PATH_MAX];
>   char accesslog[PATH_MAX];
>   char errorlog[PATH_MAX];
>   struct media_typedefault_type;
> Index: parse.y
> ===
> RCS file: /cvs/src/usr.sbin/httpd/parse.y,v
> retrieving revision 1.92
> diff -u -p -u -p -r1.92 parse.y
> --- parse.y   28 Aug 2017 06:00:05 -  1.92
> +++ parse.y   6 Mar 2018 19:11:57 -
> @@ -674,6 +674,17 @@ fcgiflags: SOCKET STRING {
>   free($2);
>   srv_conf->flags |= SRVFLAG_SOCKET;
>   }
> + | WITH STRING   {
> + if (strlcpy(srv_conf->fcgiscript, $2,
> + sizeof(srv_conf->fcgiscript)) >=
> + sizeof(srv_conf->fcgiscript)) {
> + yyerror("fastcgi script too long");
> + free($2);
> + YYERROR;
> + }
> + free($2);
> + srv_conf->flags |= SRVFLAG_FCGISCRIPT;
> + }
>   ;
>  connection   : CONNECTION '{' optnl conflags_l '}'
> Index: server_fcgi.c
> ===
> RCS file: /cvs/src/usr.sbin/httpd/server_fcgi.c,v
> retrieving revision 1.75
> diff -u -p -u -p -r1.75 server_fcgi.c
> --- server_fcgi.c 31 Jul 2017 08:02:49 -  1.75
> +++ server_fcgi.c 6 Mar 2018 19:11:57 -
> @@ -236,9 +236,18 @@ server_fcgi(struct httpd *env, struct cl
>   errstr = "failed to encode param";
>   goto fail;
>   }
> - if (fcgi_add_param(, "SCRIPT_FILENAME", script, clt) == -1) {
> - errstr = "failed to encode param";
> - goto fail;
>