summaryrefslogtreecommitdiffhomepage
path: root/contrib/package/uhttpd/src/uhttpd-utils.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2010-03-20 13:45:50 +0000
committerJo-Philipp Wich <jow@openwrt.org>2010-03-20 13:45:50 +0000
commit0f18174879e121e5c5a64de0e3cb88a9c78e2b37 (patch)
treeb6baf4fa1aacd49304075b00765e70c8ff0eb3fe /contrib/package/uhttpd/src/uhttpd-utils.c
parent66ffcefa5555b35fc2e71429d9be16ac6de82801 (diff)
uhttpd:
- rework url parsing and path resolving - handle more cgi quirks - change request dispatching - clean up cflags
Diffstat (limited to 'contrib/package/uhttpd/src/uhttpd-utils.c')
-rw-r--r--contrib/package/uhttpd/src/uhttpd-utils.c164
1 files changed, 67 insertions, 97 deletions
diff --git a/contrib/package/uhttpd/src/uhttpd-utils.c b/contrib/package/uhttpd/src/uhttpd-utils.c
index 89ee46ffd0..89a23686cd 100644
--- a/contrib/package/uhttpd/src/uhttpd-utils.c
+++ b/contrib/package/uhttpd/src/uhttpd-utils.c
@@ -344,9 +344,7 @@ struct uh_path_info * uh_path_lookup(struct client *cl, const char *url)
char *docroot = cl->server->conf->docroot;
char *pathptr = NULL;
- int skip = 0;
- int plen = 0;
-
+ int i = 0;
struct stat s;
@@ -355,129 +353,101 @@ struct uh_path_info * uh_path_lookup(struct client *cl, const char *url)
memset(buffer, 0, sizeof(buffer));
memset(&p, 0, sizeof(p));
- /* first separate query string from url */
+ /* copy docroot */
+ memcpy(buffer, docroot, sizeof(buffer));
+
+ /* separate query string from url */
if( (pathptr = strchr(url, '?')) != NULL )
{
p.query = pathptr[1] ? pathptr + 1 : NULL;
/* urldecode component w/o query */
if( pathptr > url )
- plen = uh_urldecode(
- buffer, sizeof(buffer), url,
- (int)(pathptr - url) - 1
+ uh_urldecode(
+ &buffer[strlen(docroot)],
+ sizeof(buffer) - strlen(docroot) - 1,
+ url, (int)(pathptr - url) - 1
);
- else
- plen = 0;
}
/* no query string, decode all of url */
else
{
- plen = uh_urldecode(
- buffer, sizeof(buffer), url, strlen(url)
+ uh_urldecode(
+ &buffer[strlen(docroot)],
+ sizeof(buffer) - strlen(docroot) - 1,
+ url, strlen(url)
);
}
- /* copy docroot */
- memcpy(path_phys, docroot, sizeof(path_phys));
-
- /* append normalized path, leave two bytes free
- * for trailing slash and terminating zero byte */
- plen = strlen(docroot) + uh_path_normalize(
- &path_phys[strlen(docroot)],
- sizeof(path_phys) - strlen(docroot) - 2,
- buffer, plen
- );
-
- /* copy result to info buffer */
- memcpy(path_info, path_phys, sizeof(path_info));
-
- /* find path */
- while( 1 )
+ /* create canon path */
+ for( i = strlen(buffer); i >= 0; i-- )
{
- /* test current path */
- if( !stat(path_phys, &p.stat) )
+ if( (buffer[i] == 0) || (buffer[i] == '/') )
{
- /* is a regular file */
- if( p.stat.st_mode & S_IFREG )
- {
- p.root = docroot;
- p.phys = path_phys;
- p.name = &path_phys[strlen(docroot)-1];
-
- /* find workdir */
- if( (pathptr = strrchr(path_phys, '/')) != NULL )
- {
- path_info[(int)(pathptr - path_phys) + 1] = 0;
- p.wdir = path_info;
- }
- else
- {
- p.wdir = docroot;
- }
+ memset(path_info, 0, sizeof(path_info));
+ memcpy(path_info, buffer, min(i + 1, sizeof(path_info) - 1));
- /* find path info */
- if( path_info[strlen(path_phys)] != 0 )
- {
- p.info = &path_info[strlen(path_phys)];
- }
+ if( realpath(path_info, path_phys) )
+ {
+ memset(path_info, 0, sizeof(path_info));
+ memcpy(path_info, &buffer[i],
+ min(strlen(buffer) - i, sizeof(path_info) - 1));
break;
}
+ }
+ }
- /* is a directory */
- else if( (p.stat.st_mode & S_IFDIR) && (skip < 1) )
- {
- /* ensure trailing slash */
- if( path_phys[plen-1] != '/' )
- path_phys[plen] = '/';
-
- /* try to locate index file */
- memset(buffer, 0, sizeof(buffer));
- memcpy(buffer, path_phys, sizeof(buffer));
- pathptr = &buffer[strlen(buffer)];
+ /* check whether found path is within docroot */
+ if( strncmp(path_phys, docroot, strlen(docroot)) ||
+ ((path_phys[strlen(docroot)] != 0) &&
+ (path_phys[strlen(docroot)] != '/'))
+ ) {
+ return NULL;
+ }
- for( skip = 0; skip < array_size(uh_index_files); skip++ )
- {
- strncat(buffer, uh_index_files[skip], sizeof(buffer));
-
- if( !stat(buffer, &s) && (s.st_mode & S_IFREG) )
- {
- memset(path_info, 0, sizeof(path_info));
- memcpy(path_info, path_phys, strlen(path_phys));
- memcpy(path_phys, buffer, sizeof(path_phys));
- memcpy(&p.stat, &s, sizeof(p.stat));
- p.wdir = path_info;
- break;
- }
-
- *pathptr = 0;
- }
+ /* test current path */
+ if( ! stat(path_phys, &p.stat) )
+ {
+ /* is a regular file */
+ if( p.stat.st_mode & S_IFREG )
+ {
+ p.root = docroot;
+ p.phys = path_phys;
+ p.name = &path_phys[strlen(docroot)];
+ p.info = path_info[0] ? path_info : NULL;
+ }
- p.root = docroot;
- p.phys = path_phys;
- p.name = &path_phys[strlen(docroot)-1];
+ /* is a directory */
+ else if( (p.stat.st_mode & S_IFDIR) && !strlen(path_info) )
+ {
+ /* ensure trailing slash */
+ if( path_phys[strlen(path_phys)-1] != '/' )
+ path_phys[strlen(path_phys)] = '/';
- break;
- }
+ /* try to locate index file */
+ memset(buffer, 0, sizeof(buffer));
+ memcpy(buffer, path_phys, sizeof(buffer));
+ pathptr = &buffer[strlen(buffer)];
- /* not found */
- else if( skip )
+ for( i = 0; i < array_size(uh_index_files); i++ )
{
- break;
- }
- }
+ strncat(buffer, uh_index_files[i], sizeof(buffer));
- else if( (strlen(path_phys) > strlen(docroot)) &&
- ((pathptr = strrchr(path_phys, '/')) != NULL)
- ) {
- *pathptr = 0;
- skip = 1;
- }
+ if( !stat(buffer, &s) && (s.st_mode & S_IFREG) )
+ {
+ memcpy(path_phys, buffer, sizeof(path_phys));
+ memcpy(&p.stat, &s, sizeof(p.stat));
+ break;
+ }
- else
- {
- break;
+ *pathptr = 0;
+ }
+
+ p.root = docroot;
+ p.phys = path_phys;
+ p.name = &path_phys[strlen(docroot)];
}
}