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.

andybradford 2025-10-17 03:41 UTC trunk
Commit 6fc687402673e884ba2b47aa45d44b859428909bdd1eb75561bff6aca0ade331
2 files changed +8 -1 +1 -1
+8 -1
--- src/cgi.c
+++ src/cgi.c
@@ -2290,11 +2290,11 @@
22902290
*/
22912291
void cgi_handle_ssh_http_request(const char *zIpAddr){
22922292
static int nCycles = 0;
22932293
static char *zCmd = 0;
22942294
char *z, *zToken;
2295
- int i;
2295
+ int i, n;
22962296
char zLine[2000]; /* A single line of input. */
22972297
22982298
assert( !g.httpUseSSL );
22992299
#ifdef FOSSIL_ENABLE_JSON
23002300
if( nCycles==0 ){ json_bootstrap_early(); }
@@ -2350,10 +2350,17 @@
23502350
cgi_setenv("GATEWAY_INTERFACE","CGI/1.0");
23512351
cgi_setenv("REQUEST_METHOD",zToken);
23522352
}
23532353
23542354
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
+ }
23552362
if( zToken==0 ){
23562363
malformed_request("malformed URL in HTTP header");
23572364
}
23582365
if( nCycles==0 ){
23592366
cgi_setenv("REQUEST_URI", zToken);
23602367
--- 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 @@
556556
}
557557
}
558558
}
559559
560560
/* Construct a subpath on the URL if necessary */
561
- if( g.url.isSsh || g.url.isFile ){
561
+ if( g.url.isFile ){
562562
g.url.subpath = mprintf("/sqlar/%t/%t.sqlar", zVers, zDest);
563563
}else{
564564
g.url.subpath = mprintf("%s/sqlar/%t/%t.sqlar", g.url.path, zVers, zDest);
565565
}
566566
567567
--- 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

Keyboard Shortcuts

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