Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | If the REPOSITORY argument to the "server" or "http" commands is a directory, then use the first element of PATH_INFO as the basename of a repository in that directory. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
9cd2c42e79a2fee98d0ca4932ad3e094 |
| User & Date: | drh 2010-01-31 20:29:04.000 |
References
|
2010-03-31
| ||
| 18:42 | Get chroot jails working correctly when a particular fossil repository is specified on the "http" command. This fixes a problem introduced by the multi-repository feature added by check-in [9cd2c42e79] on [2010-01-31]. check-in: 42ba7b97aa user: drh tags: trunk | |
Context
|
2010-02-01
| ||
| 06:45 | fix typo check-in: a61fe7b878 user: ron tags: trunk | |
|
2010-01-31
| ||
| 20:29 | If the REPOSITORY argument to the "server" or "http" commands is a directory, then use the first element of PATH_INFO as the basename of a repository in that directory. check-in: 9cd2c42e79 user: drh tags: trunk | |
| 17:44 | Run autosync before resolving the version name in the "update" command. In that way, if a branch is specified which has been extended by the sync, the latest version of that branch is extracted rather than the version that was latest prior to the sync. check-in: da48c10d66 user: drh tags: trunk | |
Changes
Changes to src/file.c.
| ︙ | ︙ | |||
99 100 101 102 103 104 105 |
** other than a directory.
*/
int file_isdir(const char *zFilename){
int rc;
if( zFilename ){
char *zFN = mprintf("%s", zFilename);
| | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
** other than a directory.
*/
int file_isdir(const char *zFilename){
int rc;
if( zFilename ){
char *zFN = mprintf("%s", zFilename);
file_simplify_name(zFN, -1);
rc = getStat(zFN);
free(zFN);
}else{
rc = getStat(0);
}
return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
}
|
| ︙ | ︙ | |||
227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
** * removing /./
** * removing /A/../
**
** Changes are made in-place. Return the new name length.
*/
int file_simplify_name(char *z, int n){
int i, j;
#ifdef __MINGW32__
for(i=0; i<n; i++){
if( z[i]=='\\' ) z[i] = '/';
}
#endif
while( n>1 && z[n-1]=='/' ){ n--; }
for(i=j=0; i<n; i++){
| > | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
** * removing /./
** * removing /A/../
**
** Changes are made in-place. Return the new name length.
*/
int file_simplify_name(char *z, int n){
int i, j;
if( n<0 ) n = strlen(z);
#ifdef __MINGW32__
for(i=0; i<n; i++){
if( z[i]=='\\' ) z[i] = '/';
}
#endif
while( n>1 && z[n-1]=='/' ){ n--; }
for(i=j=0; i<n; i++){
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
451 452 453 454 455 456 457 |
zSpacer = " ";
}
printf("\n");
}
}
/*
| | | 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 |
zSpacer = " ";
}
printf("\n");
}
}
/*
** COM -off- MAND: commands
**
** Usage: %fossil commands
** List all supported commands.
*/
void cmd_cmd_list(void){
int i, nCmd;
const char *aCmd[count(aCommand)];
|
| ︙ | ︙ | |||
539 540 541 542 543 544 545 |
}
}
putchar('\n');
}
/*
** Set the g.zBaseURL value to the full URL for the toplevel of
| | | 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 |
}
}
putchar('\n');
}
/*
** 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.
*/
void set_base_url(void){
int i;
const char *zHost = PD("HTTP_HOST","");
const char *zMode = PD("HTTPS","off");
const char *zCur = PD("SCRIPT_NAME","/");
|
| ︙ | ︙ | |||
569 570 571 572 573 574 575 |
void fossil_redirect_home(void){
cgi_redirectf("%s%s", g.zBaseURL, db_get("index-page", "/index"));
}
/*
** Preconditions:
**
| | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < | 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 |
void fossil_redirect_home(void){
cgi_redirectf("%s%s", g.zBaseURL, db_get("index-page", "/index"));
}
/*
** Preconditions:
**
** * Environment variables are set up according to the CGI standard.
**
** If the repository is known, it has already been opened. If unknown,
** then g.zRepositoryName holds the directory that contains the repository
** and the actual repository is taken from the first element of PATH_INFO.
**
** Process the webpage specified by the PATH_INFO or REQUEST_URI
** environment variable.
*/
static void process_one_web_page(void){
const char *zPathInfo;
char *zPath = NULL;
int idx;
int i;
/* If the repository has not been opened already, then find the
** repository based on the first element of PATH_INFO and open it.
*/
zPathInfo = P("PATH_INFO");
if( !g.repositoryOpen ){
char *zRepo;
const char *zOldScript = PD("SCRIPT_NAME", "");
char *zNewScript;
int j, k;
i = 1;
while( zPathInfo[i] && zPathInfo[i]!='/' ){ i++; }
zRepo = mprintf("%s%.*s.fossil",g.zRepositoryName,i,zPathInfo);
/* To avoid mischief, make sure the repository basename contains no
** characters other than alphanumerics, "-", and "_".
*/
for(j=strlen(g.zRepositoryName)+1, k=0; k<i-1; j++, k++){
if( !isalnum(zRepo[j]) && zRepo[j]!='-' ) zRepo[j] = '_';
}
if( file_size(zRepo)<1024 ){
@ <h1>Not Found</h1>
cgi_set_status(404, "not found");
cgi_reply();
return;
}
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);
}
/* Find the page that the user has requested, construct and deliver that
** page.
*/
set_base_url();
if( zPathInfo==0 || zPathInfo[0]==0
|| (zPathInfo[0]=='/' && zPathInfo[1]==0) ){
fossil_redirect_home();
}else{
zPath = mprintf("%s", zPathInfo);
}
|
| ︙ | ︙ | |||
705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 |
}
if( g.db==0 ){
cgi_panic("Unable to find or open the project repository");
}
cgi_init();
process_one_web_page();
}
/*
** undocumented format:
**
** fossil http REPOSITORY INFILE OUTFILE IPADDR
**
** The argv==6 form is used by the win32 server only.
**
** COMMAND: http
**
** Usage: %fossil http REPOSITORY
**
** Handle a single HTTP request appearing on stdin. The resulting webpage
** is delivered on stdout. This method is used to launch an HTTP request
** handler from inetd, for example. The argument is the name of the
** repository.
*/
void cmd_http(void){
const char *zIpAddr;
if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){
cgi_panic("no repository specified");
}
#if !defined(__MINGW32__)
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 |
}
if( g.db==0 ){
cgi_panic("Unable to find or open the project repository");
}
cgi_init();
process_one_web_page();
}
/*
** If g.argv[2] exists then it is either the name of a repository
** that will be used by a server, or else it is a directory that
** contains multiple repositories that can be served. If g.argv[2]
** is a directory, the repositories it contains must be named
** "*.fossil". If g.argv[2] does not exists, then we must be within
** a check-out and the repository to be served is the repository of
** that check-out.
**
** Open the respository to be served if it is known. If g.argv[2] is
** a directory full of repositories, then set g.zRepositoryName to
** the name of that directory and the specific repository will be
** opened later by process_one_web_page() based on the content of
** the PATH_INFO variable.
**
** If disallowDir is set, then the directory full of repositories method
** is disallowed.
*/
static void find_server_repository(int disallowDir){
if( g.argc<3 ){
db_must_be_within_tree();
}else if( !disallowDir && file_isdir(g.argv[2])==1 ){
g.zRepositoryName = mprintf("%s", g.argv[2]);
file_simplify_name(g.zRepositoryName, -1);
}else{
db_open_repository(g.argv[2]);
}
}
/*
** undocumented format:
**
** fossil http REPOSITORY INFILE OUTFILE IPADDR
**
** The argv==6 form is used by the win32 server only.
**
** COMMAND: http
**
** Usage: %fossil http REPOSITORY
**
** Handle a single HTTP request appearing on stdin. The resulting webpage
** is delivered on stdout. This method is used to launch an HTTP request
** handler from inetd, for example. The argument is the name of the
** repository.
**
** If REPOSITORY is a directory that contains one or more respositories
** with names of the form "*.fossil" then the first element of the URL
** pathname selects among the various repositories.
*/
void cmd_http(void){
const char *zIpAddr;
if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){
cgi_panic("no repository specified");
}
#if !defined(__MINGW32__)
|
| ︙ | ︙ | |||
757 758 759 760 761 762 763 |
g.httpOut = fopen(g.argv[4], "wb");
zIpAddr = g.argv[5];
}else{
g.httpIn = stdin;
g.httpOut = stdout;
zIpAddr = 0;
}
| < | < < < | 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 |
g.httpOut = fopen(g.argv[4], "wb");
zIpAddr = g.argv[5];
}else{
g.httpIn = stdin;
g.httpOut = stdout;
zIpAddr = 0;
}
find_server_repository(0);
cgi_handle_http_request(zIpAddr);
process_one_web_page();
}
/*
** COMMAND: test-http
** Works like the http command but gives setup permission to all users.
|
| ︙ | ︙ | |||
815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 |
** TCP port 8080, or on any other TCP port defined by the -P or
** --port option. The optional argument is the name of the repository.
** The repository argument may be omitted if the working directory is
** within an open checkout.
**
** The "ui" command automatically starts a web browser after initializing
** the web server.
*/
void cmd_webserver(void){
int iPort, mxPort;
const char *zPort;
char *zBrowser;
char *zBrowserCmd = 0;
#ifdef __MINGW32__
const char *zStopperFile; /* Name of file used to terminate server */
zStopperFile = find_option("stopper", 0, 1);
#endif
g.thTrace = find_option("th-trace", 0, 0)!=0;
if( g.thTrace ){
blob_zero(&g.thLog);
}
zPort = find_option("port", "P", 1);
if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
| > > > > > > | < < | < | | 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 |
** TCP port 8080, or on any other TCP port defined by the -P or
** --port option. The optional argument is the name of the repository.
** The repository argument may be omitted if the working directory is
** within an open checkout.
**
** The "ui" command automatically starts a web browser after initializing
** the web server.
**
** In the "server" command, the REPOSITORY can be a directory (aka folder)
** that contains one or more respositories with names ending in ".fossil".
** In that case, the first element of the URL is used to select among the
** various repositories.
*/
void cmd_webserver(void){
int iPort, mxPort;
const char *zPort;
char *zBrowser;
char *zBrowserCmd = 0;
int isUiCmd; /* True if command is "ui", not "server' */
#ifdef __MINGW32__
const char *zStopperFile; /* Name of file used to terminate server */
zStopperFile = find_option("stopper", 0, 1);
#endif
g.thTrace = find_option("th-trace", 0, 0)!=0;
if( g.thTrace ){
blob_zero(&g.thLog);
}
zPort = find_option("port", "P", 1);
if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
isUiCmd = g.argv[1][0]=='u';
find_server_repository(isUiCmd);
if( zPort ){
iPort = mxPort = atoi(zPort);
}else{
iPort = db_get_int("http-port", 8080);
mxPort = iPort+100;
}
#ifndef __MINGW32__
/* Unix implementation */
if( isUiCmd ){
#if !defined(__DARWIN__) && !defined(__APPLE__)
zBrowser = db_get("web-browser", 0);
if( zBrowser==0 ){
static char *azBrowserProg[] = { "xdg-open", "gnome-open", "firefox" };
int i;
zBrowser = "echo";
for(i=0; i<sizeof(azBrowserProg)/sizeof(azBrowserProg[0]); i++){
|
| ︙ | ︙ | |||
875 876 877 878 879 880 881 |
}
g.httpIn = stdin;
g.httpOut = stdout;
if( g.fHttpTrace || g.fSqlTrace ){
fprintf(stderr, "====== SERVER pid %d =======\n", getpid());
}
g.cgiPanic = 1;
| < < < | < | | 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 |
}
g.httpIn = stdin;
g.httpOut = stdout;
if( g.fHttpTrace || g.fSqlTrace ){
fprintf(stderr, "====== SERVER pid %d =======\n", getpid());
}
g.cgiPanic = 1;
find_server_repository(isUiCmd);
cgi_handle_http_request(0);
process_one_web_page();
#else
/* Win32 implementation */
if( isUiCmd ){
zBrowser = db_get("web-browser", "start");
zBrowserCmd = mprintf("%s http://127.0.0.1:%%d/", zBrowser);
}
db_close();
win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile);
#endif
}
|