Fossil SCM

Add the "redirect:" option to CGI, to scan multiple repositories and redirect to the one that contains the requested artifact ID.

drh 2011-03-23 13:30 trunk
Commit ef6e364866d76ce9114fc4281d464f023ceeecbc
1 file changed +64 -3
+64 -3
--- src/main.c
+++ src/main.c
@@ -1024,11 +1024,13 @@
10241024
** the values of standard CGI environment variables.
10251025
*/
10261026
void cmd_cgi(void){
10271027
const char *zFile;
10281028
const char *zNotFound = 0;
1029
- Blob config, line, key, value;
1029
+ char **azRedirect = 0; /* List of repositories to redirect to */
1030
+ int nRedirect = 0; /* Number of entries in azRedirect */
1031
+ Blob config, line, key, value, value2;
10301032
if( g.argc==3 && fossil_strcmp(g.argv[1],"cgi")==0 ){
10311033
zFile = g.argv[2];
10321034
}else{
10331035
zFile = g.argv[1];
10341036
}
@@ -1078,17 +1080,76 @@
10781080
}
10791081
if( blob_eq(&key, "localauth") ){
10801082
g.useLocalauth = 1;
10811083
continue;
10821084
}
1085
+ if( blob_eq(&key, "redirect:") && blob_token(&line, &value)
1086
+ && blob_token(&line, &value2) ){
1087
+ nRedirect++;
1088
+ azRedirect = fossil_realloc(azRedirect, 2*nRedirect*sizeof(char*));
1089
+ azRedirect[nRedirect*2-2] = mprintf("%s", blob_str(&value));
1090
+ azRedirect[nRedirect*2-1] = mprintf("%s", blob_str(&value2));
1091
+ blob_reset(&value);
1092
+ blob_reset(&value2);
1093
+ continue;
1094
+ }
10831095
}
10841096
blob_reset(&config);
1085
- if( g.db==0 && g.zRepositoryName==0 ){
1097
+ if( g.db==0 && g.zRepositoryName==0 && nRedirect==0 ){
10861098
cgi_panic("Unable to find or open the project repository");
10871099
}
10881100
cgi_init();
1089
- process_one_web_page(zNotFound);
1101
+ if( nRedirect ){
1102
+ redirect_web_page(nRedirect, azRedirect);
1103
+ }else{
1104
+ process_one_web_page(zNotFound);
1105
+ }
1106
+}
1107
+
1108
+/* If the CGI program contains one or more lines of the form
1109
+**
1110
+** redirect: repository-filename http://hostname/path/%s
1111
+**
1112
+** then control jumps here. Search each repository for an artifact ID
1113
+** that matches the "name" CGI parameter and for the first match,
1114
+** redirect to the corresponding URL with the "name" CGI parameter
1115
+** inserted. Paint an error page if no match is found.
1116
+**
1117
+** If there is a line of the form:
1118
+**
1119
+** redirect: * URL
1120
+**
1121
+** Then a redirect is made to URL if no match is found. Otherwise a
1122
+** very primative error message is returned.
1123
+*/
1124
+void redirect_web_page(int nRedirect, char **azRedirect){
1125
+ int i; /* Loop counter */
1126
+ const char *zNotFound = 0; /* Not found URL */
1127
+ const char *zName = P("name");
1128
+ if( zName && validate16(zName, strlen(zName)) ){
1129
+ for(i=0; i<nRedirect; i++){
1130
+ if( strcmp(azRedirect[i*2],"*")==0 ){
1131
+ zNotFound = azRedirect[i*2+1];
1132
+ continue;
1133
+ }
1134
+ db_open_repository(azRedirect[i*2]);
1135
+ if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%s*'", zName) ){
1136
+ cgi_redirectf(azRedirect[i*2+1], zName);
1137
+ return;
1138
+ }
1139
+ db_close(1);
1140
+ }
1141
+ }
1142
+ if( zNotFound ){
1143
+ cgi_redirectf(zNotFound, zName);
1144
+ }else{
1145
+ printf(
1146
+ "Status: 200 Ok\r\n\r\n"
1147
+ "<p>No such object: %s</p>\n",
1148
+ zName
1149
+ );
1150
+ }
10901151
}
10911152
10921153
/*
10931154
** If g.argv[2] exists then it is either the name of a repository
10941155
** that will be used by a server, or else it is a directory that
10951156
--- src/main.c
+++ src/main.c
@@ -1024,11 +1024,13 @@
1024 ** the values of standard CGI environment variables.
1025 */
1026 void cmd_cgi(void){
1027 const char *zFile;
1028 const char *zNotFound = 0;
1029 Blob config, line, key, value;
 
 
1030 if( g.argc==3 && fossil_strcmp(g.argv[1],"cgi")==0 ){
1031 zFile = g.argv[2];
1032 }else{
1033 zFile = g.argv[1];
1034 }
@@ -1078,17 +1080,76 @@
1078 }
1079 if( blob_eq(&key, "localauth") ){
1080 g.useLocalauth = 1;
1081 continue;
1082 }
 
 
 
 
 
 
 
 
 
 
1083 }
1084 blob_reset(&config);
1085 if( g.db==0 && g.zRepositoryName==0 ){
1086 cgi_panic("Unable to find or open the project repository");
1087 }
1088 cgi_init();
1089 process_one_web_page(zNotFound);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1090 }
1091
1092 /*
1093 ** If g.argv[2] exists then it is either the name of a repository
1094 ** that will be used by a server, or else it is a directory that
1095
--- src/main.c
+++ src/main.c
@@ -1024,11 +1024,13 @@
1024 ** the values of standard CGI environment variables.
1025 */
1026 void cmd_cgi(void){
1027 const char *zFile;
1028 const char *zNotFound = 0;
1029 char **azRedirect = 0; /* List of repositories to redirect to */
1030 int nRedirect = 0; /* Number of entries in azRedirect */
1031 Blob config, line, key, value, value2;
1032 if( g.argc==3 && fossil_strcmp(g.argv[1],"cgi")==0 ){
1033 zFile = g.argv[2];
1034 }else{
1035 zFile = g.argv[1];
1036 }
@@ -1078,17 +1080,76 @@
1080 }
1081 if( blob_eq(&key, "localauth") ){
1082 g.useLocalauth = 1;
1083 continue;
1084 }
1085 if( blob_eq(&key, "redirect:") && blob_token(&line, &value)
1086 && blob_token(&line, &value2) ){
1087 nRedirect++;
1088 azRedirect = fossil_realloc(azRedirect, 2*nRedirect*sizeof(char*));
1089 azRedirect[nRedirect*2-2] = mprintf("%s", blob_str(&value));
1090 azRedirect[nRedirect*2-1] = mprintf("%s", blob_str(&value2));
1091 blob_reset(&value);
1092 blob_reset(&value2);
1093 continue;
1094 }
1095 }
1096 blob_reset(&config);
1097 if( g.db==0 && g.zRepositoryName==0 && nRedirect==0 ){
1098 cgi_panic("Unable to find or open the project repository");
1099 }
1100 cgi_init();
1101 if( nRedirect ){
1102 redirect_web_page(nRedirect, azRedirect);
1103 }else{
1104 process_one_web_page(zNotFound);
1105 }
1106 }
1107
1108 /* If the CGI program contains one or more lines of the form
1109 **
1110 ** redirect: repository-filename http://hostname/path/%s
1111 **
1112 ** then control jumps here. Search each repository for an artifact ID
1113 ** that matches the "name" CGI parameter and for the first match,
1114 ** redirect to the corresponding URL with the "name" CGI parameter
1115 ** inserted. Paint an error page if no match is found.
1116 **
1117 ** If there is a line of the form:
1118 **
1119 ** redirect: * URL
1120 **
1121 ** Then a redirect is made to URL if no match is found. Otherwise a
1122 ** very primative error message is returned.
1123 */
1124 void redirect_web_page(int nRedirect, char **azRedirect){
1125 int i; /* Loop counter */
1126 const char *zNotFound = 0; /* Not found URL */
1127 const char *zName = P("name");
1128 if( zName && validate16(zName, strlen(zName)) ){
1129 for(i=0; i<nRedirect; i++){
1130 if( strcmp(azRedirect[i*2],"*")==0 ){
1131 zNotFound = azRedirect[i*2+1];
1132 continue;
1133 }
1134 db_open_repository(azRedirect[i*2]);
1135 if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%s*'", zName) ){
1136 cgi_redirectf(azRedirect[i*2+1], zName);
1137 return;
1138 }
1139 db_close(1);
1140 }
1141 }
1142 if( zNotFound ){
1143 cgi_redirectf(zNotFound, zName);
1144 }else{
1145 printf(
1146 "Status: 200 Ok\r\n\r\n"
1147 "<p>No such object: %s</p>\n",
1148 zName
1149 );
1150 }
1151 }
1152
1153 /*
1154 ** If g.argv[2] exists then it is either the name of a repository
1155 ** that will be used by a server, or else it is a directory that
1156

Keyboard Shortcuts

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