Fossil SCM
Have the new "fossil get" command work more like other SSH operations (e.g. sync, clone) by sending the complete URI. This enables "fossil get" to work with SSH servers with force the command to "fossil test-http /path" to restrict access to just Fossil repositories from a specific directory, without wich Fossil returns 404. See problem discussion in [forum:/forumpost/7b3e0e0582525d3b|forum post 7b3e0e0582525d] for more details.
Commit
6fc687402673e884ba2b47aa45d44b859428909bdd1eb75561bff6aca0ade331
Parent
196cb7722377ef1…
2 files changed
+8
-1
+1
-1
+8
-1
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -2290,11 +2290,11 @@ | ||
| 2290 | 2290 | */ |
| 2291 | 2291 | void cgi_handle_ssh_http_request(const char *zIpAddr){ |
| 2292 | 2292 | static int nCycles = 0; |
| 2293 | 2293 | static char *zCmd = 0; |
| 2294 | 2294 | char *z, *zToken; |
| 2295 | - int i; | |
| 2295 | + int i, n; | |
| 2296 | 2296 | char zLine[2000]; /* A single line of input. */ |
| 2297 | 2297 | |
| 2298 | 2298 | assert( !g.httpUseSSL ); |
| 2299 | 2299 | #ifdef FOSSIL_ENABLE_JSON |
| 2300 | 2300 | if( nCycles==0 ){ json_bootstrap_early(); } |
| @@ -2350,10 +2350,17 @@ | ||
| 2350 | 2350 | cgi_setenv("GATEWAY_INTERFACE","CGI/1.0"); |
| 2351 | 2351 | cgi_setenv("REQUEST_METHOD",zToken); |
| 2352 | 2352 | } |
| 2353 | 2353 | |
| 2354 | 2354 | zToken = extract_token(z, &z); |
| 2355 | + if( zToken==0 ){ | |
| 2356 | + malformed_request("malformed URL in HTTP header"); | |
| 2357 | + } | |
| 2358 | + n = strlen(g.zRepositoryName); | |
| 2359 | + if( fossil_strncmp(g.zRepositoryName, zToken, n)==0 ){ | |
| 2360 | + zToken += n; | |
| 2361 | + } | |
| 2355 | 2362 | if( zToken==0 ){ |
| 2356 | 2363 | malformed_request("malformed URL in HTTP header"); |
| 2357 | 2364 | } |
| 2358 | 2365 | if( nCycles==0 ){ |
| 2359 | 2366 | cgi_setenv("REQUEST_URI", zToken); |
| 2360 | 2367 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -2290,11 +2290,11 @@ | |
| 2290 | */ |
| 2291 | void cgi_handle_ssh_http_request(const char *zIpAddr){ |
| 2292 | static int nCycles = 0; |
| 2293 | static char *zCmd = 0; |
| 2294 | char *z, *zToken; |
| 2295 | int i; |
| 2296 | char zLine[2000]; /* A single line of input. */ |
| 2297 | |
| 2298 | assert( !g.httpUseSSL ); |
| 2299 | #ifdef FOSSIL_ENABLE_JSON |
| 2300 | if( nCycles==0 ){ json_bootstrap_early(); } |
| @@ -2350,10 +2350,17 @@ | |
| 2350 | cgi_setenv("GATEWAY_INTERFACE","CGI/1.0"); |
| 2351 | cgi_setenv("REQUEST_METHOD",zToken); |
| 2352 | } |
| 2353 | |
| 2354 | zToken = extract_token(z, &z); |
| 2355 | if( zToken==0 ){ |
| 2356 | malformed_request("malformed URL in HTTP header"); |
| 2357 | } |
| 2358 | if( nCycles==0 ){ |
| 2359 | cgi_setenv("REQUEST_URI", zToken); |
| 2360 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -2290,11 +2290,11 @@ | |
| 2290 | */ |
| 2291 | void cgi_handle_ssh_http_request(const char *zIpAddr){ |
| 2292 | static int nCycles = 0; |
| 2293 | static char *zCmd = 0; |
| 2294 | char *z, *zToken; |
| 2295 | int i, n; |
| 2296 | char zLine[2000]; /* A single line of input. */ |
| 2297 | |
| 2298 | assert( !g.httpUseSSL ); |
| 2299 | #ifdef FOSSIL_ENABLE_JSON |
| 2300 | if( nCycles==0 ){ json_bootstrap_early(); } |
| @@ -2350,10 +2350,17 @@ | |
| 2350 | cgi_setenv("GATEWAY_INTERFACE","CGI/1.0"); |
| 2351 | cgi_setenv("REQUEST_METHOD",zToken); |
| 2352 | } |
| 2353 | |
| 2354 | zToken = extract_token(z, &z); |
| 2355 | if( zToken==0 ){ |
| 2356 | malformed_request("malformed URL in HTTP header"); |
| 2357 | } |
| 2358 | n = strlen(g.zRepositoryName); |
| 2359 | if( fossil_strncmp(g.zRepositoryName, zToken, n)==0 ){ |
| 2360 | zToken += n; |
| 2361 | } |
| 2362 | if( zToken==0 ){ |
| 2363 | malformed_request("malformed URL in HTTP header"); |
| 2364 | } |
| 2365 | if( nCycles==0 ){ |
| 2366 | cgi_setenv("REQUEST_URI", zToken); |
| 2367 |
+1
-1
| --- src/checkout.c | ||
| +++ src/checkout.c | ||
| @@ -556,11 +556,11 @@ | ||
| 556 | 556 | } |
| 557 | 557 | } |
| 558 | 558 | } |
| 559 | 559 | |
| 560 | 560 | /* Construct a subpath on the URL if necessary */ |
| 561 | - if( g.url.isSsh || g.url.isFile ){ | |
| 561 | + if( g.url.isFile ){ | |
| 562 | 562 | g.url.subpath = mprintf("/sqlar/%t/%t.sqlar", zVers, zDest); |
| 563 | 563 | }else{ |
| 564 | 564 | g.url.subpath = mprintf("%s/sqlar/%t/%t.sqlar", g.url.path, zVers, zDest); |
| 565 | 565 | } |
| 566 | 566 | |
| 567 | 567 |
| --- src/checkout.c | |
| +++ src/checkout.c | |
| @@ -556,11 +556,11 @@ | |
| 556 | } |
| 557 | } |
| 558 | } |
| 559 | |
| 560 | /* Construct a subpath on the URL if necessary */ |
| 561 | if( g.url.isSsh || g.url.isFile ){ |
| 562 | g.url.subpath = mprintf("/sqlar/%t/%t.sqlar", zVers, zDest); |
| 563 | }else{ |
| 564 | g.url.subpath = mprintf("%s/sqlar/%t/%t.sqlar", g.url.path, zVers, zDest); |
| 565 | } |
| 566 | |
| 567 |
| --- src/checkout.c | |
| +++ src/checkout.c | |
| @@ -556,11 +556,11 @@ | |
| 556 | } |
| 557 | } |
| 558 | } |
| 559 | |
| 560 | /* Construct a subpath on the URL if necessary */ |
| 561 | if( g.url.isFile ){ |
| 562 | g.url.subpath = mprintf("/sqlar/%t/%t.sqlar", zVers, zDest); |
| 563 | }else{ |
| 564 | g.url.subpath = mprintf("%s/sqlar/%t/%t.sqlar", g.url.path, zVers, zDest); |
| 565 | } |
| 566 | |
| 567 |