-/* $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>
#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>
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)
{
-/* $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>
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);
-/* $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>
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;
h->type = FCGI_PARAMS;
h->content_len = param.total_len = 0;
- if (fcgi_add_param(¶m, "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(¶m, "SCRIPT_FILENAME", str,
- clt);
- free(str);
- if (ret == -1) {
+ if (scriptlen) {
+ if (fcgi_add_param(¶m, "PATH_INFO",
+ script + scriptlen, clt) == -1) {
errstr = "failed to encode param";
goto fail;
}
+ script[scriptlen] = '\0';
+ }
+
+ if (fcgi_add_param(¶m, "SCRIPT_NAME",
+ script + strlen(srv_conf->root), clt) == -1) {
+ errstr = "failed to encode param";
+ goto fail;
+ }
+ if (fcgi_add_param(¶m, "SCRIPT_FILENAME", script, clt) == -1) {
+ errstr = "failed to encode param";
+ goto fail;
}
if (desc->http_query)
goto fail;
}
+ if (fcgi_add_param(¶m, "DOCUMENT_ROOT", srv_conf->root,
+ clt) == -1) {
+ errstr = "failed to encode param";
+ goto fail;
+ }
if (fcgi_add_param(¶m, "DOCUMENT_URI", desc->http_path,
clt) == -1) {
errstr = "failed to encode param";
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);