From e46d51a0fa0c672b0f4d1e004169f6c2e99fd3d5 Mon Sep 17 00:00:00 2001 From: reyk Date: Sun, 3 Aug 2014 11:16:10 +0000 Subject: [PATCH] Split fastcgi socket path and document root option and add the SCRIPT_FILENAME CGI param with a prepended root. This fixes php-fpm that expects SCRIPT_FILENAME and also works with slowcgi if you configure the root correctly. For example, if SCRIPT_NAME and REQUEST_URI are /php/index.php, root is /htdocs, SCRIPT_FILENAME will be /htdocs/php/index.php. As tested and discussed with florian@ --- usr.sbin/httpd/config.c | 19 +++++++++---------- usr.sbin/httpd/httpd.h | 28 +++++++++++++++------------- usr.sbin/httpd/parse.y | 27 +++++++++++---------------- usr.sbin/httpd/server_fcgi.c | 31 +++++++++++++++++++++---------- usr.sbin/httpd/server_file.c | 6 +++--- 5 files changed, 59 insertions(+), 52 deletions(-) diff --git a/usr.sbin/httpd/config.c b/usr.sbin/httpd/config.c index 650514e2910..42fcab6fe00 100644 --- a/usr.sbin/httpd/config.c +++ b/usr.sbin/httpd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.11 2014/08/02 21:21:47 doug Exp $ */ +/* $OpenBSD: config.c,v 1.12 2014/08/03 11:16:10 reyk Exp $ */ /* * Copyright (c) 2011 - 2014 Reyk Floeter @@ -238,19 +238,18 @@ config_getserver_config(struct httpd *env, struct server *srv, if ((srv_conf->flags & f) == 0) srv_conf->flags |= srv->srv_conf.flags & f; - f = SRVFLAG_PATH|SRVFLAG_FCGI; + f = SRVFLAG_SOCKET|SRVFLAG_FCGI; if ((srv_conf->flags & f) == SRVFLAG_FCGI) { - (void)strlcpy(srv_conf->path, - HTTPD_FCGI_SOCKET, - sizeof(srv_conf->path)); - srv_conf->flags |= SRVFLAG_PATH; + srv_conf->flags |= f; + (void)strlcpy(srv_conf->socket, HTTPD_FCGI_SOCKET, + sizeof(srv_conf->socket)); } - f = SRVFLAG_PATH; + f = SRVFLAG_ROOT; if ((srv_conf->flags & f) == 0) { - (void)strlcpy(srv_conf->path, - srv->srv_conf.path, - sizeof(srv_conf->path)); + srv_conf->flags |= srv->srv_conf.flags & f; + (void)strlcpy(srv_conf->root, srv->srv_conf.root, + sizeof(srv_conf->root)); } f = SRVFLAG_FCGI|SRVFLAG_NO_FCGI; diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h index a47e4c99a40..b7f6b351a3b 100644 --- a/usr.sbin/httpd/httpd.h +++ b/usr.sbin/httpd/httpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: httpd.h,v 1.34 2014/08/03 10:26:43 reyk Exp $ */ +/* $OpenBSD: httpd.h,v 1.35 2014/08/03 11:16:10 reyk Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter @@ -285,20 +285,21 @@ struct client { }; SPLAY_HEAD(client_tree, client); -#define SRVFLAG_INDEX 0x001 -#define SRVFLAG_NO_INDEX 0x002 -#define SRVFLAG_AUTO_INDEX 0x004 -#define SRVFLAG_NO_AUTO_INDEX 0x008 -#define SRVFLAG_PATH 0x010 -#define SRVFLAG_LOCATION 0x020 -#define SRVFLAG_FCGI 0x040 -#define SRVFLAG_NO_FCGI 0x080 -#define SRVFLAG_LOG 0x100 -#define SRVFLAG_NO_LOG 0x200 +#define SRVFLAG_INDEX 0x0001 +#define SRVFLAG_NO_INDEX 0x0002 +#define SRVFLAG_AUTO_INDEX 0x0004 +#define SRVFLAG_NO_AUTO_INDEX 0x0008 +#define SRVFLAG_ROOT 0x0010 +#define SRVFLAG_LOCATION 0x0020 +#define SRVFLAG_FCGI 0x0040 +#define SRVFLAG_NO_FCGI 0x0080 +#define SRVFLAG_LOG 0x0100 +#define SRVFLAG_NO_LOG 0x0200 +#define SRVFLAG_SOCKET 0x0400 #define SRVFLAG_BITS \ "\10\01INDEX\02NO_INDEX\03AUTO_INDEX\04NO_AUTO_INDEX" \ - "\05PATH\06LOCATION\07FCGI\10NO_FCGI\11LOG\12NO_LOG" + "\05ROOT\06LOCATION\07FCGI\10NO_FCGI\11LOG\12NO_LOG\13SOCKET" #define TCPFLAG_NODELAY 0x01 #define TCPFLAG_NNODELAY 0x02 @@ -325,7 +326,8 @@ struct server_config { char name[MAXHOSTNAMELEN]; char location[NAME_MAX]; char index[NAME_MAX]; - char path[MAXPATHLEN]; + char root[MAXPATHLEN]; + char socket[MAXPATHLEN]; in_port_t port; struct sockaddr_storage ss; diff --git a/usr.sbin/httpd/parse.y b/usr.sbin/httpd/parse.y index 2ff7c505dae..74f5a2a354b 100644 --- a/usr.sbin/httpd/parse.y +++ b/usr.sbin/httpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.17 2014/08/03 10:26:43 reyk Exp $ */ +/* $OpenBSD: parse.y,v 1.18 2014/08/03 11:16:10 reyk Exp $ */ /* * Copyright (c) 2007 - 2014 Reyk Floeter @@ -210,8 +210,8 @@ server : SERVER STRING { } free($2); - strlcpy(s->srv_conf.path, HTTPD_DOCROOT, - sizeof(s->srv_conf.path)); + strlcpy(s->srv_conf.root, HTTPD_DOCROOT, + sizeof(s->srv_conf.root)); strlcpy(s->srv_conf.index, HTTPD_INDEX, sizeof(s->srv_conf.index)); s->srv_conf.id = ++last_server_id; @@ -280,20 +280,15 @@ serveroptsl : LISTEN ON STRING port { host_free(&al); } | ROOT STRING { - if (srv->srv_conf.flags & SRVFLAG_FCGI) { - yyerror("root conflicts with fastcgi"); - free($2); - YYERROR; - } - if (strlcpy(srv->srv_conf.path, $2, - sizeof(srv->srv_conf.path)) >= - sizeof(srv->srv_conf.path)) { + if (strlcpy(srv->srv_conf.root, $2, + sizeof(srv->srv_conf.root)) >= + sizeof(srv->srv_conf.root)) { yyerror("document root too long"); free($2); YYERROR; } free($2); - srv->srv_conf.flags |= SRVFLAG_PATH; + srv->srv_conf.flags |= SRVFLAG_ROOT; } | DIRECTORY dirflags | DIRECTORY '{' dirflags_l '}' @@ -397,15 +392,15 @@ fcgiflags_l : fcgiflags comma fcgiflags_l ; fcgiflags : SOCKET STRING { - if (strlcpy(srv->srv_conf.path, $2, - sizeof(srv->srv_conf.path)) >= - sizeof(srv->srv_conf.path)) { + if (strlcpy(srv->srv_conf.socket, $2, + sizeof(srv->srv_conf.socket)) >= + sizeof(srv->srv_conf.socket)) { yyerror("fastcgi socket too long"); free($2); YYERROR; } free($2); - srv->srv_conf.flags |= SRVFLAG_PATH; + srv->srv_conf.flags |= SRVFLAG_SOCKET; } ; diff --git a/usr.sbin/httpd/server_fcgi.c b/usr.sbin/httpd/server_fcgi.c index d65d3474553..63978d9735e 100644 --- a/usr.sbin/httpd/server_fcgi.c +++ b/usr.sbin/httpd/server_fcgi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_fcgi.c,v 1.13 2014/08/03 10:38:42 reyk Exp $ */ +/* $OpenBSD: server_fcgi.c,v 1.14 2014/08/03 11:16:10 reyk Exp $ */ /* * Copyright (c) 2014 Florian Obser @@ -98,14 +98,14 @@ server_fcgi(struct httpd *env, struct client *clt) struct fcgi_begin_request_body *begin; struct kv *kv, key; size_t len; - int fd = -1, total_len; + int fd = -1, total_len, ret; const char *errstr = NULL; - char *request_uri, *p; + char *str, *p; in_port_t port; struct sockaddr_storage ss; - if (srv_conf->path[0] == ':') { - p = srv_conf->path + 1; + if (srv_conf->socket[0] == ':') { + p = srv_conf->socket + 1; port = strtonum(p, 0, 0xffff, &errstr); if (errstr != NULL) { @@ -127,7 +127,7 @@ server_fcgi(struct httpd *env, struct client *clt) memset(&sun, 0, sizeof(sun)); sun.sun_family = AF_UNIX; len = strlcpy(sun.sun_path, - srv_conf->path, sizeof(sun.sun_path)); + srv_conf->socket, sizeof(sun.sun_path)); if (len >= sizeof(sun.sun_path)) { errstr = "socket path to long"; goto fail; @@ -190,6 +190,16 @@ server_fcgi(struct httpd *env, struct client *clt) goto fail; } + if (asprintf(&str, "%s%s", srv_conf->root, desc->http_path) != -1) { + ret = fcgi_add_param(buf, "SCRIPT_FILENAME", str, + &total_len, clt); + free(str); + if (ret == -1) { + errstr = "failed to encode param"; + goto fail; + } + } + if (desc->http_query) if (fcgi_add_param(buf, "QUERY_STRING", desc->http_query, &total_len, clt) == -1) { @@ -295,14 +305,15 @@ server_fcgi(struct httpd *env, struct client *clt) errstr = "failed to encode param"; goto fail; } - } else if (asprintf(&request_uri, "%s?%s", desc->http_path, + } else if (asprintf(&str, "%s?%s", desc->http_path, desc->http_query) != -1) { - if (fcgi_add_param(buf, "REQUEST_URI", request_uri, &total_len, - clt) == -1) { + ret = fcgi_add_param(buf, "REQUEST_URI", str, + &total_len, clt); + free(str); + if (ret == -1) { errstr = "failed to encode param"; goto fail; } - free(request_uri); } (void)print_host(&clt->clt_srv_ss, hbuf, sizeof(hbuf)); diff --git a/usr.sbin/httpd/server_file.c b/usr.sbin/httpd/server_file.c index 5985681acdd..4a906612dd6 100644 --- a/usr.sbin/httpd/server_file.c +++ b/usr.sbin/httpd/server_file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_file.c,v 1.24 2014/08/02 09:54:13 reyk Exp $ */ +/* $OpenBSD: server_file.c,v 1.25 2014/08/03 11:16:10 reyk Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter @@ -148,7 +148,7 @@ server_file(struct httpd *env, struct client *clt) /* Request path is already canonicalized */ if ((size_t)snprintf(path, sizeof(path), "%s%s", - srv_conf->path, desc->http_path) >= sizeof(path)) { + srv_conf->root, desc->http_path) >= sizeof(path)) { /* Do not echo the uncanonicalized path */ server_abort_http(clt, 500, desc->http_path); return (-1); @@ -226,7 +226,7 @@ server_file_index(struct httpd *env, struct client *clt) /* Request path is already canonicalized */ if ((size_t)snprintf(path, sizeof(path), "%s%s", - srv_conf->path, desc->http_path) >= sizeof(path)) + srv_conf->root, desc->http_path) >= sizeof(path)) goto fail; /* Now open the file, should be readable or we have another problem */ -- 2.20.1