use url decode while handle file

Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
main^2
Jianhui Zhao 2021-01-15 11:48:21 +08:00
parent 563ec0ff42
commit 971602f45f
3 changed files with 46 additions and 6 deletions

View File

@ -38,6 +38,7 @@
#include "uhttpd_internal.h"
#include "mimetypes.h"
#include "utils.h"
#include "file.h"
static const char *file_mktag(struct stat *s, char *buf, int len)
@ -256,7 +257,8 @@ void serve_file(struct uh_connection *conn)
struct uh_server_internal *srv = conni->srv;
const char *docroot = srv->docroot;
const char *index_page = srv->index_page;
static char fullpath[512];
static char fullpath[PATH_MAX];
int docroot_len;
size_t start, end;
const char *mime;
struct stat st;
@ -268,13 +270,16 @@ void serve_file(struct uh_connection *conn)
if (!index_page || !index_page[0])
index_page = "index.html";
strcpy(fullpath, docroot);
docroot_len = strlen(docroot);
memcpy(fullpath, docroot, docroot_len);
if (!strncmp(path.p, "/", path.len)) {
strcat(fullpath, "/");
strcat(fullpath, index_page);
} else {
strncat(fullpath, path.p, path.len);
fullpath[docroot_len] = '/';
strcpy(fullpath + docroot_len + 1, index_page);
} else if (urldecode(fullpath + docroot_len, PATH_MAX - docroot_len, path.p, path.len) < 0) {
conn->error(conn, HTTP_STATUS_NOT_FOUND, NULL);
return;
}
if (stat(fullpath, &st) < 0) {

View File

@ -28,6 +28,7 @@
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <ctype.h>
#include "utils.h"
@ -61,3 +62,30 @@ bool support_so_reuseport()
return ok;
}
int urldecode(char *buf, int blen, const char *src, int slen)
{
int i;
int len = 0;
#define hex(x) \
(((x) <= '9') ? ((x) - '0') : \
(((x) <= 'F') ? ((x) - 'A' + 10) : \
((x) - 'a' + 10)))
for (i = 0; (i < slen) && (len < blen); i++) {
if (src[i] != '%') {
buf[len++] = src[i];
continue;
}
if (i + 2 >= slen || !isxdigit(src[i + 1]) || !isxdigit(src[i + 2]))
return -2;
buf[len++] = (char)(16 * hex(src[i+1]) + hex(src[i+2]));
i += 2;
}
buf[len] = 0;
return (i == slen) ? len : -1;
}

View File

@ -42,4 +42,11 @@ const char *saddr2str(struct sockaddr *addr, char buf[], int len, int *port);
bool support_so_reuseport();
/*
** blen is the size of buf; slen is the length of src. The input-string need
** not be, and the output string will not be, null-terminated. Returns the
** length of the decoded string, -1 on buffer overflow, -2 on malformed string.
*/
int urldecode(char *buf, int blen, const char *src, int slen);
#endif