Fossil SCM

Fix issue where the --baseurl was interacting with directory-full-of- repositories mode badly and producing incorrect URLs.

dg 2013-02-05 23:39 dg-misc
Commit fb80037e2652626f44f41b70453d48f746294b35
1 file changed +25 -16
+25 -16
--- src/main.c
+++ src/main.c
@@ -135,10 +135,11 @@
135135
int fSshTrace; /* Trace the SSH setup traffic */
136136
int fNoSync; /* Do not do an autosync ever. --nosync */
137137
char *zPath; /* Name of webpage being served */
138138
char *zExtra; /* Extra path information past the webpage name */
139139
char *zBaseURL; /* Full text of the URL being served */
140
+ const char *zAltBase; /* Alternative URL root. --baseurl */
140141
char *zTop; /* Parent directory of zPath */
141142
const char *zContentType; /* The content type of the input HTTP request */
142143
int iErrPriority; /* Priority of current error message */
143144
char *zErrMsg; /* Text of an error message */
144145
int sslNotAvailable; /* SSL is not available. Do not redirect to https: */
@@ -1116,24 +1117,30 @@
11161117
** Set the g.zBaseURL value to the full URL for the toplevel of
11171118
** the fossil tree. Set g.zTop to g.zBaseURL without the
11181119
** leading "http://" and the host and port.
11191120
**
11201121
** The g.zBaseURL is normally set based on HTTP_HOST and SCRIPT_NAME
1121
-** environment variables. However, if zAltBase is not NULL then it
1122
+** environment variables. However, if g.zAltBase is not NULL then it
11221123
** is the argument to the --baseurl option command-line option and
11231124
** g.zBaseURL and g.zTop is set from that instead.
1125
+**
1126
+** If g.zAltBase is set, then zRepoName may be a repository name (with a
1127
+** leading slash ** but without the .fossil) with is concatenated to the
1128
+** root.
11241129
*/
1125
-static void set_base_url(const char *zAltBase){
1130
+static void set_base_url(const char* zRepoName){
11261131
int i;
11271132
const char *zHost;
11281133
const char *zMode;
11291134
const char *zCur;
11301135
1131
- if( g.zBaseURL!=0 ) return;
1132
- if( zAltBase ){
1136
+ fossil_free(g.zBaseURL);
1137
+ if( g.zAltBase ){
11331138
int i, n, c;
1134
- g.zTop = g.zBaseURL = mprintf("%s", zAltBase);
1139
+ if (!zRepoName) zRepoName = "";
1140
+ if (zRepoName[0] == '/') zRepoName++;
1141
+ g.zTop = g.zBaseURL = mprintf("%s%s", g.zAltBase, zRepoName);
11351142
if( memcmp(g.zTop, "http://", 7)!=0 && memcmp(g.zTop,"https://",8)!=0 ){
11361143
fossil_fatal("argument to --baseurl should be 'http://host/path'"
11371144
" or 'https://host/path'");
11381145
}
11391146
for(i=n=0; (c = g.zTop[i])!=0; i++){
@@ -1273,10 +1280,11 @@
12731280
zPathInfo = PD("PATH_INFO","");
12741281
if( !g.repositoryOpen ){
12751282
char *zRepo, *zToFree;
12761283
const char *zOldScript = PD("SCRIPT_NAME", "");
12771284
char *zNewScript;
1285
+ char *zRepoName;
12781286
int j, k;
12791287
i64 szFile;
12801288
12811289
i = zPathInfo[0]!=0;
12821290
while( 1 ){
@@ -1349,10 +1357,14 @@
13491357
}
13501358
return;
13511359
}
13521360
break;
13531361
}
1362
+ /* Rebuild the base URL to add the repository name to the end. */
1363
+ zRepoName = mprintf("%.*s", i, zPathInfo);
1364
+ set_base_url(zRepoName);
1365
+ fossil_free(zRepoName);
13541366
zNewScript = mprintf("%s%.*s", zOldScript, i, zPathInfo);
13551367
cgi_replace_parameter("PATH_INFO", &zPathInfo[i+1]);
13561368
zPathInfo += i;
13571369
cgi_replace_parameter("SCRIPT_NAME", zNewScript);
13581370
db_open_repository(zRepo);
@@ -1362,18 +1374,19 @@
13621374
"# new PATH_INFO = [%s]\n"
13631375
"# new SCRIPT_NAME = [%s]\n",
13641376
zRepo, zPathInfo, zNewScript);
13651377
}
13661378
}
1379
+ else
1380
+ set_base_url(0);
13671381
13681382
/* Find the page that the user has requested, construct and deliver that
13691383
** page.
13701384
*/
13711385
if( g.zContentType && memcmp(g.zContentType, "application/x-fossil", 20)==0 ){
13721386
zPathInfo = "/xfer";
13731387
}
1374
- set_base_url(0);
13751388
if( zPathInfo==0 || zPathInfo[0]==0
13761389
|| (zPathInfo[0]=='/' && zPathInfo[1]==0) ){
13771390
#ifdef FOSSIL_ENABLE_JSON
13781391
if(g.json.isJsonMode){
13791392
json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
@@ -1740,11 +1753,10 @@
17401753
*/
17411754
void cmd_http(void){
17421755
const char *zIpAddr;
17431756
const char *zNotFound;
17441757
const char *zHost;
1745
- const char *zAltBase;
17461758
const char *zFileGlob;
17471759
17481760
/* The winhttp module passes the --files option as --files-urlenc with
17491761
** the argument being URL encoded, to avoid wildcard expansion in the
17501762
** shell. This option is for internal use and is undocumented.
@@ -1758,27 +1770,27 @@
17581770
zFileGlob = find_option("files",0,1);
17591771
}
17601772
zNotFound = find_option("notfound", 0, 1);
17611773
g.useLocalauth = find_option("localauth", 0, 0)!=0;
17621774
g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
1763
- zAltBase = find_option("baseurl", 0, 1);
1764
- if( zAltBase ) set_base_url(zAltBase);
1775
+ g.zAltBase = find_option("baseurl", 0, 1);
1776
+ set_base_url(0);
17651777
if( find_option("https",0,0)!=0 ) cgi_replace_parameter("HTTPS","on");
17661778
zHost = find_option("host", 0, 1);
17671779
if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
17681780
g.cgiOutput = 1;
1781
+ g.httpIn = stdin;
1782
+ g.httpOut = stdout;
17691783
if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){
17701784
fossil_fatal("no repository specified");
17711785
}
17721786
g.fullHttpReply = 1;
17731787
if( g.argc==6 ){
17741788
g.httpIn = fossil_fopen(g.argv[3], "rb");
17751789
g.httpOut = fossil_fopen(g.argv[4], "wb");
17761790
zIpAddr = g.argv[5];
17771791
}else{
1778
- g.httpIn = stdin;
1779
- g.httpOut = stdout;
17801792
zIpAddr = 0;
17811793
}
17821794
find_server_repository(0);
17831795
g.zRepositoryName = enter_chroot_jail(g.zRepositoryName);
17841796
cgi_handle_http_request(zIpAddr);
@@ -1888,11 +1900,10 @@
18881900
const char *zBrowser; /* Name of web browser program */
18891901
char *zBrowserCmd = 0; /* Command to launch the web browser */
18901902
int isUiCmd; /* True if command is "ui", not "server' */
18911903
const char *zNotFound; /* The --notfound option or NULL */
18921904
int flags = 0; /* Server flags */
1893
- const char *zAltBase; /* Argument to the --baseurl option */
18941905
const char *zFileGlob; /* Static content must match this */
18951906
18961907
#if defined(_WIN32)
18971908
const char *zStopperFile; /* Name of file used to terminate server */
18981909
zStopperFile = find_option("stopper", 0, 1);
@@ -1904,14 +1915,12 @@
19041915
if( g.thTrace ){
19051916
blob_zero(&g.thLog);
19061917
}
19071918
zPort = find_option("port", "P", 1);
19081919
zNotFound = find_option("notfound", 0, 1);
1909
- zAltBase = find_option("baseurl", 0, 1);
1910
- if( zAltBase ){
1911
- set_base_url(zAltBase);
1912
- }
1920
+ g.zAltBase = find_option("baseurl", 0, 1);
1921
+ set_base_url(0);
19131922
if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
19141923
isUiCmd = g.argv[1][0]=='u';
19151924
if( isUiCmd ){
19161925
flags |= HTTP_SERVER_LOCALHOST;
19171926
g.useLocalauth = 1;
19181927
--- src/main.c
+++ src/main.c
@@ -135,10 +135,11 @@
135 int fSshTrace; /* Trace the SSH setup traffic */
136 int fNoSync; /* Do not do an autosync ever. --nosync */
137 char *zPath; /* Name of webpage being served */
138 char *zExtra; /* Extra path information past the webpage name */
139 char *zBaseURL; /* Full text of the URL being served */
 
140 char *zTop; /* Parent directory of zPath */
141 const char *zContentType; /* The content type of the input HTTP request */
142 int iErrPriority; /* Priority of current error message */
143 char *zErrMsg; /* Text of an error message */
144 int sslNotAvailable; /* SSL is not available. Do not redirect to https: */
@@ -1116,24 +1117,30 @@
1116 ** Set the g.zBaseURL value to the full URL for the toplevel of
1117 ** the fossil tree. Set g.zTop to g.zBaseURL without the
1118 ** leading "http://" and the host and port.
1119 **
1120 ** The g.zBaseURL is normally set based on HTTP_HOST and SCRIPT_NAME
1121 ** environment variables. However, if zAltBase is not NULL then it
1122 ** is the argument to the --baseurl option command-line option and
1123 ** g.zBaseURL and g.zTop is set from that instead.
 
 
 
 
1124 */
1125 static void set_base_url(const char *zAltBase){
1126 int i;
1127 const char *zHost;
1128 const char *zMode;
1129 const char *zCur;
1130
1131 if( g.zBaseURL!=0 ) return;
1132 if( zAltBase ){
1133 int i, n, c;
1134 g.zTop = g.zBaseURL = mprintf("%s", zAltBase);
 
 
1135 if( memcmp(g.zTop, "http://", 7)!=0 && memcmp(g.zTop,"https://",8)!=0 ){
1136 fossil_fatal("argument to --baseurl should be 'http://host/path'"
1137 " or 'https://host/path'");
1138 }
1139 for(i=n=0; (c = g.zTop[i])!=0; i++){
@@ -1273,10 +1280,11 @@
1273 zPathInfo = PD("PATH_INFO","");
1274 if( !g.repositoryOpen ){
1275 char *zRepo, *zToFree;
1276 const char *zOldScript = PD("SCRIPT_NAME", "");
1277 char *zNewScript;
 
1278 int j, k;
1279 i64 szFile;
1280
1281 i = zPathInfo[0]!=0;
1282 while( 1 ){
@@ -1349,10 +1357,14 @@
1349 }
1350 return;
1351 }
1352 break;
1353 }
 
 
 
 
1354 zNewScript = mprintf("%s%.*s", zOldScript, i, zPathInfo);
1355 cgi_replace_parameter("PATH_INFO", &zPathInfo[i+1]);
1356 zPathInfo += i;
1357 cgi_replace_parameter("SCRIPT_NAME", zNewScript);
1358 db_open_repository(zRepo);
@@ -1362,18 +1374,19 @@
1362 "# new PATH_INFO = [%s]\n"
1363 "# new SCRIPT_NAME = [%s]\n",
1364 zRepo, zPathInfo, zNewScript);
1365 }
1366 }
 
 
1367
1368 /* Find the page that the user has requested, construct and deliver that
1369 ** page.
1370 */
1371 if( g.zContentType && memcmp(g.zContentType, "application/x-fossil", 20)==0 ){
1372 zPathInfo = "/xfer";
1373 }
1374 set_base_url(0);
1375 if( zPathInfo==0 || zPathInfo[0]==0
1376 || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){
1377 #ifdef FOSSIL_ENABLE_JSON
1378 if(g.json.isJsonMode){
1379 json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
@@ -1740,11 +1753,10 @@
1740 */
1741 void cmd_http(void){
1742 const char *zIpAddr;
1743 const char *zNotFound;
1744 const char *zHost;
1745 const char *zAltBase;
1746 const char *zFileGlob;
1747
1748 /* The winhttp module passes the --files option as --files-urlenc with
1749 ** the argument being URL encoded, to avoid wildcard expansion in the
1750 ** shell. This option is for internal use and is undocumented.
@@ -1758,27 +1770,27 @@
1758 zFileGlob = find_option("files",0,1);
1759 }
1760 zNotFound = find_option("notfound", 0, 1);
1761 g.useLocalauth = find_option("localauth", 0, 0)!=0;
1762 g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
1763 zAltBase = find_option("baseurl", 0, 1);
1764 if( zAltBase ) set_base_url(zAltBase);
1765 if( find_option("https",0,0)!=0 ) cgi_replace_parameter("HTTPS","on");
1766 zHost = find_option("host", 0, 1);
1767 if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
1768 g.cgiOutput = 1;
 
 
1769 if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){
1770 fossil_fatal("no repository specified");
1771 }
1772 g.fullHttpReply = 1;
1773 if( g.argc==6 ){
1774 g.httpIn = fossil_fopen(g.argv[3], "rb");
1775 g.httpOut = fossil_fopen(g.argv[4], "wb");
1776 zIpAddr = g.argv[5];
1777 }else{
1778 g.httpIn = stdin;
1779 g.httpOut = stdout;
1780 zIpAddr = 0;
1781 }
1782 find_server_repository(0);
1783 g.zRepositoryName = enter_chroot_jail(g.zRepositoryName);
1784 cgi_handle_http_request(zIpAddr);
@@ -1888,11 +1900,10 @@
1888 const char *zBrowser; /* Name of web browser program */
1889 char *zBrowserCmd = 0; /* Command to launch the web browser */
1890 int isUiCmd; /* True if command is "ui", not "server' */
1891 const char *zNotFound; /* The --notfound option or NULL */
1892 int flags = 0; /* Server flags */
1893 const char *zAltBase; /* Argument to the --baseurl option */
1894 const char *zFileGlob; /* Static content must match this */
1895
1896 #if defined(_WIN32)
1897 const char *zStopperFile; /* Name of file used to terminate server */
1898 zStopperFile = find_option("stopper", 0, 1);
@@ -1904,14 +1915,12 @@
1904 if( g.thTrace ){
1905 blob_zero(&g.thLog);
1906 }
1907 zPort = find_option("port", "P", 1);
1908 zNotFound = find_option("notfound", 0, 1);
1909 zAltBase = find_option("baseurl", 0, 1);
1910 if( zAltBase ){
1911 set_base_url(zAltBase);
1912 }
1913 if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
1914 isUiCmd = g.argv[1][0]=='u';
1915 if( isUiCmd ){
1916 flags |= HTTP_SERVER_LOCALHOST;
1917 g.useLocalauth = 1;
1918
--- src/main.c
+++ src/main.c
@@ -135,10 +135,11 @@
135 int fSshTrace; /* Trace the SSH setup traffic */
136 int fNoSync; /* Do not do an autosync ever. --nosync */
137 char *zPath; /* Name of webpage being served */
138 char *zExtra; /* Extra path information past the webpage name */
139 char *zBaseURL; /* Full text of the URL being served */
140 const char *zAltBase; /* Alternative URL root. --baseurl */
141 char *zTop; /* Parent directory of zPath */
142 const char *zContentType; /* The content type of the input HTTP request */
143 int iErrPriority; /* Priority of current error message */
144 char *zErrMsg; /* Text of an error message */
145 int sslNotAvailable; /* SSL is not available. Do not redirect to https: */
@@ -1116,24 +1117,30 @@
1117 ** Set the g.zBaseURL value to the full URL for the toplevel of
1118 ** the fossil tree. Set g.zTop to g.zBaseURL without the
1119 ** leading "http://" and the host and port.
1120 **
1121 ** The g.zBaseURL is normally set based on HTTP_HOST and SCRIPT_NAME
1122 ** environment variables. However, if g.zAltBase is not NULL then it
1123 ** is the argument to the --baseurl option command-line option and
1124 ** g.zBaseURL and g.zTop is set from that instead.
1125 **
1126 ** If g.zAltBase is set, then zRepoName may be a repository name (with a
1127 ** leading slash ** but without the .fossil) with is concatenated to the
1128 ** root.
1129 */
1130 static void set_base_url(const char* zRepoName){
1131 int i;
1132 const char *zHost;
1133 const char *zMode;
1134 const char *zCur;
1135
1136 fossil_free(g.zBaseURL);
1137 if( g.zAltBase ){
1138 int i, n, c;
1139 if (!zRepoName) zRepoName = "";
1140 if (zRepoName[0] == '/') zRepoName++;
1141 g.zTop = g.zBaseURL = mprintf("%s%s", g.zAltBase, zRepoName);
1142 if( memcmp(g.zTop, "http://", 7)!=0 && memcmp(g.zTop,"https://",8)!=0 ){
1143 fossil_fatal("argument to --baseurl should be 'http://host/path'"
1144 " or 'https://host/path'");
1145 }
1146 for(i=n=0; (c = g.zTop[i])!=0; i++){
@@ -1273,10 +1280,11 @@
1280 zPathInfo = PD("PATH_INFO","");
1281 if( !g.repositoryOpen ){
1282 char *zRepo, *zToFree;
1283 const char *zOldScript = PD("SCRIPT_NAME", "");
1284 char *zNewScript;
1285 char *zRepoName;
1286 int j, k;
1287 i64 szFile;
1288
1289 i = zPathInfo[0]!=0;
1290 while( 1 ){
@@ -1349,10 +1357,14 @@
1357 }
1358 return;
1359 }
1360 break;
1361 }
1362 /* Rebuild the base URL to add the repository name to the end. */
1363 zRepoName = mprintf("%.*s", i, zPathInfo);
1364 set_base_url(zRepoName);
1365 fossil_free(zRepoName);
1366 zNewScript = mprintf("%s%.*s", zOldScript, i, zPathInfo);
1367 cgi_replace_parameter("PATH_INFO", &zPathInfo[i+1]);
1368 zPathInfo += i;
1369 cgi_replace_parameter("SCRIPT_NAME", zNewScript);
1370 db_open_repository(zRepo);
@@ -1362,18 +1374,19 @@
1374 "# new PATH_INFO = [%s]\n"
1375 "# new SCRIPT_NAME = [%s]\n",
1376 zRepo, zPathInfo, zNewScript);
1377 }
1378 }
1379 else
1380 set_base_url(0);
1381
1382 /* Find the page that the user has requested, construct and deliver that
1383 ** page.
1384 */
1385 if( g.zContentType && memcmp(g.zContentType, "application/x-fossil", 20)==0 ){
1386 zPathInfo = "/xfer";
1387 }
 
1388 if( zPathInfo==0 || zPathInfo[0]==0
1389 || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){
1390 #ifdef FOSSIL_ENABLE_JSON
1391 if(g.json.isJsonMode){
1392 json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
@@ -1740,11 +1753,10 @@
1753 */
1754 void cmd_http(void){
1755 const char *zIpAddr;
1756 const char *zNotFound;
1757 const char *zHost;
 
1758 const char *zFileGlob;
1759
1760 /* The winhttp module passes the --files option as --files-urlenc with
1761 ** the argument being URL encoded, to avoid wildcard expansion in the
1762 ** shell. This option is for internal use and is undocumented.
@@ -1758,27 +1770,27 @@
1770 zFileGlob = find_option("files",0,1);
1771 }
1772 zNotFound = find_option("notfound", 0, 1);
1773 g.useLocalauth = find_option("localauth", 0, 0)!=0;
1774 g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
1775 g.zAltBase = find_option("baseurl", 0, 1);
1776 set_base_url(0);
1777 if( find_option("https",0,0)!=0 ) cgi_replace_parameter("HTTPS","on");
1778 zHost = find_option("host", 0, 1);
1779 if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
1780 g.cgiOutput = 1;
1781 g.httpIn = stdin;
1782 g.httpOut = stdout;
1783 if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){
1784 fossil_fatal("no repository specified");
1785 }
1786 g.fullHttpReply = 1;
1787 if( g.argc==6 ){
1788 g.httpIn = fossil_fopen(g.argv[3], "rb");
1789 g.httpOut = fossil_fopen(g.argv[4], "wb");
1790 zIpAddr = g.argv[5];
1791 }else{
 
 
1792 zIpAddr = 0;
1793 }
1794 find_server_repository(0);
1795 g.zRepositoryName = enter_chroot_jail(g.zRepositoryName);
1796 cgi_handle_http_request(zIpAddr);
@@ -1888,11 +1900,10 @@
1900 const char *zBrowser; /* Name of web browser program */
1901 char *zBrowserCmd = 0; /* Command to launch the web browser */
1902 int isUiCmd; /* True if command is "ui", not "server' */
1903 const char *zNotFound; /* The --notfound option or NULL */
1904 int flags = 0; /* Server flags */
 
1905 const char *zFileGlob; /* Static content must match this */
1906
1907 #if defined(_WIN32)
1908 const char *zStopperFile; /* Name of file used to terminate server */
1909 zStopperFile = find_option("stopper", 0, 1);
@@ -1904,14 +1915,12 @@
1915 if( g.thTrace ){
1916 blob_zero(&g.thLog);
1917 }
1918 zPort = find_option("port", "P", 1);
1919 zNotFound = find_option("notfound", 0, 1);
1920 g.zAltBase = find_option("baseurl", 0, 1);
1921 set_base_url(0);
 
 
1922 if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
1923 isUiCmd = g.argv[1][0]=='u';
1924 if( isUiCmd ){
1925 flags |= HTTP_SERVER_LOCALHOST;
1926 g.useLocalauth = 1;
1927

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button