Fossil SCM

Candidate fix for --baseurl option when used with a directory of repositories. May need fine-tuning.

mistachkin 2016-02-02 03:39 UTC trunk
Commit 7063f8d4cc40b369c57193a005a1f64dc85d841c
1 file changed +31 -17
+31 -17
--- src/main.c
+++ src/main.c
@@ -156,10 +156,11 @@
156156
int fNoSync; /* Do not do an autosync ever. --nosync */
157157
int fIPv4; /* Use only IPv4, not IPv6. --ipv4 */
158158
char *zPath; /* Name of webpage being served */
159159
char *zExtra; /* Extra path information past the webpage name */
160160
char *zBaseURL; /* Full text of the URL being served */
161
+ char *zAltBaseURL; /* Value of --baseurl option, if any */
161162
char *zHttpsURL; /* zBaseURL translated to https: */
162163
char *zTop; /* Parent directory of zPath */
163164
const char *zContentType; /* The content type of the input HTTP request */
164165
int iErrPriority; /* Priority of current error message */
165166
char *zErrMsg; /* Text of an error message */
@@ -1396,11 +1397,11 @@
13961397
const char *zCur;
13971398
13981399
if( g.zBaseURL!=0 ) return;
13991400
if( zAltBase ){
14001401
int i, n, c;
1401
- g.zTop = g.zBaseURL = mprintf("%s", zAltBase);
1402
+ g.zTop = g.zBaseURL = g.zAltBaseURL = mprintf("%s", zAltBase);
14021403
if( strncmp(g.zTop, "http://", 7)==0 ){
14031404
/* it is HTTP, replace prefix with HTTPS. */
14041405
g.zHttpsURL = mprintf("https://%s", &g.zTop[7]);
14051406
}else if( strncmp(g.zTop, "https://", 8)==0 ){
14061407
/* it is already HTTPS, use it. */
@@ -1593,10 +1594,11 @@
15931594
const char *zNotFound, /* Redirect here on a 404 if not NULL */
15941595
Glob *pFileGlob, /* Deliver static files matching */
15951596
int allowRepoList /* Send repo list for "/" URL */
15961597
){
15971598
const char *zPathInfo;
1599
+ const char *zFullPathInfo;
15981600
char *zPath = NULL;
15991601
int idx;
16001602
int i;
16011603
16021604
/* Handle universal query parameters */
@@ -1607,22 +1609,32 @@
16071609
}
16081610
16091611
/* If the repository has not been opened already, then find the
16101612
** repository based on the first element of PATH_INFO and open it.
16111613
*/
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
+ }
16131625
if( !g.repositoryOpen ){
16141626
char *zRepo, *zToFree;
16151627
const char *zOldScript = PD("SCRIPT_NAME", "");
16161628
char *zNewScript;
16171629
int j, k;
16181630
i64 szFile;
16191631
1620
- i = zPathInfo[0]!=0;
1632
+ i = zFullPathInfo[0]!=0;
16211633
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);
16241636
16251637
/* To avoid mischief, make sure the repository basename contains no
16261638
** characters other than alphanumerics, "/", "_", "-", and ".", and
16271639
** that "-" never occurs immediately after a "/" and that "." is always
16281640
** surrounded by two alphanumerics. Any character that does not
@@ -1645,19 +1657,21 @@
16451657
if( zRepo[0]=='/' && zRepo[1]=='/' ){ zRepo++; j--; }
16461658
szFile = file_size(zRepo);
16471659
/* this should only be set from the --baseurl option, not CGI */
16481660
if( g.zBaseURL && g.zBaseURL[0]!=0 && g.zTop && g.zTop[0]!=0 &&
16491661
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
+ }
16521666
}
16531667
}
16541668
if( szFile<0 && i>0 ){
16551669
const char *zMimetype;
16561670
assert( fossil_strcmp(&zRepo[j], ".fossil")==0 );
16571671
zRepo[j] = 0;
1658
- if( zPathInfo[i]=='/' && file_isdir(zRepo)==1 ){
1672
+ if( zFullPathInfo[i]=='/' && file_isdir(zRepo)==1 ){
16591673
fossil_free(zToFree);
16601674
i++;
16611675
continue;
16621676
}
16631677
if( pFileGlob!=0
@@ -1677,11 +1691,11 @@
16771691
zRepo[j] = '.';
16781692
}
16791693
16801694
if( szFile<1024 ){
16811695
set_base_url(0);
1682
- if( strcmp(zPathInfo,"/")==0
1696
+ if( strcmp(zFullPathInfo,"/")==0
16831697
&& allowRepoList
16841698
&& repo_list_page() ){
16851699
/* Will return a list of repositories */
16861700
}else if( zNotFound ){
16871701
cgi_redirect(zNotFound);
@@ -1698,43 +1712,43 @@
16981712
}
16991713
return;
17001714
}
17011715
break;
17021716
}
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;
17061720
cgi_replace_parameter("SCRIPT_NAME", zNewScript);
17071721
db_open_repository(zRepo);
17081722
if( g.fHttpTrace ){
17091723
fprintf(stderr,
17101724
"# repository: [%s]\n"
17111725
"# new PATH_INFO = [%s]\n"
17121726
"# new SCRIPT_NAME = [%s]\n",
1713
- zRepo, zPathInfo, zNewScript);
1727
+ zRepo, zFullPathInfo, zNewScript);
17141728
}
17151729
}
17161730
17171731
/* Find the page that the user has requested, construct and deliver that
17181732
** page.
17191733
*/
17201734
if( g.zContentType &&
17211735
strncmp(g.zContentType, "application/x-fossil", 20)==0 ){
1722
- zPathInfo = "/xfer";
1736
+ zFullPathInfo = "/xfer";
17231737
}
17241738
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) ){
17271741
#ifdef FOSSIL_ENABLE_JSON
17281742
if(g.json.isJsonMode){
17291743
json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
17301744
fossil_exit(0);
17311745
}
17321746
#endif
17331747
fossil_redirect_home() /*does not return*/;
17341748
}else{
1735
- zPath = mprintf("%s", zPathInfo);
1749
+ zPath = mprintf("%s", zFullPathInfo);
17361750
}
17371751
17381752
/* Make g.zPath point to the first element of the path. Make
17391753
** g.zExtra point to everything past that point.
17401754
*/
17411755
--- src/main.c
+++ src/main.c
@@ -156,10 +156,11 @@
156 int fNoSync; /* Do not do an autosync ever. --nosync */
157 int fIPv4; /* Use only IPv4, not IPv6. --ipv4 */
158 char *zPath; /* Name of webpage being served */
159 char *zExtra; /* Extra path information past the webpage name */
160 char *zBaseURL; /* Full text of the URL being served */
 
161 char *zHttpsURL; /* zBaseURL translated to https: */
162 char *zTop; /* Parent directory of zPath */
163 const char *zContentType; /* The content type of the input HTTP request */
164 int iErrPriority; /* Priority of current error message */
165 char *zErrMsg; /* Text of an error message */
@@ -1396,11 +1397,11 @@
1396 const char *zCur;
1397
1398 if( g.zBaseURL!=0 ) return;
1399 if( zAltBase ){
1400 int i, n, c;
1401 g.zTop = g.zBaseURL = mprintf("%s", zAltBase);
1402 if( strncmp(g.zTop, "http://", 7)==0 ){
1403 /* it is HTTP, replace prefix with HTTPS. */
1404 g.zHttpsURL = mprintf("https://%s", &g.zTop[7]);
1405 }else if( strncmp(g.zTop, "https://", 8)==0 ){
1406 /* it is already HTTPS, use it. */
@@ -1593,10 +1594,11 @@
1593 const char *zNotFound, /* Redirect here on a 404 if not NULL */
1594 Glob *pFileGlob, /* Deliver static files matching */
1595 int allowRepoList /* Send repo list for "/" URL */
1596 ){
1597 const char *zPathInfo;
 
1598 char *zPath = NULL;
1599 int idx;
1600 int i;
1601
1602 /* Handle universal query parameters */
@@ -1607,22 +1609,32 @@
1607 }
1608
1609 /* If the repository has not been opened already, then find the
1610 ** repository based on the first element of PATH_INFO and open it.
1611 */
1612 zPathInfo = PD("PATH_INFO","");
 
 
 
 
 
 
 
 
 
 
1613 if( !g.repositoryOpen ){
1614 char *zRepo, *zToFree;
1615 const char *zOldScript = PD("SCRIPT_NAME", "");
1616 char *zNewScript;
1617 int j, k;
1618 i64 szFile;
1619
1620 i = zPathInfo[0]!=0;
1621 while( 1 ){
1622 while( zPathInfo[i] && zPathInfo[i]!='/' ){ i++; }
1623 zRepo = zToFree = mprintf("%s%.*s.fossil",g.zRepositoryName,i,zPathInfo);
1624
1625 /* To avoid mischief, make sure the repository basename contains no
1626 ** characters other than alphanumerics, "/", "_", "-", and ".", and
1627 ** that "-" never occurs immediately after a "/" and that "." is always
1628 ** surrounded by two alphanumerics. Any character that does not
@@ -1645,19 +1657,21 @@
1645 if( zRepo[0]=='/' && zRepo[1]=='/' ){ zRepo++; j--; }
1646 szFile = file_size(zRepo);
1647 /* this should only be set from the --baseurl option, not CGI */
1648 if( g.zBaseURL && g.zBaseURL[0]!=0 && g.zTop && g.zTop[0]!=0 &&
1649 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);
 
 
1652 }
1653 }
1654 if( szFile<0 && i>0 ){
1655 const char *zMimetype;
1656 assert( fossil_strcmp(&zRepo[j], ".fossil")==0 );
1657 zRepo[j] = 0;
1658 if( zPathInfo[i]=='/' && file_isdir(zRepo)==1 ){
1659 fossil_free(zToFree);
1660 i++;
1661 continue;
1662 }
1663 if( pFileGlob!=0
@@ -1677,11 +1691,11 @@
1677 zRepo[j] = '.';
1678 }
1679
1680 if( szFile<1024 ){
1681 set_base_url(0);
1682 if( strcmp(zPathInfo,"/")==0
1683 && allowRepoList
1684 && repo_list_page() ){
1685 /* Will return a list of repositories */
1686 }else if( zNotFound ){
1687 cgi_redirect(zNotFound);
@@ -1698,43 +1712,43 @@
1698 }
1699 return;
1700 }
1701 break;
1702 }
1703 zNewScript = mprintf("%s%.*s", zOldScript, i, zPathInfo);
1704 cgi_replace_parameter("PATH_INFO", &zPathInfo[i+1]);
1705 zPathInfo += i;
1706 cgi_replace_parameter("SCRIPT_NAME", zNewScript);
1707 db_open_repository(zRepo);
1708 if( g.fHttpTrace ){
1709 fprintf(stderr,
1710 "# repository: [%s]\n"
1711 "# new PATH_INFO = [%s]\n"
1712 "# new SCRIPT_NAME = [%s]\n",
1713 zRepo, zPathInfo, zNewScript);
1714 }
1715 }
1716
1717 /* Find the page that the user has requested, construct and deliver that
1718 ** page.
1719 */
1720 if( g.zContentType &&
1721 strncmp(g.zContentType, "application/x-fossil", 20)==0 ){
1722 zPathInfo = "/xfer";
1723 }
1724 set_base_url(0);
1725 if( zPathInfo==0 || zPathInfo[0]==0
1726 || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){
1727 #ifdef FOSSIL_ENABLE_JSON
1728 if(g.json.isJsonMode){
1729 json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
1730 fossil_exit(0);
1731 }
1732 #endif
1733 fossil_redirect_home() /*does not return*/;
1734 }else{
1735 zPath = mprintf("%s", zPathInfo);
1736 }
1737
1738 /* Make g.zPath point to the first element of the path. Make
1739 ** g.zExtra point to everything past that point.
1740 */
1741
--- src/main.c
+++ src/main.c
@@ -156,10 +156,11 @@
156 int fNoSync; /* Do not do an autosync ever. --nosync */
157 int fIPv4; /* Use only IPv4, not IPv6. --ipv4 */
158 char *zPath; /* Name of webpage being served */
159 char *zExtra; /* Extra path information past the webpage name */
160 char *zBaseURL; /* Full text of the URL being served */
161 char *zAltBaseURL; /* Value of --baseurl option, if any */
162 char *zHttpsURL; /* zBaseURL translated to https: */
163 char *zTop; /* Parent directory of zPath */
164 const char *zContentType; /* The content type of the input HTTP request */
165 int iErrPriority; /* Priority of current error message */
166 char *zErrMsg; /* Text of an error message */
@@ -1396,11 +1397,11 @@
1397 const char *zCur;
1398
1399 if( g.zBaseURL!=0 ) return;
1400 if( zAltBase ){
1401 int i, n, c;
1402 g.zTop = g.zBaseURL = g.zAltBaseURL = mprintf("%s", zAltBase);
1403 if( strncmp(g.zTop, "http://", 7)==0 ){
1404 /* it is HTTP, replace prefix with HTTPS. */
1405 g.zHttpsURL = mprintf("https://%s", &g.zTop[7]);
1406 }else if( strncmp(g.zTop, "https://", 8)==0 ){
1407 /* it is already HTTPS, use it. */
@@ -1593,10 +1594,11 @@
1594 const char *zNotFound, /* Redirect here on a 404 if not NULL */
1595 Glob *pFileGlob, /* Deliver static files matching */
1596 int allowRepoList /* Send repo list for "/" URL */
1597 ){
1598 const char *zPathInfo;
1599 const char *zFullPathInfo;
1600 char *zPath = NULL;
1601 int idx;
1602 int i;
1603
1604 /* Handle universal query parameters */
@@ -1607,22 +1609,32 @@
1609 }
1610
1611 /* If the repository has not been opened already, then find the
1612 ** repository based on the first element of PATH_INFO and open it.
1613 */
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 }
1625 if( !g.repositoryOpen ){
1626 char *zRepo, *zToFree;
1627 const char *zOldScript = PD("SCRIPT_NAME", "");
1628 char *zNewScript;
1629 int j, k;
1630 i64 szFile;
1631
1632 i = zFullPathInfo[0]!=0;
1633 while( 1 ){
1634 while( zFullPathInfo[i] && zFullPathInfo[i]!='/' ){ i++; }
1635 zRepo = zToFree = mprintf("%s%.*s.fossil",g.zRepositoryName,i,zFullPathInfo);
1636
1637 /* To avoid mischief, make sure the repository basename contains no
1638 ** characters other than alphanumerics, "/", "_", "-", and ".", and
1639 ** that "-" never occurs immediately after a "/" and that "." is always
1640 ** surrounded by two alphanumerics. Any character that does not
@@ -1645,19 +1657,21 @@
1657 if( zRepo[0]=='/' && zRepo[1]=='/' ){ zRepo++; j--; }
1658 szFile = file_size(zRepo);
1659 /* this should only be set from the --baseurl option, not CGI */
1660 if( g.zBaseURL && g.zBaseURL[0]!=0 && g.zTop && g.zTop[0]!=0 &&
1661 file_isdir(g.zRepositoryName)==1 ){
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 }
1666 }
1667 }
1668 if( szFile<0 && i>0 ){
1669 const char *zMimetype;
1670 assert( fossil_strcmp(&zRepo[j], ".fossil")==0 );
1671 zRepo[j] = 0;
1672 if( zFullPathInfo[i]=='/' && file_isdir(zRepo)==1 ){
1673 fossil_free(zToFree);
1674 i++;
1675 continue;
1676 }
1677 if( pFileGlob!=0
@@ -1677,11 +1691,11 @@
1691 zRepo[j] = '.';
1692 }
1693
1694 if( szFile<1024 ){
1695 set_base_url(0);
1696 if( strcmp(zFullPathInfo,"/")==0
1697 && allowRepoList
1698 && repo_list_page() ){
1699 /* Will return a list of repositories */
1700 }else if( zNotFound ){
1701 cgi_redirect(zNotFound);
@@ -1698,43 +1712,43 @@
1712 }
1713 return;
1714 }
1715 break;
1716 }
1717 zNewScript = mprintf("%s%.*s", zOldScript, i, zFullPathInfo);
1718 cgi_replace_parameter("PATH_INFO", &zFullPathInfo[i+1]);
1719 zFullPathInfo += i;
1720 cgi_replace_parameter("SCRIPT_NAME", zNewScript);
1721 db_open_repository(zRepo);
1722 if( g.fHttpTrace ){
1723 fprintf(stderr,
1724 "# repository: [%s]\n"
1725 "# new PATH_INFO = [%s]\n"
1726 "# new SCRIPT_NAME = [%s]\n",
1727 zRepo, zFullPathInfo, zNewScript);
1728 }
1729 }
1730
1731 /* Find the page that the user has requested, construct and deliver that
1732 ** page.
1733 */
1734 if( g.zContentType &&
1735 strncmp(g.zContentType, "application/x-fossil", 20)==0 ){
1736 zFullPathInfo = "/xfer";
1737 }
1738 set_base_url(0);
1739 if( zFullPathInfo==0 || zFullPathInfo[0]==0
1740 || (zFullPathInfo[0]=='/' && zFullPathInfo[1]==0) ){
1741 #ifdef FOSSIL_ENABLE_JSON
1742 if(g.json.isJsonMode){
1743 json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
1744 fossil_exit(0);
1745 }
1746 #endif
1747 fossil_redirect_home() /*does not return*/;
1748 }else{
1749 zPath = mprintf("%s", zFullPathInfo);
1750 }
1751
1752 /* Make g.zPath point to the first element of the path. Make
1753 ** g.zExtra point to everything past that point.
1754 */
1755

Keyboard Shortcuts

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