Fossil

Check-in [7063f8d4]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Candidate fix for --baseurl option when used with a directory of repositories. May need fine-tuning.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | baseUrlRepoDir
Files: files | file ages | folders
SHA1:7063f8d4cc40b369c57193a005a1f64dc85d841c
User & Date: mistachkin 2016-02-02 03:39:39
References
2016-03-17
19:32
Simpler alternative to [7063f8d4cc]. Skips initial directory portion of PATH_INFO when building the g.zBaseURL and g.zTop used with a directory of repositories. check-in: abb19e88 user: mistachkin tags: trunk
2016-02-02
04:18
Simpler alternative to [7063f8d4cc]. Skips initial directory portion of PATH_INFO when building the g.zBaseURL and g.zTop used with a directory of repositories. check-in: 7d5307b4 user: mistachkin tags: altBaseUrlRepoDir
Context
2016-02-02
03:39
Candidate fix for --baseurl option when used with a directory of repositories. May need fine-tuning. Closed-Leaf check-in: 7063f8d4 user: mistachkin tags: baseUrlRepoDir
2016-02-01
20:38
Add --https and --nossl options to the 'server' command. check-in: b8c7af5b user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/main.c.

   154    154     int fSshClient;         /* HTTP client flags for SSH client */
   155    155     char *zSshCmd;          /* SSH command string */
   156    156     int fNoSync;            /* Do not do an autosync ever.  --nosync */
   157    157     int fIPv4;              /* Use only IPv4, not IPv6. --ipv4 */
   158    158     char *zPath;            /* Name of webpage being served */
   159    159     char *zExtra;           /* Extra path information past the webpage name */
   160    160     char *zBaseURL;         /* Full text of the URL being served */
          161  +  char *zAltBaseURL;      /* Value of --baseurl option, if any */
   161    162     char *zHttpsURL;        /* zBaseURL translated to https: */
   162    163     char *zTop;             /* Parent directory of zPath */
   163    164     const char *zContentType;  /* The content type of the input HTTP request */
   164    165     int iErrPriority;       /* Priority of current error message */
   165    166     char *zErrMsg;          /* Text of an error message */
   166    167     int sslNotAvailable;    /* SSL is not available.  Do not redirect to https: */
   167    168     Blob cgiIn;             /* Input to an xfer www method */
................................................................................
  1394   1395     const char *zHost;
  1395   1396     const char *zMode;
  1396   1397     const char *zCur;
  1397   1398   
  1398   1399     if( g.zBaseURL!=0 ) return;
  1399   1400     if( zAltBase ){
  1400   1401       int i, n, c;
  1401         -    g.zTop = g.zBaseURL = mprintf("%s", zAltBase);
         1402  +    g.zTop = g.zBaseURL = g.zAltBaseURL = mprintf("%s", zAltBase);
  1402   1403       if( strncmp(g.zTop, "http://", 7)==0 ){
  1403   1404         /* it is HTTP, replace prefix with HTTPS. */
  1404   1405         g.zHttpsURL = mprintf("https://%s", &g.zTop[7]);
  1405   1406       }else if( strncmp(g.zTop, "https://", 8)==0 ){
  1406   1407         /* it is already HTTPS, use it. */
  1407   1408         g.zHttpsURL = mprintf("%s", g.zTop);
  1408   1409       }else{
................................................................................
  1591   1592   */
  1592   1593   static void process_one_web_page(
  1593   1594     const char *zNotFound,      /* Redirect here on a 404 if not NULL */
  1594   1595     Glob *pFileGlob,            /* Deliver static files matching */
  1595   1596     int allowRepoList           /* Send repo list for "/" URL */
  1596   1597   ){
  1597   1598     const char *zPathInfo;
         1599  +  const char *zFullPathInfo;
  1598   1600     char *zPath = NULL;
  1599   1601     int idx;
  1600   1602     int i;
  1601   1603   
  1602   1604     /* Handle universal query parameters */
  1603   1605     if( PB("utc") ){
  1604   1606       g.fTimeFormat = 1;
................................................................................
  1605   1607     }else if( PB("localtime") ){
  1606   1608       g.fTimeFormat = 2;
  1607   1609     }
  1608   1610   
  1609   1611     /* If the repository has not been opened already, then find the
  1610   1612     ** repository based on the first element of PATH_INFO and open it.
  1611   1613     */
  1612         -  zPathInfo = PD("PATH_INFO","");
         1614  +  zPathInfo = zFullPathInfo = PD("PATH_INFO","");
         1615  +  /* If zAltBaseURL is present (i.e. the --baseurl option was used),
         1616  +  ** make sure to skip over the portion of zTop that appears in the
         1617  +  ** value of zAltBaseURL; otherwise, it may be duplicated later.
         1618  +  */
         1619  +  if( g.zAltBaseURL && g.zTop ){
         1620  +    int nTop = strlen(g.zTop);
         1621  +    if ( strncmp(zPathInfo, g.zTop, nTop)==0 ){
         1622  +      zPathInfo += nTop;
         1623  +    }
         1624  +  }
  1613   1625     if( !g.repositoryOpen ){
  1614   1626       char *zRepo, *zToFree;
  1615   1627       const char *zOldScript = PD("SCRIPT_NAME", "");
  1616   1628       char *zNewScript;
  1617   1629       int j, k;
  1618   1630       i64 szFile;
  1619   1631   
  1620         -    i = zPathInfo[0]!=0;
         1632  +    i = zFullPathInfo[0]!=0;
  1621   1633       while( 1 ){
  1622         -      while( zPathInfo[i] && zPathInfo[i]!='/' ){ i++; }
  1623         -      zRepo = zToFree = mprintf("%s%.*s.fossil",g.zRepositoryName,i,zPathInfo);
         1634  +      while( zFullPathInfo[i] && zFullPathInfo[i]!='/' ){ i++; }
         1635  +      zRepo = zToFree = mprintf("%s%.*s.fossil",g.zRepositoryName,i,zFullPathInfo);
  1624   1636   
  1625   1637         /* To avoid mischief, make sure the repository basename contains no
  1626   1638         ** characters other than alphanumerics, "/", "_", "-", and ".", and
  1627   1639         ** that "-" never occurs immediately after a "/" and that "." is always
  1628   1640         ** surrounded by two alphanumerics.  Any character that does not
  1629   1641         ** satisfy these constraints is converted into "_".
  1630   1642         */
................................................................................
  1643   1655         }
  1644   1656         if( szFile==0 && sqlite3_strglob("*/.fossil",zRepo)!=0 ){
  1645   1657           if( zRepo[0]=='/' && zRepo[1]=='/' ){ zRepo++; j--; }
  1646   1658           szFile = file_size(zRepo);
  1647   1659           /* this should only be set from the --baseurl option, not CGI  */
  1648   1660           if( g.zBaseURL && g.zBaseURL[0]!=0 && g.zTop && g.zTop[0]!=0 &&
  1649   1661               file_isdir(g.zRepositoryName)==1 ){
  1650         -          g.zBaseURL = mprintf("%s%.*s", g.zBaseURL, i, zPathInfo);
  1651         -          g.zTop = mprintf("%s%.*s", g.zTop, i, zPathInfo);
         1662  +          if( zPathInfo==zFullPathInfo ){
         1663  +            g.zBaseURL = mprintf("%s%.*s", g.zBaseURL, i, zPathInfo);
         1664  +            g.zTop = mprintf("%s%.*s", g.zTop, i, zPathInfo);
         1665  +          }
  1652   1666           }
  1653   1667         }
  1654   1668         if( szFile<0 && i>0 ){
  1655   1669           const char *zMimetype;
  1656   1670           assert( fossil_strcmp(&zRepo[j], ".fossil")==0 );
  1657   1671           zRepo[j] = 0;
  1658         -        if( zPathInfo[i]=='/' && file_isdir(zRepo)==1 ){
         1672  +        if( zFullPathInfo[i]=='/' && file_isdir(zRepo)==1 ){
  1659   1673             fossil_free(zToFree);
  1660   1674             i++;
  1661   1675             continue;
  1662   1676           }
  1663   1677           if( pFileGlob!=0
  1664   1678            && file_isfile(zRepo)
  1665   1679            && glob_match(pFileGlob, zRepo)
................................................................................
  1675   1689             return;
  1676   1690           }
  1677   1691           zRepo[j] = '.';
  1678   1692         }
  1679   1693   
  1680   1694         if( szFile<1024 ){
  1681   1695           set_base_url(0);
  1682         -        if( strcmp(zPathInfo,"/")==0
         1696  +        if( strcmp(zFullPathInfo,"/")==0
  1683   1697                     && allowRepoList
  1684   1698                     && repo_list_page() ){
  1685   1699             /* Will return a list of repositories */
  1686   1700           }else if( zNotFound ){
  1687   1701             cgi_redirect(zNotFound);
  1688   1702           }else{
  1689   1703   #ifdef FOSSIL_ENABLE_JSON
................................................................................
  1696   1710             cgi_set_status(404, "not found");
  1697   1711             cgi_reply();
  1698   1712           }
  1699   1713           return;
  1700   1714         }
  1701   1715         break;
  1702   1716       }
  1703         -    zNewScript = mprintf("%s%.*s", zOldScript, i, zPathInfo);
  1704         -    cgi_replace_parameter("PATH_INFO", &zPathInfo[i+1]);
  1705         -    zPathInfo += i;
         1717  +    zNewScript = mprintf("%s%.*s", zOldScript, i, zFullPathInfo);
         1718  +    cgi_replace_parameter("PATH_INFO", &zFullPathInfo[i+1]);
         1719  +    zFullPathInfo += i;
  1706   1720       cgi_replace_parameter("SCRIPT_NAME", zNewScript);
  1707   1721       db_open_repository(zRepo);
  1708   1722       if( g.fHttpTrace ){
  1709   1723         fprintf(stderr,
  1710   1724             "# repository: [%s]\n"
  1711   1725             "# new PATH_INFO = [%s]\n"
  1712   1726             "# new SCRIPT_NAME = [%s]\n",
  1713         -          zRepo, zPathInfo, zNewScript);
         1727  +          zRepo, zFullPathInfo, zNewScript);
  1714   1728       }
  1715   1729     }
  1716   1730   
  1717   1731     /* Find the page that the user has requested, construct and deliver that
  1718   1732     ** page.
  1719   1733     */
  1720   1734     if( g.zContentType &&
  1721   1735         strncmp(g.zContentType, "application/x-fossil", 20)==0 ){
  1722         -    zPathInfo = "/xfer";
         1736  +    zFullPathInfo = "/xfer";
  1723   1737     }
  1724   1738     set_base_url(0);
  1725         -  if( zPathInfo==0 || zPathInfo[0]==0
  1726         -      || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){
         1739  +  if( zFullPathInfo==0 || zFullPathInfo[0]==0
         1740  +      || (zFullPathInfo[0]=='/' && zFullPathInfo[1]==0) ){
  1727   1741   #ifdef FOSSIL_ENABLE_JSON
  1728   1742       if(g.json.isJsonMode){
  1729   1743         json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
  1730   1744         fossil_exit(0);
  1731   1745       }
  1732   1746   #endif
  1733   1747       fossil_redirect_home() /*does not return*/;
  1734   1748     }else{
  1735         -    zPath = mprintf("%s", zPathInfo);
         1749  +    zPath = mprintf("%s", zFullPathInfo);
  1736   1750     }
  1737   1751   
  1738   1752     /* Make g.zPath point to the first element of the path.  Make
  1739   1753     ** g.zExtra point to everything past that point.
  1740   1754     */
  1741   1755     while(1){
  1742   1756       char *zAltRepo = 0;