-.\" $OpenBSD: httpd.conf.5,v 1.41 2015/01/03 15:49:18 reyk Exp $
+.\" $OpenBSD: httpd.conf.5,v 1.42 2015/01/04 22:23:58 chrisz Exp $
.\"
.\" Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org>
.\"
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: January 3 2015 $
+.Dd $Mdocdate: January 4 2015 $
.Dt HTTPD.CONF 5
.Os
.Sh NAME
.Xr syslog 3
instead of the log files.
.El
-.It Ic root Ar directory
+.It Ic root Ar option
+Valid options are:
+.Bl -tag -width Ds
+.It Ar directory
Set the document root of the server.
The
.Ar directory
.Nm httpd .
If not specified, it defaults to
.Pa /htdocs .
+.It Ic strip Ar number
+Strip
+.Ar number
+path components from the beginning of the request URI before
+looking up the stripped-down URI at the document root.
+.El
.It Ic tcp Ar option
Enable or disable the specified TCP/IP options; see
.Xr tcp 4
-/* $OpenBSD: httpd.h,v 1.65 2015/01/02 19:09:52 reyk Exp $ */
+/* $OpenBSD: httpd.h,v 1.66 2015/01/04 22:23:58 chrisz Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
char *tls_key_file;
u_int32_t flags;
+ int strip;
u_int8_t tcpflags;
int tcpbufsiz;
int tcpbacklog;
void server_reset_http(struct client *);
void server_close_http(struct client *);
int server_response(struct httpd *, struct client *);
+const char *
+ server_root_strip(const char *, int);
struct server_config *
server_getlocation(struct client *, const char *);
const char *
-/* $OpenBSD: parse.y,v 1.49 2015/01/03 23:54:25 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.50 2015/01/04 22:23:58 chrisz Exp $ */
/*
* Copyright (c) 2007 - 2014 Reyk Floeter <reyk@openbsd.org>
%token ACCESS ALIAS AUTO BACKLOG BODY BUFFER CERTIFICATE CHROOT CIPHERS COMMON
%token COMBINED CONNECTION DIRECTORY ERR FCGI INDEX IP KEY LISTEN LOCATION
%token LOG LOGDIR MAXIMUM NO NODELAY ON PORT PREFORK REQUEST REQUESTS ROOT
-%token SACK SERVER SOCKET STYLE SYSLOG TCP TIMEOUT TLS TYPES
+%token SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TIMEOUT TLS TYPES
%token ERROR INCLUDE
%token <v.string> STRING
%token <v.number> NUMBER
YYERROR;
}
} tls
- | ROOT STRING {
- 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_ROOT;
- }
+ | ROOT rootflags
+ | ROOT '{' rootflags_l '}'
| DIRECTORY dirflags
| DIRECTORY '{' dirflags_l '}'
| logformat
}
;
+rootflags_l : rootflags comma rootflags_l
+ | rootflags
+ ;
+
+rootflags : STRING {
+ if (strlcpy(srv->srv_conf.root, $1,
+ sizeof(srv->srv_conf.root)) >=
+ sizeof(srv->srv_conf.root)) {
+ yyerror("document root too long");
+ free($1);
+ YYERROR;
+ }
+ free($1);
+ srv->srv_conf.flags |= SRVFLAG_ROOT;
+ }
+ | STRIP NUMBER {
+ if ($2 < 0 || $2 > INT_MAX) {
+ yyerror("invalid strip number");
+ YYERROR;
+ }
+ srv->srv_conf.strip = $2;
+ }
+ ;
+
dirflags_l : dirflags comma dirflags_l
| dirflags
;
{ "sack", SACK },
{ "server", SERVER },
{ "socket", SOCKET },
+ { "strip", STRIP },
{ "style", STYLE },
{ "syslog", SYSLOG },
{ "tcp", TCP },
-/* $OpenBSD: server_fcgi.c,v 1.43 2014/12/21 00:54:49 guenther Exp $ */
+/* $OpenBSD: server_fcgi.c,v 1.44 2015/01/04 22:23:58 chrisz Exp $ */
/*
* Copyright (c) 2014 Florian Obser <florian@openbsd.org>
size_t scriptlen;
int pathlen;
int fd = -1, ret;
- const char *errstr = NULL;
- char *str, *p, *script = NULL;
+ const char *stripped, *p, *alias, *errstr = NULL;
+ char *str, *script = NULL;
if (srv_conf->socket[0] == ':') {
struct sockaddr_storage ss;
h->type = FCGI_PARAMS;
h->content_len = param.total_len = 0;
- if ((pathlen = asprintf(&script, "%s%s", srv_conf->root,
- desc->http_path_alias != NULL ?
- desc->http_path_alias : desc->http_path)) == -1) {
+ alias = desc->http_path_alias != NULL
+ ? desc->http_path_alias
+ : desc->http_path;
+
+ stripped = server_root_strip(alias, srv_conf->strip);
+ if ((pathlen = asprintf(&script, "%s%s", srv_conf->root, stripped))
+ == -1) {
errstr = "failed to get script name";
goto fail;
}
script[scriptlen] = '\0';
}
- if (fcgi_add_param(¶m, "SCRIPT_NAME",
- script + strlen(srv_conf->root), clt) == -1) {
+ /*
+ * calculate length of http SCRIPT_NAME:
+ * add length of stripped prefix,
+ * subtract length of prepended local root
+ */
+ scriptlen += (stripped - alias) - strlen(srv_conf->root);
+ if ((str = strndup(alias, scriptlen)) == NULL)
+ goto fail;
+ ret = fcgi_add_param(¶m, "SCRIPT_NAME", str, clt);
+ free(str);
+ if (ret == -1) {
errstr = "failed to encode param";
goto fail;
}
-/* $OpenBSD: server_file.c,v 1.43 2015/01/01 14:15:02 reyk Exp $ */
+/* $OpenBSD: server_file.c,v 1.44 2015/01/04 22:23:58 chrisz Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
struct http_descriptor *desc = clt->clt_descreq;
struct server_config *srv_conf = clt->clt_srv_conf;
char path[MAXPATHLEN];
- const char *errstr = NULL;
+ const char *stripped, *errstr = NULL;
int ret = 500;
if (srv_conf->flags & SRVFLAG_FCGI)
return (server_fcgi(env, clt));
/* Request path is already canonicalized */
- if ((size_t)snprintf(path, sizeof(path), "%s%s",
- srv_conf->root,
+ stripped = server_root_strip(
desc->http_path_alias != NULL ?
- desc->http_path_alias : desc->http_path) >= sizeof(path)) {
+ desc->http_path_alias : desc->http_path,
+ srv_conf->strip);
+ if ((size_t)snprintf(path, sizeof(path), "%s%s",
+ srv_conf->root, stripped) >= sizeof(path)) {
errstr = desc->http_path;
goto abort;
}
int code = 500;
struct evbuffer *evb = NULL;
struct media_type *media;
- const char *style;
+ const char *stripped, *style;
struct tm tm;
time_t t, dir_mtime;
}
/* Request path is already canonicalized */
+ stripped = server_root_strip(desc->http_path, srv_conf->strip);
if ((size_t)snprintf(path, sizeof(path), "%s%s",
- srv_conf->root, desc->http_path) >= sizeof(path))
+ srv_conf->root, stripped) >= sizeof(path))
goto abort;
/* Now open the file, should be readable or we have another problem */
-/* $OpenBSD: server_http.c,v 1.58 2015/01/01 14:15:02 reyk Exp $ */
+/* $OpenBSD: server_http.c,v 1.59 2015/01/04 22:23:58 chrisz Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
return (-1);
}
+const char *
+server_root_strip(const char *path, int n)
+{
+ const char *p;
+
+ /* Strip strip leading directories. Leading '/' is ignored. */
+ for (; n > 0 && *path != '\0'; n--)
+ if ((p = strchr(++path, '/')) == NULL)
+ path = strchr(path, '\0');
+ else
+ path = p;
+
+ return (path);
+}
+
struct server_config *
server_getlocation(struct client *clt, const char *path)
{