A while back I ran into an issue where baseurl wasn't being handled properly for the case where a single fossil server was handling multiple repositories. For example, with:
fossil server /home/fossil --baseurl https://cowlark.com/ ...then when $baseurl was being expanded in the templates, it would not have the repo name added to it; so if you tried to fetch 'https://cowlark.com/reponame/home', then all the URLs would be end up pointing at 'https://cowlark.com/timeline' rather than 'https://cowlark.com/reponame/timeline'. I've finally had time to have a look at this. Enclosed is a patch that at least pretends to fix it. What it does is change set_base_url() so that it takes a repo name as an optional parameter; zAltBase now becomes a global. process_one_web_page() then calls this to rebuild g.zTop and g.zBaseURL once it knows the name of the repository. I don't know the Fossil logic very well and so I'm sure I've introduced edge cases, but this does at least solve my immediate problem. You can see it in action at http://cowlark.com/calculon. (...there's also a fix to a crashing bug I found where cmd_http can call fatalError() before it sets up the output stream, which causes a seg fault, which I ran into while debugging this.) I hope it's useful to someone. -- ┌─── dg@cowlark.com ───── http://www.cowlark.com ───── │ "Of course, on a sufficiently small planet, 40 km/hr is, in fact, │ sufficient to punt the elastic spherical cow into low orbit." --- │ Brooks Moses on r.a.sf.c
--- src/main.c +++ src/main.c @@ -135,10 +135,11 @@ int fSshTrace; /* Trace the SSH setup traffic */ int fNoSync; /* Do not do an autosync ever. --nosync */ char *zPath; /* Name of webpage being served */ char *zExtra; /* Extra path information past the webpage name */ char *zBaseURL; /* Full text of the URL being served */ + const char *zAltBase; /* Alternative URL root. --baseurl */ char *zTop; /* Parent directory of zPath */ const char *zContentType; /* The content type of the input HTTP request */ int iErrPriority; /* Priority of current error message */ char *zErrMsg; /* Text of an error message */ int sslNotAvailable; /* SSL is not available. Do not redirect to https: */ @@ -1116,24 +1117,30 @@ ** Set the g.zBaseURL value to the full URL for the toplevel of ** the fossil tree. Set g.zTop to g.zBaseURL without the ** leading "http://" and the host and port. ** ** The g.zBaseURL is normally set based on HTTP_HOST and SCRIPT_NAME -** environment variables. However, if zAltBase is not NULL then it +** environment variables. However, if g.zAltBase is not NULL then it ** is the argument to the --baseurl option command-line option and ** g.zBaseURL and g.zTop is set from that instead. +** +** If g.zAltBase is set, then zRepoName may be a repository name (with a +** leading slash ** but without the .fossil) with is concatenated to the +** root. */ -static void set_base_url(const char *zAltBase){ +static void set_base_url(const char* zRepoName){ int i; const char *zHost; const char *zMode; const char *zCur; - if( g.zBaseURL!=0 ) return; - if( zAltBase ){ + fossil_free(g.zBaseURL); + if( g.zAltBase ){ int i, n, c; - g.zTop = g.zBaseURL = mprintf("%s", zAltBase); + if (!zRepoName) zRepoName = ""; + if (zRepoName[0] == '/') zRepoName++; + g.zTop = g.zBaseURL = mprintf("%s%s", g.zAltBase, zRepoName); if( memcmp(g.zTop, "http://", 7)!=0 && memcmp(g.zTop,"https://",8)!=0 ){ fossil_fatal("argument to --baseurl should be 'http://host/path'" " or 'https://host/path'"); } for(i=n=0; (c = g.zTop[i])!=0; i++){ @@ -1273,10 +1280,11 @@ zPathInfo = PD("PATH_INFO",""); if( !g.repositoryOpen ){ char *zRepo, *zToFree; const char *zOldScript = PD("SCRIPT_NAME", ""); char *zNewScript; + char *zRepoName; int j, k; i64 szFile; i = zPathInfo[0]!=0; while( 1 ){ @@ -1349,10 +1357,14 @@ } return; } break; } + /* Rebuild the base URL to add the repository name to the end. */ + zRepoName = mprintf("%.*s", i, zPathInfo); + set_base_url(zRepoName); + fossil_free(zRepoName); zNewScript = mprintf("%s%.*s", zOldScript, i, zPathInfo); cgi_replace_parameter("PATH_INFO", &zPathInfo[i+1]); zPathInfo += i; cgi_replace_parameter("SCRIPT_NAME", zNewScript); db_open_repository(zRepo); @@ -1362,18 +1374,19 @@ "# new PATH_INFO = [%s]\n" "# new SCRIPT_NAME = [%s]\n", zRepo, zPathInfo, zNewScript); } } + else + set_base_url(0); /* Find the page that the user has requested, construct and deliver that ** page. */ if( g.zContentType && memcmp(g.zContentType, "application/x-fossil", 20)==0 ){ zPathInfo = "/xfer"; } - set_base_url(0); if( zPathInfo==0 || zPathInfo[0]==0 || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){ #ifdef FOSSIL_ENABLE_JSON if(g.json.isJsonMode){ json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1); @@ -1740,11 +1753,10 @@ */ void cmd_http(void){ const char *zIpAddr; const char *zNotFound; const char *zHost; - const char *zAltBase; const char *zFileGlob; /* The winhttp module passes the --files option as --files-urlenc with ** the argument being URL encoded, to avoid wildcard expansion in the ** shell. This option is for internal use and is undocumented. @@ -1758,27 +1770,27 @@ zFileGlob = find_option("files",0,1); } zNotFound = find_option("notfound", 0, 1); g.useLocalauth = find_option("localauth", 0, 0)!=0; g.sslNotAvailable = find_option("nossl", 0, 0)!=0; - zAltBase = find_option("baseurl", 0, 1); - if( zAltBase ) set_base_url(zAltBase); + g.zAltBase = find_option("baseurl", 0, 1); + set_base_url(0); if( find_option("https",0,0)!=0 ) cgi_replace_parameter("HTTPS","on"); zHost = find_option("host", 0, 1); if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost); g.cgiOutput = 1; + g.httpIn = stdin; + g.httpOut = stdout; if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){ fossil_fatal("no repository specified"); } g.fullHttpReply = 1; if( g.argc==6 ){ g.httpIn = fossil_fopen(g.argv[3], "rb"); g.httpOut = fossil_fopen(g.argv[4], "wb"); zIpAddr = g.argv[5]; }else{ - g.httpIn = stdin; - g.httpOut = stdout; zIpAddr = 0; } find_server_repository(0); g.zRepositoryName = enter_chroot_jail(g.zRepositoryName); cgi_handle_http_request(zIpAddr); @@ -1888,11 +1900,10 @@ const char *zBrowser; /* Name of web browser program */ char *zBrowserCmd = 0; /* Command to launch the web browser */ int isUiCmd; /* True if command is "ui", not "server' */ const char *zNotFound; /* The --notfound option or NULL */ int flags = 0; /* Server flags */ - const char *zAltBase; /* Argument to the --baseurl option */ const char *zFileGlob; /* Static content must match this */ #if defined(_WIN32) const char *zStopperFile; /* Name of file used to terminate server */ zStopperFile = find_option("stopper", 0, 1); @@ -1904,14 +1915,12 @@ if( g.thTrace ){ blob_zero(&g.thLog); } zPort = find_option("port", "P", 1); zNotFound = find_option("notfound", 0, 1); - zAltBase = find_option("baseurl", 0, 1); - if( zAltBase ){ - set_base_url(zAltBase); - } + g.zAltBase = find_option("baseurl", 0, 1); + set_base_url(0); if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?"); isUiCmd = g.argv[1][0]=='u'; if( isUiCmd ){ flags |= HTTP_SERVER_LOCALHOST; g.useLocalauth = 1;
signature.asc
Description: OpenPGP digital signature
_______________________________________________ fossil-users mailing list [email protected] http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users

