Fossil SCM
Back out [5bb921dd0893a548]. It turns out that REQUEST_URI should have the query string appended. Make other changes to cgi.c to bring it into "compliance". "Compliance" is in quotes because rfc3875 does not define REQUEST_URI. That variable is really just by conveniention. But Apache and Nginx both append the query string, so we should too.
Commit
fd1c9b090ac53c372704488bbad94f4c5eda276704597169bca002f6e7873520
Parent
c9082b29711617c…
1 file changed
+19
-5
+19
-5
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -1174,10 +1174,14 @@ | ||
| 1174 | 1174 | ** |
| 1175 | 1175 | ** REQUEST_URI, PATH_INFO, and SCRIPT_NAME are related as follows: |
| 1176 | 1176 | ** |
| 1177 | 1177 | ** REQUEST_URI == SCRIPT_NAME + PATH_INFO |
| 1178 | 1178 | ** |
| 1179 | +** Or if QUERY_STRING is not empty: | |
| 1180 | +** | |
| 1181 | +** REQUEST_URI == SCRIPT_NAME + PATH_INFO + '?' + QUERY_STRING | |
| 1182 | +** | |
| 1179 | 1183 | ** Where "+" means concatenate. Fossil requires SCRIPT_NAME. If |
| 1180 | 1184 | ** REQUEST_URI is provided but PATH_INFO is not, then PATH_INFO is |
| 1181 | 1185 | ** computed from REQUEST_URI and SCRIPT_NAME. If PATH_INFO is provided |
| 1182 | 1186 | ** but REQUEST_URI is not, then compute REQUEST_URI from PATH_INFO and |
| 1183 | 1187 | ** SCRIPT_NAME. If neither REQUEST_URI nor PATH_INFO are provided, then |
| @@ -1193,12 +1197,12 @@ | ||
| 1193 | 1197 | ** PATH_INFO when it is empty. |
| 1194 | 1198 | ** |
| 1195 | 1199 | ** CGI Parameter quick reference: |
| 1196 | 1200 | ** |
| 1197 | 1201 | ** REQUEST_URI |
| 1198 | -** _____________|____________ | |
| 1199 | -** / \ | |
| 1202 | +** _____________|________________ | |
| 1203 | +** / \ | |
| 1200 | 1204 | ** https://www.fossil-scm.org/forum/info/12736b30c072551a?t=c |
| 1201 | 1205 | ** \________________/\____/\____________________/ \_/ |
| 1202 | 1206 | ** | | | | |
| 1203 | 1207 | ** HTTP_HOST | PATH_INFO QUERY_STRING |
| 1204 | 1208 | ** SCRIPT_NAME |
| @@ -1226,11 +1230,16 @@ | ||
| 1226 | 1230 | if( zScriptName==0 ){ |
| 1227 | 1231 | size_t nRU, nPI; |
| 1228 | 1232 | if( zRequestUri==0 || zPathInfo==0 ){ |
| 1229 | 1233 | malformed_request("missing SCRIPT_NAME"); /* Does not return */ |
| 1230 | 1234 | } |
| 1231 | - nRU = strlen(zRequestUri); | |
| 1235 | + z = strchr(zRequestUri,'?'); | |
| 1236 | + if( z ){ | |
| 1237 | + nRU = (int)(z - zRequestUri); | |
| 1238 | + }else{ | |
| 1239 | + nRU = strlen(zRequestUri); | |
| 1240 | + } | |
| 1232 | 1241 | nPI = strlen(zPathInfo); |
| 1233 | 1242 | if( nRU<nPI ){ |
| 1234 | 1243 | malformed_request("PATH_INFO is longer than REQUEST_URI"); |
| 1235 | 1244 | } |
| 1236 | 1245 | zScriptName = fossil_strndup(zRequestUri,(int)(nRU-nPI)); |
| @@ -1251,15 +1260,20 @@ | ||
| 1251 | 1260 | cgi_replace_parameter("PATH_INFO", zPathInfo); |
| 1252 | 1261 | } |
| 1253 | 1262 | #endif |
| 1254 | 1263 | if( zRequestUri==0 ){ |
| 1255 | 1264 | const char *z = zPathInfo; |
| 1265 | + const char *zQS = cgi_parameter("QUERY_STRING",0); | |
| 1256 | 1266 | if( zPathInfo==0 ){ |
| 1257 | 1267 | malformed_request("missing PATH_INFO and/or REQUEST_URI"); |
| 1258 | 1268 | } |
| 1259 | 1269 | if( z[0]=='/' ) z++; |
| 1260 | - zRequestUri = mprintf("%s/%s", zScriptName, z); | |
| 1270 | + if( zQS && zQS[0] ){ | |
| 1271 | + zRequestUri = mprintf("%s/%s?%s", zScriptName, z, zQS); | |
| 1272 | + }else{ | |
| 1273 | + zRequestUri = mprintf("%s/%s", zScriptName, z); | |
| 1274 | + } | |
| 1261 | 1275 | cgi_set_parameter("REQUEST_URI", zRequestUri); |
| 1262 | 1276 | } |
| 1263 | 1277 | if( zPathInfo==0 ){ |
| 1264 | 1278 | int i, j; |
| 1265 | 1279 | for(i=0; zRequestUri[i]==zScriptName[i] && zRequestUri[i]; i++){} |
| @@ -1866,14 +1880,14 @@ | ||
| 1866 | 1880 | cgi_setenv("REQUEST_METHOD",zToken); |
| 1867 | 1881 | zToken = extract_token(z, &z); |
| 1868 | 1882 | if( zToken==0 ){ |
| 1869 | 1883 | malformed_request("malformed URL in HTTP header"); |
| 1870 | 1884 | } |
| 1885 | + cgi_setenv("REQUEST_URI", zToken); | |
| 1871 | 1886 | cgi_setenv("SCRIPT_NAME", ""); |
| 1872 | 1887 | for(i=0; zToken[i] && zToken[i]!='?'; i++){} |
| 1873 | 1888 | if( zToken[i] ) zToken[i++] = 0; |
| 1874 | - cgi_setenv("REQUEST_URI", zToken); | |
| 1875 | 1889 | cgi_setenv("PATH_INFO", zToken); |
| 1876 | 1890 | cgi_setenv("QUERY_STRING", &zToken[i]); |
| 1877 | 1891 | if( zIpAddr==0 ){ |
| 1878 | 1892 | zIpAddr = cgi_remote_ip(fileno(g.httpIn)); |
| 1879 | 1893 | } |
| 1880 | 1894 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -1174,10 +1174,14 @@ | |
| 1174 | ** |
| 1175 | ** REQUEST_URI, PATH_INFO, and SCRIPT_NAME are related as follows: |
| 1176 | ** |
| 1177 | ** REQUEST_URI == SCRIPT_NAME + PATH_INFO |
| 1178 | ** |
| 1179 | ** Where "+" means concatenate. Fossil requires SCRIPT_NAME. If |
| 1180 | ** REQUEST_URI is provided but PATH_INFO is not, then PATH_INFO is |
| 1181 | ** computed from REQUEST_URI and SCRIPT_NAME. If PATH_INFO is provided |
| 1182 | ** but REQUEST_URI is not, then compute REQUEST_URI from PATH_INFO and |
| 1183 | ** SCRIPT_NAME. If neither REQUEST_URI nor PATH_INFO are provided, then |
| @@ -1193,12 +1197,12 @@ | |
| 1193 | ** PATH_INFO when it is empty. |
| 1194 | ** |
| 1195 | ** CGI Parameter quick reference: |
| 1196 | ** |
| 1197 | ** REQUEST_URI |
| 1198 | ** _____________|____________ |
| 1199 | ** / \ |
| 1200 | ** https://www.fossil-scm.org/forum/info/12736b30c072551a?t=c |
| 1201 | ** \________________/\____/\____________________/ \_/ |
| 1202 | ** | | | | |
| 1203 | ** HTTP_HOST | PATH_INFO QUERY_STRING |
| 1204 | ** SCRIPT_NAME |
| @@ -1226,11 +1230,16 @@ | |
| 1226 | if( zScriptName==0 ){ |
| 1227 | size_t nRU, nPI; |
| 1228 | if( zRequestUri==0 || zPathInfo==0 ){ |
| 1229 | malformed_request("missing SCRIPT_NAME"); /* Does not return */ |
| 1230 | } |
| 1231 | nRU = strlen(zRequestUri); |
| 1232 | nPI = strlen(zPathInfo); |
| 1233 | if( nRU<nPI ){ |
| 1234 | malformed_request("PATH_INFO is longer than REQUEST_URI"); |
| 1235 | } |
| 1236 | zScriptName = fossil_strndup(zRequestUri,(int)(nRU-nPI)); |
| @@ -1251,15 +1260,20 @@ | |
| 1251 | cgi_replace_parameter("PATH_INFO", zPathInfo); |
| 1252 | } |
| 1253 | #endif |
| 1254 | if( zRequestUri==0 ){ |
| 1255 | const char *z = zPathInfo; |
| 1256 | if( zPathInfo==0 ){ |
| 1257 | malformed_request("missing PATH_INFO and/or REQUEST_URI"); |
| 1258 | } |
| 1259 | if( z[0]=='/' ) z++; |
| 1260 | zRequestUri = mprintf("%s/%s", zScriptName, z); |
| 1261 | cgi_set_parameter("REQUEST_URI", zRequestUri); |
| 1262 | } |
| 1263 | if( zPathInfo==0 ){ |
| 1264 | int i, j; |
| 1265 | for(i=0; zRequestUri[i]==zScriptName[i] && zRequestUri[i]; i++){} |
| @@ -1866,14 +1880,14 @@ | |
| 1866 | cgi_setenv("REQUEST_METHOD",zToken); |
| 1867 | zToken = extract_token(z, &z); |
| 1868 | if( zToken==0 ){ |
| 1869 | malformed_request("malformed URL in HTTP header"); |
| 1870 | } |
| 1871 | cgi_setenv("SCRIPT_NAME", ""); |
| 1872 | for(i=0; zToken[i] && zToken[i]!='?'; i++){} |
| 1873 | if( zToken[i] ) zToken[i++] = 0; |
| 1874 | cgi_setenv("REQUEST_URI", zToken); |
| 1875 | cgi_setenv("PATH_INFO", zToken); |
| 1876 | cgi_setenv("QUERY_STRING", &zToken[i]); |
| 1877 | if( zIpAddr==0 ){ |
| 1878 | zIpAddr = cgi_remote_ip(fileno(g.httpIn)); |
| 1879 | } |
| 1880 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -1174,10 +1174,14 @@ | |
| 1174 | ** |
| 1175 | ** REQUEST_URI, PATH_INFO, and SCRIPT_NAME are related as follows: |
| 1176 | ** |
| 1177 | ** REQUEST_URI == SCRIPT_NAME + PATH_INFO |
| 1178 | ** |
| 1179 | ** Or if QUERY_STRING is not empty: |
| 1180 | ** |
| 1181 | ** REQUEST_URI == SCRIPT_NAME + PATH_INFO + '?' + QUERY_STRING |
| 1182 | ** |
| 1183 | ** Where "+" means concatenate. Fossil requires SCRIPT_NAME. If |
| 1184 | ** REQUEST_URI is provided but PATH_INFO is not, then PATH_INFO is |
| 1185 | ** computed from REQUEST_URI and SCRIPT_NAME. If PATH_INFO is provided |
| 1186 | ** but REQUEST_URI is not, then compute REQUEST_URI from PATH_INFO and |
| 1187 | ** SCRIPT_NAME. If neither REQUEST_URI nor PATH_INFO are provided, then |
| @@ -1193,12 +1197,12 @@ | |
| 1197 | ** PATH_INFO when it is empty. |
| 1198 | ** |
| 1199 | ** CGI Parameter quick reference: |
| 1200 | ** |
| 1201 | ** REQUEST_URI |
| 1202 | ** _____________|________________ |
| 1203 | ** / \ |
| 1204 | ** https://www.fossil-scm.org/forum/info/12736b30c072551a?t=c |
| 1205 | ** \________________/\____/\____________________/ \_/ |
| 1206 | ** | | | | |
| 1207 | ** HTTP_HOST | PATH_INFO QUERY_STRING |
| 1208 | ** SCRIPT_NAME |
| @@ -1226,11 +1230,16 @@ | |
| 1230 | if( zScriptName==0 ){ |
| 1231 | size_t nRU, nPI; |
| 1232 | if( zRequestUri==0 || zPathInfo==0 ){ |
| 1233 | malformed_request("missing SCRIPT_NAME"); /* Does not return */ |
| 1234 | } |
| 1235 | z = strchr(zRequestUri,'?'); |
| 1236 | if( z ){ |
| 1237 | nRU = (int)(z - zRequestUri); |
| 1238 | }else{ |
| 1239 | nRU = strlen(zRequestUri); |
| 1240 | } |
| 1241 | nPI = strlen(zPathInfo); |
| 1242 | if( nRU<nPI ){ |
| 1243 | malformed_request("PATH_INFO is longer than REQUEST_URI"); |
| 1244 | } |
| 1245 | zScriptName = fossil_strndup(zRequestUri,(int)(nRU-nPI)); |
| @@ -1251,15 +1260,20 @@ | |
| 1260 | cgi_replace_parameter("PATH_INFO", zPathInfo); |
| 1261 | } |
| 1262 | #endif |
| 1263 | if( zRequestUri==0 ){ |
| 1264 | const char *z = zPathInfo; |
| 1265 | const char *zQS = cgi_parameter("QUERY_STRING",0); |
| 1266 | if( zPathInfo==0 ){ |
| 1267 | malformed_request("missing PATH_INFO and/or REQUEST_URI"); |
| 1268 | } |
| 1269 | if( z[0]=='/' ) z++; |
| 1270 | if( zQS && zQS[0] ){ |
| 1271 | zRequestUri = mprintf("%s/%s?%s", zScriptName, z, zQS); |
| 1272 | }else{ |
| 1273 | zRequestUri = mprintf("%s/%s", zScriptName, z); |
| 1274 | } |
| 1275 | cgi_set_parameter("REQUEST_URI", zRequestUri); |
| 1276 | } |
| 1277 | if( zPathInfo==0 ){ |
| 1278 | int i, j; |
| 1279 | for(i=0; zRequestUri[i]==zScriptName[i] && zRequestUri[i]; i++){} |
| @@ -1866,14 +1880,14 @@ | |
| 1880 | cgi_setenv("REQUEST_METHOD",zToken); |
| 1881 | zToken = extract_token(z, &z); |
| 1882 | if( zToken==0 ){ |
| 1883 | malformed_request("malformed URL in HTTP header"); |
| 1884 | } |
| 1885 | cgi_setenv("REQUEST_URI", zToken); |
| 1886 | cgi_setenv("SCRIPT_NAME", ""); |
| 1887 | for(i=0; zToken[i] && zToken[i]!='?'; i++){} |
| 1888 | if( zToken[i] ) zToken[i++] = 0; |
| 1889 | cgi_setenv("PATH_INFO", zToken); |
| 1890 | cgi_setenv("QUERY_STRING", &zToken[i]); |
| 1891 | if( zIpAddr==0 ){ |
| 1892 | zIpAddr = cgi_remote_ip(fileno(g.httpIn)); |
| 1893 | } |
| 1894 |