Fossil SCM
Enhance the /ext page to search for "index.*" files if the pathname ends with "/" and is a directory name.
Commit
3ed3fa3dda9c6d6f51f45b5ebaa6410f4cb732deccefadfa2333670868a8847f
Parent
5590fb9e0f64194…
1 file changed
+39
-1
+39
-1
| --- src/extcgi.c | ||
| +++ src/extcgi.c | ||
| @@ -98,10 +98,43 @@ | ||
| 98 | 98 | break; |
| 99 | 99 | } |
| 100 | 100 | } |
| 101 | 101 | return zFailReason; |
| 102 | 102 | } |
| 103 | + | |
| 104 | +/* | |
| 105 | +** The *pzPath input is a pathname obtained from mprintf(). | |
| 106 | +** | |
| 107 | +** If | |
| 108 | +** | |
| 109 | +** (1) zPathname is the name of a directory, and | |
| 110 | +** (2) the name ends with "/", and | |
| 111 | +** (3) the directory contains a file named index.html, index.wiki, | |
| 112 | +** or index.md (in that order) | |
| 113 | +** | |
| 114 | +** then replace the input with a revised name that includes the index.* | |
| 115 | +** file and return non-zero (true). If any condition is not met, return | |
| 116 | +** zero and leave the input pathname unchanged. | |
| 117 | +*/ | |
| 118 | +static int isDirWithIndexFile(char **pzPath){ | |
| 119 | + static const char *azIndexNames[] = { | |
| 120 | + "index.html", "index.wiki", "index.md" | |
| 121 | + }; | |
| 122 | + int i; | |
| 123 | + if( file_isdir(*pzPath, ExtFILE)!=1 ) return 0; | |
| 124 | + if( sqlite3_strglob("*/", *pzPath)!=0 ) return 0; | |
| 125 | + for(i=0; i<sizeof(azIndexNames)/sizeof(azIndexNames[0]); i++){ | |
| 126 | + char *zNew = mprintf("%s%s", *pzPath, azIndexNames[i]); | |
| 127 | + if( file_isfile(zNew, ExtFILE) ){ | |
| 128 | + fossil_free(*pzPath); | |
| 129 | + *pzPath = zNew; | |
| 130 | + return 1; | |
| 131 | + } | |
| 132 | + fossil_free(zNew); | |
| 133 | + } | |
| 134 | + return 0; | |
| 135 | +} | |
| 103 | 136 | |
| 104 | 137 | /* |
| 105 | 138 | ** WEBPAGE: ext raw-content |
| 106 | 139 | ** |
| 107 | 140 | ** Relay an HTTP request to secondary CGI after first checking the |
| @@ -120,10 +153,15 @@ | ||
| 120 | 153 | ** The path after the /ext is the path to the CGI script or static file |
| 121 | 154 | ** relative to DIR. For security, this path may not contain characters |
| 122 | 155 | ** other than ASCII letters or digits, ".", "-", "/", and "_". If the |
| 123 | 156 | ** "." or "-" characters are present in the path then they may not follow |
| 124 | 157 | ** a "/". |
| 158 | +** | |
| 159 | +** If the path after /ext ends with "/" and is the name of a directory then | |
| 160 | +** that directory is searched for files named "index.html", "index.wiki", | |
| 161 | +** and "index.md" (in that order) and if found, those filenames are | |
| 162 | +** appended to the path. | |
| 125 | 163 | */ |
| 126 | 164 | void ext_page(void){ |
| 127 | 165 | const char *zName = P("name"); /* Path information after /ext */ |
| 128 | 166 | char *zPath = 0; /* Complete path from extroot */ |
| 129 | 167 | int nRoot; /* Number of bytes in the extroot name */ |
| @@ -164,11 +202,11 @@ | ||
| 164 | 202 | zFailReason = "extroot is not a directory"; |
| 165 | 203 | goto ext_not_found; |
| 166 | 204 | } |
| 167 | 205 | zPath = mprintf("%s/%s", g.zExtRoot, zName); |
| 168 | 206 | nRoot = (int)strlen(g.zExtRoot); |
| 169 | - if( file_isfile(zPath, ExtFILE) ){ | |
| 207 | + if( file_isfile(zPath, ExtFILE) || isDirWithIndexFile(&zPath) ){ | |
| 170 | 208 | nScript = (int)strlen(zPath); |
| 171 | 209 | zScript = zPath; |
| 172 | 210 | }else{ |
| 173 | 211 | for(i=nRoot+1; zPath[i]; i++){ |
| 174 | 212 | char c = zPath[i]; |
| 175 | 213 |
| --- src/extcgi.c | |
| +++ src/extcgi.c | |
| @@ -98,10 +98,43 @@ | |
| 98 | break; |
| 99 | } |
| 100 | } |
| 101 | return zFailReason; |
| 102 | } |
| 103 | |
| 104 | /* |
| 105 | ** WEBPAGE: ext raw-content |
| 106 | ** |
| 107 | ** Relay an HTTP request to secondary CGI after first checking the |
| @@ -120,10 +153,15 @@ | |
| 120 | ** The path after the /ext is the path to the CGI script or static file |
| 121 | ** relative to DIR. For security, this path may not contain characters |
| 122 | ** other than ASCII letters or digits, ".", "-", "/", and "_". If the |
| 123 | ** "." or "-" characters are present in the path then they may not follow |
| 124 | ** a "/". |
| 125 | */ |
| 126 | void ext_page(void){ |
| 127 | const char *zName = P("name"); /* Path information after /ext */ |
| 128 | char *zPath = 0; /* Complete path from extroot */ |
| 129 | int nRoot; /* Number of bytes in the extroot name */ |
| @@ -164,11 +202,11 @@ | |
| 164 | zFailReason = "extroot is not a directory"; |
| 165 | goto ext_not_found; |
| 166 | } |
| 167 | zPath = mprintf("%s/%s", g.zExtRoot, zName); |
| 168 | nRoot = (int)strlen(g.zExtRoot); |
| 169 | if( file_isfile(zPath, ExtFILE) ){ |
| 170 | nScript = (int)strlen(zPath); |
| 171 | zScript = zPath; |
| 172 | }else{ |
| 173 | for(i=nRoot+1; zPath[i]; i++){ |
| 174 | char c = zPath[i]; |
| 175 |
| --- src/extcgi.c | |
| +++ src/extcgi.c | |
| @@ -98,10 +98,43 @@ | |
| 98 | break; |
| 99 | } |
| 100 | } |
| 101 | return zFailReason; |
| 102 | } |
| 103 | |
| 104 | /* |
| 105 | ** The *pzPath input is a pathname obtained from mprintf(). |
| 106 | ** |
| 107 | ** If |
| 108 | ** |
| 109 | ** (1) zPathname is the name of a directory, and |
| 110 | ** (2) the name ends with "/", and |
| 111 | ** (3) the directory contains a file named index.html, index.wiki, |
| 112 | ** or index.md (in that order) |
| 113 | ** |
| 114 | ** then replace the input with a revised name that includes the index.* |
| 115 | ** file and return non-zero (true). If any condition is not met, return |
| 116 | ** zero and leave the input pathname unchanged. |
| 117 | */ |
| 118 | static int isDirWithIndexFile(char **pzPath){ |
| 119 | static const char *azIndexNames[] = { |
| 120 | "index.html", "index.wiki", "index.md" |
| 121 | }; |
| 122 | int i; |
| 123 | if( file_isdir(*pzPath, ExtFILE)!=1 ) return 0; |
| 124 | if( sqlite3_strglob("*/", *pzPath)!=0 ) return 0; |
| 125 | for(i=0; i<sizeof(azIndexNames)/sizeof(azIndexNames[0]); i++){ |
| 126 | char *zNew = mprintf("%s%s", *pzPath, azIndexNames[i]); |
| 127 | if( file_isfile(zNew, ExtFILE) ){ |
| 128 | fossil_free(*pzPath); |
| 129 | *pzPath = zNew; |
| 130 | return 1; |
| 131 | } |
| 132 | fossil_free(zNew); |
| 133 | } |
| 134 | return 0; |
| 135 | } |
| 136 | |
| 137 | /* |
| 138 | ** WEBPAGE: ext raw-content |
| 139 | ** |
| 140 | ** Relay an HTTP request to secondary CGI after first checking the |
| @@ -120,10 +153,15 @@ | |
| 153 | ** The path after the /ext is the path to the CGI script or static file |
| 154 | ** relative to DIR. For security, this path may not contain characters |
| 155 | ** other than ASCII letters or digits, ".", "-", "/", and "_". If the |
| 156 | ** "." or "-" characters are present in the path then they may not follow |
| 157 | ** a "/". |
| 158 | ** |
| 159 | ** If the path after /ext ends with "/" and is the name of a directory then |
| 160 | ** that directory is searched for files named "index.html", "index.wiki", |
| 161 | ** and "index.md" (in that order) and if found, those filenames are |
| 162 | ** appended to the path. |
| 163 | */ |
| 164 | void ext_page(void){ |
| 165 | const char *zName = P("name"); /* Path information after /ext */ |
| 166 | char *zPath = 0; /* Complete path from extroot */ |
| 167 | int nRoot; /* Number of bytes in the extroot name */ |
| @@ -164,11 +202,11 @@ | |
| 202 | zFailReason = "extroot is not a directory"; |
| 203 | goto ext_not_found; |
| 204 | } |
| 205 | zPath = mprintf("%s/%s", g.zExtRoot, zName); |
| 206 | nRoot = (int)strlen(g.zExtRoot); |
| 207 | if( file_isfile(zPath, ExtFILE) || isDirWithIndexFile(&zPath) ){ |
| 208 | nScript = (int)strlen(zPath); |
| 209 | zScript = zPath; |
| 210 | }else{ |
| 211 | for(i=nRoot+1; zPath[i]; i++){ |
| 212 | char c = zPath[i]; |
| 213 |