Index: src/cgi.c ================================================================== --- src/cgi.c +++ src/cgi.c @@ -1174,10 +1174,14 @@ ** ** REQUEST_URI, PATH_INFO, and SCRIPT_NAME are related as follows: ** ** REQUEST_URI == SCRIPT_NAME + PATH_INFO ** +** Or if QUERY_STRING is not empty: +** +** REQUEST_URI == SCRIPT_NAME + PATH_INFO + '?' + QUERY_STRING +** ** Where "+" means concatenate. Fossil requires SCRIPT_NAME. If ** REQUEST_URI is provided but PATH_INFO is not, then PATH_INFO is ** computed from REQUEST_URI and SCRIPT_NAME. If PATH_INFO is provided ** but REQUEST_URI is not, then compute REQUEST_URI from PATH_INFO and ** SCRIPT_NAME. If neither REQUEST_URI nor PATH_INFO are provided, then @@ -1193,12 +1197,12 @@ ** PATH_INFO when it is empty. ** ** CGI Parameter quick reference: ** ** REQUEST_URI -** _____________|____________ -** / \ +** _____________|________________ +** / \ ** https://www.fossil-scm.org/forum/info/12736b30c072551a?t=c ** \________________/\____/\____________________/ \_/ ** | | | | ** HTTP_HOST | PATH_INFO QUERY_STRING ** SCRIPT_NAME @@ -1226,11 +1230,16 @@ if( zScriptName==0 ){ size_t nRU, nPI; if( zRequestUri==0 || zPathInfo==0 ){ malformed_request("missing SCRIPT_NAME"); /* Does not return */ } - nRU = strlen(zRequestUri); + z = strchr(zRequestUri,'?'); + if( z ){ + nRU = (int)(z - zRequestUri); + }else{ + nRU = strlen(zRequestUri); + } nPI = strlen(zPathInfo); if( nRU=nRoot+1 ); style_set_current_page("ext/%s", &zScript[nRoot+1]); + + /* Overriding of base href disabled as part of 'base-href-fix' branch + ** otherwise #fragment links may break under /ext */ + zMime = mimetype_from_name(zScript); if( zMime==0 ) zMime = "application/octet-stream"; if( !file_isexe(zScript, ExtFILE) ){ /* File is not executable. Must be a regular file. In that case, ** disallow extra path elements */ Index: src/fossil.page.wikiedit.js ================================================================== --- src/fossil.page.wikiedit.js +++ src/fossil.page.wikiedit.js @@ -883,11 +883,15 @@ btnSlot.parentNode.insertBefore( P.e.btnSave.parentNode, btnSlot ); btnSlot.parentNode.insertBefore( P.e.btnSaveClose.parentNode, btnSlot ); P.updateSaveButton(); } if(theTab===P.e.tabs.preview){ - P.baseHrefForWiki(); + + /* Overriding of base href disabled as part of 'base-href-fix' branch + ** To bring back the old behavior uncomment the following call + ** P.baseHrefForWiki(); + */ if(P.previewNeedsUpdate && P.e.cbAutoPreview.checked) P.preview(); }else if(theTab===P.e.tabs.diff){ /* Work around a weird bug where the page gets wider than the window when the diff tab is NOT in view and the current SBS diff widget is wider than the window. When @@ -903,11 +907,15 @@ P.tabs.addEventListener( /* Set up auto-refresh of the preview tab... */ 'before-switch-from', function(ev){ const theTab = ev.detail; if(theTab===P.e.tabs.preview){ - P.baseHrefRestore(); + + /* Overriding of base href disabled as part of 'base-href-fix' branch + ** To bring back the old behavior uncomment the following call + ** P.baseHrefRestore(); + */ }else if(theTab===P.e.tabs.diff){ /* See notes in the before-switch-to handler. */ D.addClass(P.e.diffTarget, 'hidden'); } } Index: src/info.c ================================================================== --- src/info.c +++ src/info.c @@ -986,13 +986,13 @@ } } style_header("Update of \"%h\"", pWiki->zWikiTitle); zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); zDate = db_text(0, "SELECT datetime(%.17g)", pWiki->rDate); - style_submenu_element("Raw", "artifact/%s", zUuid); - style_submenu_element("History", "whistory?name=%t", pWiki->zWikiTitle); - style_submenu_element("Page", "wiki?name=%t", pWiki->zWikiTitle); + style_submenu_element("Raw", "%R/artifact/%s", zUuid); + style_submenu_element("History", "%R/whistory?name=%t", pWiki->zWikiTitle); + style_submenu_element("Page", "%R/wiki?name=%t", pWiki->zWikiTitle); login_anonymous_available(); @
Overview
@

@ @ } tagid = wiki_tagid(pWiki->zWikiTitle); @@ -1432,10 +1432,11 @@ }else{ @
  • File if( bNeedBase ){ bNeedBase = 0; style_set_current_page("doc/%S/%s",zVers,zName); + style_set_base_href_suffix("doc/%S/%s",zVers,zName); } } objType |= OBJTYPE_CONTENT; @ %z(href("%R/finfo?name=%T&ci=%!S&m=%!S",zName,zVers,zUuid))\ @ %h(zName) @@ -2574,16 +2575,19 @@ if( isFile ){ if( isSymbolicCI ){ zHeader = mprintf("%s at %s", file_tail(zName), zCI); style_set_current_page("doc/%t/%T", zCI, zName); + style_set_base_href_suffix("doc/%t/%T", zCI, zName); }else if( zCIUuid && zCIUuid[0] ){ zHeader = mprintf("%s at [%S]", file_tail(zName), zCIUuid); style_set_current_page("doc/%S/%T", zCIUuid, zName); + style_set_base_href_suffix("doc/%S/%T", zCIUuid, zName); }else{ zHeader = mprintf("%s", file_tail(zName)); style_set_current_page("doc/tip/%T", zName); + style_set_base_href_suffix("doc/tip/%T", zName); } }else if( descOnly ){ zHeader = mprintf("Artifact Description [%S]", zUuid); }else{ zHeader = mprintf("Artifact [%S]", zUuid); Index: src/main.c ================================================================== --- src/main.c +++ src/main.c @@ -178,11 +178,13 @@ const char *zHttpCmd; /* External program to do HTTP requests */ int fNoSync; /* Do not do an autosync ever. --nosync */ int fIPv4; /* Use only IPv4, not IPv6. --ipv4 */ 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 */ + char *zBaseURL; /* Full URL for the toplevel of the fossil tree */ + const char *zRelReqURI; /* Relative Request URI (includes QUERY_STRING) + zBaseUrl/zRelReqURI == Full text of the URL being served */ char *zHttpsURL; /* zBaseURL translated to https: */ char *zTop; /* Parent directory of zPath */ int nExtraURL; /* Extra bytes added to SCRIPT_NAME */ const char *zExtRoot; /* Document root for the /ext sub-website */ const char *zContentType; /* The content type of the input HTTP request */ @@ -1352,10 +1354,12 @@ void set_base_url(const char *zAltBase){ int i; const char *zHost; const char *zMode; const char *zCur; + const char *zRU; /* REQUEST_URI */ + size_t nTop; /* length of g.zTop */ if( g.zBaseURL!=0 ) return; if( zAltBase ){ int i, n, c; g.zTop = g.zBaseURL = mprintf("%s", zAltBase); @@ -1411,10 +1415,16 @@ g.zHttpsURL = mprintf("https://%s%.*s", z, i, zCur); } fossil_free(z); } + zRU = PD("REQUEST_URI",""); + nTop = strlen( g.zTop ); + g.zRelReqURI = strncmp(zRU,g.zTop,nTop) ? "" : zRU+nTop; + if(g.zRelReqURI[0]=='/') g.zRelReqURI++; + g.zRelReqURI = fossil_strdup( g.zRelReqURI ); + /* Try to record the base URL as a CONFIG table entry with a name ** of the form: "baseurl:BASE". This keeps a record of how the ** the repository is used as a server, to help in answering questions ** like "where is the CGI script that references this repository?" ** Index: src/style.c ================================================================== --- src/style.c +++ src/style.c @@ -404,10 +404,34 @@ va_start(ap, zFormat); local_zCurrentPage = vmprintf(zFormat, ap); va_end(ap); } } + +/* Use this for the $base_href_suffix variable if it is not NULL. +** If it is NULL then use g.zRelReqURI +*/ +static const char *local_zBaseHrefSuffix = 0; + +/* +** Set the desired $base_href_suffix to something other than g.zRelReqURI +*/ +void style_set_base_href_suffix(const char *zFormat, ...){ + fossil_free( (char*)local_zBaseHrefSuffix ); + if( zFormat==0 ){ + local_zBaseHrefSuffix = 0; + }else{ + char *z; + va_list ap; + + va_start(ap, zFormat); + z = vmprintf(zFormat, ap); + va_end(ap); + local_zBaseHrefSuffix = escape_quotes( z ); + if( local_zBaseHrefSuffix!=z ) fossil_free( z ); + } +} /* ** Create a TH1 variable containing the URL for the stylesheet. ** ** The name of the new variable will be "stylesheet_url". @@ -647,20 +671,20 @@ ** prepended. */ static const char zDfltHeader[] = @ @ -@ @ +@ @ @ @ $<project_name>: $<title> @ @ @ -@ +@ ; /* ** Returns the default page header. */ @@ -769,10 +793,13 @@ Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL); Th_Store("home", g.zTop); Th_Store("index_page", db_get("index-page","/home")); if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath); Th_Store("current_page", local_zCurrentPage); + if( !local_zBaseHrefSuffix ) style_set_base_href_suffix("%s",g.zRelReqURI); + Th_Store("base_href_suffix", local_zBaseHrefSuffix); + Th_Store("webpagename", escape_quotes(g.zPath)); Th_Store("csrf_token", g.zCsrfToken); Th_Store("release_version", RELEASE_VERSION); Th_Store("manifest_version", MANIFEST_VERSION); Th_Store("manifest_date", MANIFEST_DATE); Th_Store("compiler_name", COMPILER_NAME); @@ -1383,10 +1410,11 @@ #if !defined(_WIN32) @ uid=%d(getuid()), gid=%d(getgid())
    #endif @ g.zBaseURL = %h(g.zBaseURL)
    @ g.zHttpsURL = %h(g.zHttpsURL)
    + @ g.zRelReqURI = %h(g.zRelReqURI)
    @ g.zTop = %h(g.zTop)
    @ g.zPath = %h(g.zPath)
    @ g.userUid = %d(g.userUid)
    @ g.zLogin = %h(g.zLogin)
    @ g.isHuman = %d(g.isHuman)
    Index: src/wiki.c ================================================================== --- src/wiki.c +++ src/wiki.c @@ -597,10 +597,15 @@ style_submenu_element("History", "%R/whistory?name=%T", zPageName); } } if( !isPopup ){ style_set_current_page("%T?name=%T", g.zPath, zPageName); + + /* Overriding of base href disabled as part of 'base-href-fix' branch + ** To bring back the old behavior uncomment the following call + ** style_set_base_href_suffix("%T?name=%T", g.zPath, zPageName); + */ wiki_page_header(WIKITYPE_UNKNOWN, zPageName, ""); if( !noSubmenu ){ wiki_standard_submenu(submenuFlags); } } @@ -1669,10 +1674,15 @@ manifest_destroy(pWiki); cgi_redirectf("wiki?name=%T", zPageName); return; } style_set_current_page("%T?name=%T", g.zPath, zPageName); + + /* Overriding of base href disabled as part of 'base-href-fix' branch + ** To bring back the old behavior uncomment the following call + ** style_set_base_href_suffix("%T?name=%T", g.zPath, zPageName); + */ style_set_current_feature("wiki"); style_header("Append Comment To: %s", zPageName); if( !goodCaptcha ){ @

    Error: Incorrect security code.

    }
  • Artifact ID:%z(href("%R/artifact/%!S",zUuid))%s(zUuid) @@ -1014,11 +1014,11 @@ if( pWiki->nParent>0 ){ int i; @
    Parent%s(pWiki->nParent==1?"":"s"): for(i=0; inParent; i++){ char *zParent = pWiki->azParent[i]; - @ %z(href("info/%!S",zParent))%s(zParent) + @ %z(href("%R/info/%!S",zParent))%s(zParent) @ %z(href("%R/wdiff?id=%!S&pid=%!S",zUuid,zParent))(diff) } @