Fossil SCM
Change unconditional CGI redirects to be 301 Moved Permanently.
Commit
33c1cfde9c6e8d5f4b3b91720264c75b58ec9059e8de5f2ed167743412fda897
Parent
271a6bd31d5087f…
2 files changed
+3
+20
-4
+3
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -637,10 +637,13 @@ | ||
| 637 | 637 | cgi_set_status(iStat, zStat); |
| 638 | 638 | free(zLocation); |
| 639 | 639 | cgi_reply(); |
| 640 | 640 | fossil_exit(0); |
| 641 | 641 | } |
| 642 | +NORETURN void cgi_redirect_perm(const char *zURL){ | |
| 643 | + cgi_redirect_with_status(zURL, 301, "Moved Permanently"); | |
| 644 | +} | |
| 642 | 645 | NORETURN void cgi_redirect(const char *zURL){ |
| 643 | 646 | cgi_redirect_with_status(zURL, 302, "Moved Temporarily"); |
| 644 | 647 | } |
| 645 | 648 | NORETURN void cgi_redirect_with_method(const char *zURL){ |
| 646 | 649 | cgi_redirect_with_status(zURL, 307, "Temporary Redirect"); |
| 647 | 650 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -637,10 +637,13 @@ | |
| 637 | cgi_set_status(iStat, zStat); |
| 638 | free(zLocation); |
| 639 | cgi_reply(); |
| 640 | fossil_exit(0); |
| 641 | } |
| 642 | NORETURN void cgi_redirect(const char *zURL){ |
| 643 | cgi_redirect_with_status(zURL, 302, "Moved Temporarily"); |
| 644 | } |
| 645 | NORETURN void cgi_redirect_with_method(const char *zURL){ |
| 646 | cgi_redirect_with_status(zURL, 307, "Temporary Redirect"); |
| 647 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -637,10 +637,13 @@ | |
| 637 | cgi_set_status(iStat, zStat); |
| 638 | free(zLocation); |
| 639 | cgi_reply(); |
| 640 | fossil_exit(0); |
| 641 | } |
| 642 | NORETURN void cgi_redirect_perm(const char *zURL){ |
| 643 | cgi_redirect_with_status(zURL, 301, "Moved Permanently"); |
| 644 | } |
| 645 | NORETURN void cgi_redirect(const char *zURL){ |
| 646 | cgi_redirect_with_status(zURL, 302, "Moved Temporarily"); |
| 647 | } |
| 648 | NORETURN void cgi_redirect_with_method(const char *zURL){ |
| 649 | cgi_redirect_with_status(zURL, 307, "Temporary Redirect"); |
| 650 |
+20
-4
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -2053,11 +2053,12 @@ | ||
| 2053 | 2053 | */ |
| 2054 | 2054 | set_base_url(0); |
| 2055 | 2055 | if( fossil_redirect_to_https_if_needed(2) ) return; |
| 2056 | 2056 | if( zPathInfo==0 || zPathInfo[0]==0 |
| 2057 | 2057 | || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){ |
| 2058 | - /* Second special case: If the PATH_INFO is blank, issue a redirect: | |
| 2058 | + /* Second special case: If the PATH_INFO is blank, issue a | |
| 2059 | + ** temporary 302 redirect: | |
| 2059 | 2060 | ** (1) to "/ckout" if g.useLocalauth and g.localOpen are both set. |
| 2060 | 2061 | ** (2) to the home page identified by the "index-page" setting |
| 2061 | 2062 | ** in the repository CONFIG table |
| 2062 | 2063 | ** (3) to "/index" if there no "index-page" setting in CONFIG |
| 2063 | 2064 | */ |
| @@ -2267,10 +2268,21 @@ | ||
| 2267 | 2268 | ** |
| 2268 | 2269 | ** #!/usr/bin/fossil |
| 2269 | 2270 | ** redirect: * https://fossil-scm.org/home |
| 2270 | 2271 | ** |
| 2271 | 2272 | ** Thus requests to the .com website redirect to the .org website. |
| 2273 | +** This form uses a 301 Permanent redirect. | |
| 2274 | +** | |
| 2275 | +** On a "*" redirect, the PATH_INFO and QUERY_STRING of the query | |
| 2276 | +** that provoked the redirect are appended to the target. So, for | |
| 2277 | +** example, if the input URL for the redirect above were | |
| 2278 | +** "http://www.fossil.com/index.html/timeline?c=20250404", then | |
| 2279 | +** the redirect would be to: | |
| 2280 | +** | |
| 2281 | +** https://fossil-scm.org/home/timeline?c=20250404 | |
| 2282 | +** ^^^^^^^^^^^^^^^^^^^^ | |
| 2283 | +** Copied from input URL | |
| 2272 | 2284 | */ |
| 2273 | 2285 | static void redirect_web_page(int nRedirect, char **azRedirect){ |
| 2274 | 2286 | int i; /* Loop counter */ |
| 2275 | 2287 | const char *zNotFound = 0; /* Not found URL */ |
| 2276 | 2288 | const char *zName = P("name"); |
| @@ -2297,21 +2309,22 @@ | ||
| 2297 | 2309 | } |
| 2298 | 2310 | if( zNotFound ){ |
| 2299 | 2311 | Blob to; |
| 2300 | 2312 | const char *z; |
| 2301 | 2313 | if( strstr(zNotFound, "%s") ){ |
| 2302 | - cgi_redirectf(zNotFound /*works-like:"%s"*/, zName); | |
| 2314 | + char *zTarget = mprintf(zNotFound /*works-like:"%s"*/, zName); | |
| 2315 | + cgi_redirect_perm(zTarget); | |
| 2303 | 2316 | } |
| 2304 | 2317 | if( strchr(zNotFound, '?') ){ |
| 2305 | - cgi_redirect(zNotFound); | |
| 2318 | + cgi_redirect_perm(zNotFound); | |
| 2306 | 2319 | } |
| 2307 | 2320 | blob_init(&to, zNotFound, -1); |
| 2308 | 2321 | z = P("PATH_INFO"); |
| 2309 | 2322 | if( z && z[0]=='/' ) blob_append(&to, z, -1); |
| 2310 | 2323 | z = P("QUERY_STRING"); |
| 2311 | 2324 | if( z && z[0]!=0 ) blob_appendf(&to, "?%s", z); |
| 2312 | - cgi_redirect(blob_str(&to)); | |
| 2325 | + cgi_redirect_perm(blob_str(&to)); | |
| 2313 | 2326 | }else{ |
| 2314 | 2327 | @ <html> |
| 2315 | 2328 | @ <head><title>No Such Object</title></head> |
| 2316 | 2329 | @ <body> |
| 2317 | 2330 | @ <p>No such object: <b>%h(zName)</b></p> |
| @@ -2394,10 +2407,13 @@ | ||
| 2394 | 2407 | ** REPO for a check-in or ticket that matches the |
| 2395 | 2408 | ** value of "name", then redirect to URL. There |
| 2396 | 2409 | ** can be multiple "redirect:" lines that are |
| 2397 | 2410 | ** processed in order. If the REPO is "*", then |
| 2398 | 2411 | ** an unconditional redirect to URL is taken. |
| 2412 | +** When "*" is used a 301 permanent redirect is | |
| 2413 | +** issued and the tail and query string from the | |
| 2414 | +** original query are appeneded onto URL. | |
| 2399 | 2415 | ** |
| 2400 | 2416 | ** jsmode: VALUE Specifies the delivery mode for JavaScript |
| 2401 | 2417 | ** files. See the help text for the --jsmode |
| 2402 | 2418 | ** flag of the http command. |
| 2403 | 2419 | ** |
| 2404 | 2420 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -2053,11 +2053,12 @@ | |
| 2053 | */ |
| 2054 | set_base_url(0); |
| 2055 | if( fossil_redirect_to_https_if_needed(2) ) return; |
| 2056 | if( zPathInfo==0 || zPathInfo[0]==0 |
| 2057 | || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){ |
| 2058 | /* Second special case: If the PATH_INFO is blank, issue a redirect: |
| 2059 | ** (1) to "/ckout" if g.useLocalauth and g.localOpen are both set. |
| 2060 | ** (2) to the home page identified by the "index-page" setting |
| 2061 | ** in the repository CONFIG table |
| 2062 | ** (3) to "/index" if there no "index-page" setting in CONFIG |
| 2063 | */ |
| @@ -2267,10 +2268,21 @@ | |
| 2267 | ** |
| 2268 | ** #!/usr/bin/fossil |
| 2269 | ** redirect: * https://fossil-scm.org/home |
| 2270 | ** |
| 2271 | ** Thus requests to the .com website redirect to the .org website. |
| 2272 | */ |
| 2273 | static void redirect_web_page(int nRedirect, char **azRedirect){ |
| 2274 | int i; /* Loop counter */ |
| 2275 | const char *zNotFound = 0; /* Not found URL */ |
| 2276 | const char *zName = P("name"); |
| @@ -2297,21 +2309,22 @@ | |
| 2297 | } |
| 2298 | if( zNotFound ){ |
| 2299 | Blob to; |
| 2300 | const char *z; |
| 2301 | if( strstr(zNotFound, "%s") ){ |
| 2302 | cgi_redirectf(zNotFound /*works-like:"%s"*/, zName); |
| 2303 | } |
| 2304 | if( strchr(zNotFound, '?') ){ |
| 2305 | cgi_redirect(zNotFound); |
| 2306 | } |
| 2307 | blob_init(&to, zNotFound, -1); |
| 2308 | z = P("PATH_INFO"); |
| 2309 | if( z && z[0]=='/' ) blob_append(&to, z, -1); |
| 2310 | z = P("QUERY_STRING"); |
| 2311 | if( z && z[0]!=0 ) blob_appendf(&to, "?%s", z); |
| 2312 | cgi_redirect(blob_str(&to)); |
| 2313 | }else{ |
| 2314 | @ <html> |
| 2315 | @ <head><title>No Such Object</title></head> |
| 2316 | @ <body> |
| 2317 | @ <p>No such object: <b>%h(zName)</b></p> |
| @@ -2394,10 +2407,13 @@ | |
| 2394 | ** REPO for a check-in or ticket that matches the |
| 2395 | ** value of "name", then redirect to URL. There |
| 2396 | ** can be multiple "redirect:" lines that are |
| 2397 | ** processed in order. If the REPO is "*", then |
| 2398 | ** an unconditional redirect to URL is taken. |
| 2399 | ** |
| 2400 | ** jsmode: VALUE Specifies the delivery mode for JavaScript |
| 2401 | ** files. See the help text for the --jsmode |
| 2402 | ** flag of the http command. |
| 2403 | ** |
| 2404 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -2053,11 +2053,12 @@ | |
| 2053 | */ |
| 2054 | set_base_url(0); |
| 2055 | if( fossil_redirect_to_https_if_needed(2) ) return; |
| 2056 | if( zPathInfo==0 || zPathInfo[0]==0 |
| 2057 | || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){ |
| 2058 | /* Second special case: If the PATH_INFO is blank, issue a |
| 2059 | ** temporary 302 redirect: |
| 2060 | ** (1) to "/ckout" if g.useLocalauth and g.localOpen are both set. |
| 2061 | ** (2) to the home page identified by the "index-page" setting |
| 2062 | ** in the repository CONFIG table |
| 2063 | ** (3) to "/index" if there no "index-page" setting in CONFIG |
| 2064 | */ |
| @@ -2267,10 +2268,21 @@ | |
| 2268 | ** |
| 2269 | ** #!/usr/bin/fossil |
| 2270 | ** redirect: * https://fossil-scm.org/home |
| 2271 | ** |
| 2272 | ** Thus requests to the .com website redirect to the .org website. |
| 2273 | ** This form uses a 301 Permanent redirect. |
| 2274 | ** |
| 2275 | ** On a "*" redirect, the PATH_INFO and QUERY_STRING of the query |
| 2276 | ** that provoked the redirect are appended to the target. So, for |
| 2277 | ** example, if the input URL for the redirect above were |
| 2278 | ** "http://www.fossil.com/index.html/timeline?c=20250404", then |
| 2279 | ** the redirect would be to: |
| 2280 | ** |
| 2281 | ** https://fossil-scm.org/home/timeline?c=20250404 |
| 2282 | ** ^^^^^^^^^^^^^^^^^^^^ |
| 2283 | ** Copied from input URL |
| 2284 | */ |
| 2285 | static void redirect_web_page(int nRedirect, char **azRedirect){ |
| 2286 | int i; /* Loop counter */ |
| 2287 | const char *zNotFound = 0; /* Not found URL */ |
| 2288 | const char *zName = P("name"); |
| @@ -2297,21 +2309,22 @@ | |
| 2309 | } |
| 2310 | if( zNotFound ){ |
| 2311 | Blob to; |
| 2312 | const char *z; |
| 2313 | if( strstr(zNotFound, "%s") ){ |
| 2314 | char *zTarget = mprintf(zNotFound /*works-like:"%s"*/, zName); |
| 2315 | cgi_redirect_perm(zTarget); |
| 2316 | } |
| 2317 | if( strchr(zNotFound, '?') ){ |
| 2318 | cgi_redirect_perm(zNotFound); |
| 2319 | } |
| 2320 | blob_init(&to, zNotFound, -1); |
| 2321 | z = P("PATH_INFO"); |
| 2322 | if( z && z[0]=='/' ) blob_append(&to, z, -1); |
| 2323 | z = P("QUERY_STRING"); |
| 2324 | if( z && z[0]!=0 ) blob_appendf(&to, "?%s", z); |
| 2325 | cgi_redirect_perm(blob_str(&to)); |
| 2326 | }else{ |
| 2327 | @ <html> |
| 2328 | @ <head><title>No Such Object</title></head> |
| 2329 | @ <body> |
| 2330 | @ <p>No such object: <b>%h(zName)</b></p> |
| @@ -2394,10 +2407,13 @@ | |
| 2407 | ** REPO for a check-in or ticket that matches the |
| 2408 | ** value of "name", then redirect to URL. There |
| 2409 | ** can be multiple "redirect:" lines that are |
| 2410 | ** processed in order. If the REPO is "*", then |
| 2411 | ** an unconditional redirect to URL is taken. |
| 2412 | ** When "*" is used a 301 permanent redirect is |
| 2413 | ** issued and the tail and query string from the |
| 2414 | ** original query are appeneded onto URL. |
| 2415 | ** |
| 2416 | ** jsmode: VALUE Specifies the delivery mode for JavaScript |
| 2417 | ** files. See the help text for the --jsmode |
| 2418 | ** flag of the http command. |
| 2419 | ** |
| 2420 |