@@ -1457,54 +1457,80 @@ static void remove_double_dots(char *s) {
14571457}
14581458
14591459// Resolve requested file into `path` and return its fs->stat() result
1460- static int uri_to_path (struct mg_connection * c , struct mg_http_message * hm ,
1461- struct mg_http_serve_opts * opts , char * path ,
1462- size_t path_size ) {
1463- struct mg_fs * fs = opts -> fs == NULL ? & mg_fs_posix : opts -> fs ;
1460+ static int uri_to_path2 (struct mg_connection * c , struct mg_http_message * hm ,
1461+ struct mg_fs * fs , struct mg_str url , struct mg_str dir ,
1462+ char * path , size_t path_size ) {
14641463 int flags = 0 , tmp ;
14651464 // Append URI to the root_dir, and sanitize it
1466- size_t n = (size_t ) snprintf (path , path_size , "%s" , opts -> root_dir );
1465+ size_t n = (size_t ) snprintf (path , path_size , "%.* s" , ( int ) dir . len , dir . ptr );
14671466 if (n > path_size ) n = path_size ;
1468- mg_url_decode (hm -> uri .ptr , hm -> uri .len , path + n , path_size - n , 0 );
1469- path [path_size - 1 ] = '\0' ; // Double-check
1470- remove_double_dots (path );
1471- n = strlen (path );
1472- while (n > 0 && path [n - 1 ] == '/' ) path [-- n ] = 0 ; // Strip trailing slashes
1473- flags = fs -> stat (path , NULL , NULL ); // Does it exist?
1474- if (flags == 0 ) {
1475- mg_http_reply (c , 404 , "" , "Not found\n" ); // Does not exist, doh
1476- } else if (flags & MG_FS_DIR ) {
1477- if (((snprintf (path + n , path_size - n , "/index.html" ) > 0 &&
1478- (tmp = fs -> stat (path , NULL , NULL )) != 0 ) ||
1479- (snprintf (path + n , path_size - n , "/index.shtml" ) > 0 &&
1480- (tmp = fs -> stat (path , NULL , NULL )) != 0 ))) {
1481- flags = tmp ;
1482- } else {
1483- path [n ] = '\0' ; // Remove appended index file name
1467+ path [path_size - 1 ] = '\0' ;
1468+ if ((fs -> stat (path , NULL , NULL ) & MG_FS_DIR ) == 0 ) {
1469+ mg_http_reply (c , 400 , "" , "Invalid web root [%.*s]\n" , (int ) dir .len ,
1470+ dir .ptr );
1471+ } else {
1472+ if (n + 2 < path_size ) path [n ++ ] = '/' , path [n ] = '\0' ;
1473+ mg_url_decode (hm -> uri .ptr + url .len , hm -> uri .len - url .len , path + n ,
1474+ path_size - n , 0 );
1475+ path [path_size - 1 ] = '\0' ; // Double-check
1476+ remove_double_dots (path );
1477+ n = strlen (path );
1478+ LOG (LL_DEBUG , ("--> %s" , path ));
1479+ while (n > 0 && path [n - 1 ] == '/' ) path [-- n ] = 0 ; // Trim trailing slashes
1480+ flags = fs -> stat (path , NULL , NULL ); // Does it exist?
1481+ if (flags == 0 ) {
1482+ mg_http_reply (c , 404 , "" , "Not found\n" ); // Does not exist, doh
1483+ } else if (flags & MG_FS_DIR ) {
1484+ if (((snprintf (path + n , path_size - n , "/index.html" ) > 0 &&
1485+ (tmp = fs -> stat (path , NULL , NULL )) != 0 ) ||
1486+ (snprintf (path + n , path_size - n , "/index.shtml" ) > 0 &&
1487+ (tmp = fs -> stat (path , NULL , NULL )) != 0 ))) {
1488+ flags = tmp ;
1489+ } else {
1490+ path [n ] = '\0' ; // Remove appended index file name
1491+ }
14841492 }
14851493 }
14861494 return flags ;
14871495}
14881496
1497+ static int uri_to_path (struct mg_connection * c , struct mg_http_message * hm ,
1498+ struct mg_http_serve_opts * opts , char * path ,
1499+ size_t path_size ) {
1500+ struct mg_fs * fs = opts -> fs == NULL ? & mg_fs_posix : opts -> fs ;
1501+ struct mg_str k , v , s = mg_str (opts -> root_dir ), u = {0 , 0 }, p = {0 , 0 };
1502+ while (mg_commalist (& s , & k , & v )) {
1503+ if (v .len == 0 ) v = k , k = mg_str ("/" );
1504+ if (hm -> uri .len < k .len ) continue ;
1505+ if (mg_strcmp (k , mg_str_n (hm -> uri .ptr , k .len )) != 0 ) continue ;
1506+ u = k , p = v ;
1507+ }
1508+ return uri_to_path2 (c , hm , fs , u , p , path , path_size );
1509+ }
1510+
14891511void mg_http_serve_dir (struct mg_connection * c , struct mg_http_message * hm ,
14901512 struct mg_http_serve_opts * opts ) {
14911513 char path [MG_PATH_MAX ] = "" ;
14921514 const char * sp = opts -> ssi_pattern ;
1515+ #if 0
14931516 struct mg_fs * fs = opts -> fs == NULL ? & mg_fs_posix : opts -> fs ;
14941517 if ((fs -> stat (opts -> root_dir , NULL , NULL ) & MG_FS_DIR ) == 0 ) {
14951518 mg_http_reply (c , 400 , "" , "Invalid web root [%s]\n" , opts -> root_dir );
14961519 } else {
1497- int flags = uri_to_path ( c , hm , opts , path , sizeof ( path ));
1498- if ( flags == 0 ) return ;
1499- LOG ( LL_DEBUG , ( "%.*s %s %d" , ( int ) hm -> uri . len , hm -> uri . ptr , path , flags )) ;
1500- if ( flags & MG_FS_DIR ) {
1501- listdir ( c , hm , opts , path );
1502- } else if ( sp != NULL && mg_globmatch ( sp , strlen ( sp ), path , strlen ( path ))) {
1503- mg_http_serve_ssi ( c , opts -> root_dir , path );
1504- } else {
1505- mg_http_serve_file ( c , hm , path , opts );
1506- }
1520+ #endif
1521+ int flags = uri_to_path ( c , hm , opts , path , sizeof ( path )) ;
1522+ if ( flags == 0 ) return ;
1523+ LOG ( LL_DEBUG , ( "%.*s %s %d" , ( int ) hm -> uri . len , hm -> uri . ptr , path , flags ));
1524+ if ( flags & MG_FS_DIR ) {
1525+ listdir ( c , hm , opts , path );
1526+ } else if ( sp != NULL && mg_globmatch ( sp , strlen ( sp ) , path , strlen ( path ))) {
1527+ mg_http_serve_ssi ( c , opts -> root_dir , path );
1528+ } else {
1529+ mg_http_serve_file ( c , hm , path , opts );
15071530 }
1531+ #if 0
1532+ }
1533+ #endif
15081534}
15091535
15101536static bool mg_is_url_safe (int c ) {
0 commit comments