summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2014-08-04 14:49:25 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2014-08-04 14:49:25 +0000
commit8ffa92dd2bfbed46a8fb2ea394d810a8b8217f30 (patch)
treec3a984fb63b06f4a8192324785b5e3a67052b0ee
parentce896b3f214d3f9c11ecd57293d2b78d2415f3bb (diff)
Implement PATH_INFO and add DOCUMENT_ROOT.
PATH_INFO was requested by naddy@ who successfully tested it with "cvsweb". ok naddy@
-rw-r--r--usr.sbin/httpd/httpd.c27
-rw-r--r--usr.sbin/httpd/httpd.h3
-rw-r--r--usr.sbin/httpd/server_fcgi.c38
3 files changed, 56 insertions, 12 deletions
diff --git a/usr.sbin/httpd/httpd.c b/usr.sbin/httpd/httpd.c
index c807dd4ed45..be3e1772d55 100644
--- a/usr.sbin/httpd/httpd.c
+++ b/usr.sbin/httpd/httpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: httpd.c,v 1.13 2014/08/04 11:09:25 reyk Exp $ */
+/* $OpenBSD: httpd.c,v 1.14 2014/08/04 14:49:24 reyk Exp $ */
/*
* Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org>
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/hash.h>
@@ -515,6 +516,30 @@ canonicalize_path(const char *input, char *path, size_t len)
return (path);
}
+ssize_t
+path_info(char *name)
+{
+ char *p, *start, *end;
+ char path[MAXPATHLEN];
+ struct stat st;
+
+ if (strlcpy(path, name, sizeof(path)) >= sizeof(path))
+ return (-1);
+
+ start = path;
+ end = start + strlen(path);
+
+ for (p = end; p > start; p--) {
+ if (*p != '/')
+ continue;
+ if (stat(path, &st) == 0)
+ break;
+ *p = '\0';
+ }
+
+ return (strlen(path));
+}
+
void
socket_rlimit(int maxfd)
{
diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h
index 92413cc6d22..e62bac3064e 100644
--- a/usr.sbin/httpd/httpd.h
+++ b/usr.sbin/httpd/httpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: httpd.h,v 1.38 2014/08/04 06:35:10 deraadt Exp $ */
+/* $OpenBSD: httpd.h,v 1.39 2014/08/04 14:49:24 reyk Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -473,6 +473,7 @@ void event_again(struct event *, int, short,
struct timeval *, struct timeval *, void *);
const char *canonicalize_host(const char *, char *, size_t);
const char *canonicalize_path(const char *, char *, size_t);
+ssize_t path_info(char *);
void imsg_event_add(struct imsgev *);
int imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t,
pid_t, int, void *, u_int16_t);
diff --git a/usr.sbin/httpd/server_fcgi.c b/usr.sbin/httpd/server_fcgi.c
index 87e1eb43777..a5ba108a67e 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.19 2014/08/04 11:09:25 reyk Exp $ */
+/* $OpenBSD: server_fcgi.c,v 1.20 2014/08/04 14:49:24 reyk Exp $ */
/*
* Copyright (c) 2014 Florian Obser <florian@openbsd.org>
@@ -102,9 +102,10 @@ server_fcgi(struct httpd *env, struct client *clt)
struct fcgi_record_header *h;
struct fcgi_begin_request_body *begin;
size_t len;
+ ssize_t scriptlen;
int fd = -1, ret;
const char *errstr = NULL;
- char *str, *p;
+ char *str, *p, *script = NULL;
in_port_t port;
struct sockaddr_storage ss;
@@ -188,20 +189,30 @@ server_fcgi(struct httpd *env, struct client *clt)
h->type = FCGI_PARAMS;
h->content_len = param.total_len = 0;
- if (fcgi_add_param(&param, "SCRIPT_NAME", desc->http_path,
- clt) == -1) {
- errstr = "failed to encode param";
+ if (asprintf(&script, "%s%s", srv_conf->root,
+ desc->http_path) == -1 ||
+ (scriptlen = path_info(script)) == -1) {
+ errstr = "failed to get script name";
goto fail;
}
- if (asprintf(&str, "%s%s", srv_conf->root, desc->http_path) != -1) {
- ret = fcgi_add_param(&param, "SCRIPT_FILENAME", str,
- clt);
- free(str);
- if (ret == -1) {
+ if (scriptlen) {
+ if (fcgi_add_param(&param, "PATH_INFO",
+ script + scriptlen, clt) == -1) {
errstr = "failed to encode param";
goto fail;
}
+ script[scriptlen] = '\0';
+ }
+
+ if (fcgi_add_param(&param, "SCRIPT_NAME",
+ script + strlen(srv_conf->root), clt) == -1) {
+ errstr = "failed to encode param";
+ goto fail;
+ }
+ if (fcgi_add_param(&param, "SCRIPT_FILENAME", script, clt) == -1) {
+ errstr = "failed to encode param";
+ goto fail;
}
if (desc->http_query)
@@ -211,6 +222,11 @@ server_fcgi(struct httpd *env, struct client *clt)
goto fail;
}
+ if (fcgi_add_param(&param, "DOCUMENT_ROOT", srv_conf->root,
+ clt) == -1) {
+ errstr = "failed to encode param";
+ goto fail;
+ }
if (fcgi_add_param(&param, "DOCUMENT_URI", desc->http_path,
clt) == -1) {
errstr = "failed to encode param";
@@ -321,8 +337,10 @@ server_fcgi(struct httpd *env, struct client *clt)
clt->clt_persist = 0;
clt->clt_done = 0;
+ free(script);
return (0);
fail:
+ free(script);
if (errstr == NULL)
errstr = strerror(errno);
server_abort_http(clt, 500, errstr);