Skip to content

Commit

Permalink
fix: parse path info
Browse files Browse the repository at this point in the history
Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
  • Loading branch information
zhaojh329 committed Aug 30, 2021
1 parent ffdf7de commit 64c4888
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 43 deletions.
22 changes: 5 additions & 17 deletions src/cgi.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,33 +391,21 @@ void serve_cgi(struct uh_connection *conn, int event)

if (event == UH_EV_HEAD_COMPLETE) {
struct path_info *pi;
struct stat st;
struct stat *st;

pi = parse_path_info(conni);
if (!pi) {
conn->send_error(conn, HTTP_STATUS_BAD_REQUEST, NULL);
return;
}

if (stat(pi->phys, &st) < 0) {
int code;

switch (errno) {
case EACCES:
code = HTTP_STATUS_FORBIDDEN;
break;
case ENOENT:
code = HTTP_STATUS_NOT_FOUND;
break;
default:
code = HTTP_STATUS_INTERNAL_SERVER_ERROR;
};

conn->send_error(conn, code, NULL);
st = pi->st;
if (!st) {
conn->send_error(conn, HTTP_STATUS_NOT_FOUND, NULL);
return;
}

if (!S_ISLNK(st.st_mode) && !S_ISREG(st.st_mode)) {
if (!S_ISREG(st->st_mode)) {
conn->send_error(conn, 403, NULL);
return;
}
Expand Down
47 changes: 21 additions & 26 deletions src/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ struct path_info *parse_path_info(struct uh_connection_internal *conn)
static char path_phys[PATH_MAX];
static char path_info[PATH_MAX];
static struct path_info pi = {};
static struct stat st;
int docroot_len, i;

if (!docroot || !docroot[0])
Expand Down Expand Up @@ -82,24 +83,30 @@ struct path_info *parse_path_info(struct uh_connection_internal *conn)
memcpy(path_phys, buf, i);
path_phys[i] = '\0';

if (access(path_phys, F_OK))
if (stat(path_phys, &st) || !S_ISREG(st.st_mode))
continue;

snprintf(path_info, sizeof(path_info), "%s", buf + i);
break;
}

memset(&pi, 0, sizeof(struct path_info));

if (i > docroot_len) {
pi.phys = path_phys;
pi.name = &path_phys[docroot_len];
pi.st = &st;
} else {
pi.phys = buf;
pi.name = &buf[docroot_len];
pi.st = stat(pi.phys, &st) ? NULL : &st;
}

pi.root = docroot;
pi.info = path_info;

log_info("phys: %s, name: %s, info: %s\n", pi.phys, pi.name, pi.info);

return &pi;
}

Expand Down Expand Up @@ -298,7 +305,7 @@ void serve_file(struct uh_connection *conn)
struct path_info *pi = parse_path_info(conni);
uint64_t start, end;
const char *mime;
struct stat st;
struct stat *st;
bool ranged;
int fd, len;

Expand All @@ -307,25 +314,13 @@ void serve_file(struct uh_connection *conn)
return;
}

if (stat(pi->phys, &st) < 0) {
int code;

switch (errno) {
case EACCES:
code = HTTP_STATUS_FORBIDDEN;
break;
case ENOENT:
code = HTTP_STATUS_NOT_FOUND;
break;
default:
code = HTTP_STATUS_INTERNAL_SERVER_ERROR;
};

conn->send_error(conn, code, NULL);
st = pi->st;
if (!st) {
conn->send_error(conn, HTTP_STATUS_NOT_FOUND, NULL);
return;
}

if (!S_ISLNK(st.st_mode) && !S_ISREG(st.st_mode)) {
if (!S_ISREG(st->st_mode)) {
conn->send_error(conn, HTTP_STATUS_FORBIDDEN, NULL);
return;
}
Expand All @@ -339,19 +334,19 @@ void serve_file(struct uh_connection *conn)
return;
}

if (!file_range(conn, st.st_size, &start, &end, &ranged)) {
if (!file_range(conn, st->st_size, &start, &end, &ranged)) {
conn->send_head(conn, HTTP_STATUS_RANGE_NOT_SATISFIABLE, 0, NULL);
conn->send_header(conn, "Content-Range", "bytes */%" PRIu64, st.st_size);
conn->send_header(conn, "Content-Range", "bytes */%" PRIu64, st->st_size);
conn->send_header(conn, "Content-Type", "text/plain");
conn->send_header(conn, "Connection", "close");
conn->end_headers(conn);
conni->flags |= CONN_F_SEND_AND_CLOSE;
return;
}

if (!file_if_modified_since(conn, &st) ||
!file_if_range(conn, &st) ||
!file_if_unmodified_since(conn, &st)) {
if (!file_if_modified_since(conn, st) ||
!file_if_range(conn, st) ||
!file_if_unmodified_since(conn, st)) {
conn->end_response(conn);
return;
}
Expand All @@ -361,14 +356,14 @@ void serve_file(struct uh_connection *conn)
else
conn->send_head(conn, HTTP_STATUS_OK, end - start + 1, NULL);

file_response_ok_hdrs(conn, &st);
file_response_ok_hdrs(conn, st);

mime = file_mime_lookup(pi->phys);

conn->send_header(conn, "Content-Type", "%s", mime);

if (ranged)
conn->send_header(conn, "Content-Range", "bytes %" PRIu64 "-%" PRIu64 "/%" PRIu64, start, end, (uint64_t)st.st_size);
conn->send_header(conn, "Content-Range", "bytes %" PRIu64 "-%" PRIu64 "/%" PRIu64, start, end, (uint64_t)st->st_size);
else
file_if_gzip(conn, pi->phys, mime);

Expand All @@ -385,7 +380,7 @@ void serve_file(struct uh_connection *conn)
}

lseek(fd, start, SEEK_SET);
st.st_size -= start;
st->st_size -= start;

len = end - start + 1;

Expand Down
1 change: 1 addition & 0 deletions src/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct path_info {
const char *phys;
const char *name;
const char *info;
struct stat *st;
};

struct path_info *parse_path_info(struct uh_connection_internal *conn);
Expand Down

0 comments on commit 64c4888

Please sign in to comment.