Check-in [8dbcf2acba]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Remove the now-obsolete parsing of the X-Fossil-Xfer-Login HTTP header.
Timelines: family | ancestors | descendants | both | xfer-login-card
Files: files | file ages | folders
SHA3-256: 8dbcf2acba6f00bd72bf8555274f9a6ed9d52e3d4cce93e285fe695cbfbf411f
User & Date: stephan 2025-07-24 05:26:40.894
Context
2025-07-25
15:08
Extend the login card mode version check to include the date and time. It is currently still set to 2.27.1, but if/when merged then the version would need to be reverted to 2.27.0 and the version/date/time check will need to be set to compare against the trunk version from immediately before the merge. This needs more testing but looks like it will... check-in: 86cc923de4 user: stephan tags: xfer-login-card
2025-07-24
05:26
Remove the now-obsolete parsing of the X-Fossil-Xfer-Login HTTP header. check-in: 8dbcf2acba user: stephan tags: xfer-login-card
05:10
Use a Cookie, instead of a custom HTTP header and/or URL param, to send the sync login header, as suggested in [forum:9959d2d9d9be22d2 | forum post 9959d2d9d9be22d2]. This is simpler. check-in: 756ad2f23c user: stephan tags: xfer-login-card
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/cgi.c.
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
    }
  }
  if( !g.syncInfo.zLoginCard && 0!=(z=(char*)P("x-f-x-l")) ){
    /* X-Fossil-Xfer-Login card transmitted via cookie instead of in
    ** the sync payload. */
    rc |= 0x04;
    g.syncInfo.zLoginCard = fossil_strdup(z);
    g.syncInfo.fLoginCardMode |= 0x04;
    cgi_delete_parameter("x-f-x-l");
  }
  return rc;
}

/*
** Initialize the query parameter database.  Information is pulled from







|







1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
    }
  }
  if( !g.syncInfo.zLoginCard && 0!=(z=(char*)P("x-f-x-l")) ){
    /* X-Fossil-Xfer-Login card transmitted via cookie instead of in
    ** the sync payload. */
    rc |= 0x04;
    g.syncInfo.zLoginCard = fossil_strdup(z);
    g.syncInfo.fLoginCardMode |= 0x02;
    cgi_delete_parameter("x-f-x-l");
  }
  return rc;
}

/*
** Initialize the query parameter database.  Information is pulled from
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
    }else if( fossil_strcmp(zFieldName,"range:")==0 ){
      int x1 = 0;
      int x2 = 0;
      if( sscanf(zVal,"bytes=%d-%d",&x1,&x2)==2 && x1>=0 && x1<=x2 ){
        rangeStart = x1;
        rangeEnd = x2+1;
      }
    }else if( fossil_strcmp(zFieldName, "x-fossil-xfer-login:")==0 ){
      fossil_free( g.syncInfo.zLoginCard );
      g.syncInfo.zLoginCard = fossil_strdup(zVal);
      g.syncInfo.fLoginCardMode |= 0x08;
    }
  }
  cgi_setenv("REQUEST_SCHEME",zScheme);
  cgi_init();
  cgi_trace(0);
}








<
<
<
<







2232
2233
2234
2235
2236
2237
2238




2239
2240
2241
2242
2243
2244
2245
    }else if( fossil_strcmp(zFieldName,"range:")==0 ){
      int x1 = 0;
      int x2 = 0;
      if( sscanf(zVal,"bytes=%d-%d",&x1,&x2)==2 && x1>=0 && x1<=x2 ){
        rangeStart = x1;
        rangeEnd = x2+1;
      }




    }
  }
  cgi_setenv("REQUEST_SCHEME",zScheme);
  cgi_init();
  cgi_trace(0);
}

Changes to src/http.c.
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
      }else{
        if( mHttpFlags & HTTP_GENERIC ){
          if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0;
        }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){
          isError = 1;
        }
      }
    }else if( fossil_strnicmp(zLine, "x-fossil-xfer-login: ", 21)==0 ){
      fossil_free( g.syncInfo.zLoginCard );
      g.syncInfo.zLoginCard = fossil_strdup(&zLine[21]);
      g.syncInfo.fLoginCardMode |= 0x02;
    }
  }
  if( iHttpVersion<0 ){
    /* We got nothing back from the server.  If using the ssh: protocol,
    ** this might mean we need to add or remove the PATH=... argument
    ** to the SSH command being sent.  If that is the case, retry the
    ** request after adding or removing the PATH= argument.







<
<
<
<







660
661
662
663
664
665
666




667
668
669
670
671
672
673
      }else{
        if( mHttpFlags & HTTP_GENERIC ){
          if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0;
        }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){
          isError = 1;
        }
      }




    }
  }
  if( iHttpVersion<0 ){
    /* We got nothing back from the server.  If using the ssh: protocol,
    ** this might mean we need to add or remove the PATH=... argument
    ** to the SSH command being sent.  If that is the case, retry the
    ** request after adding or removing the PATH= argument.
Changes to src/main.c.
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
  int nPendingRequest;           /* # of HTTP requests in "fossil server" */
  int nRequest;                  /* Total # of HTTP request */
  int bAvoidDeltaManifests;      /* Avoid using delta manifests if true */

  /* State for communicating specific details between the inbound HTTP
  ** header parser (cgi.c), xfer.c, and http.c. */
  struct {
    char *zLoginCard;       /* Inbound "X-Fossil-Xfer-Login" request
                            ** header or "x-f-x-l" URL parameter. */
    int fLoginCardMode;     /* If non-0, emit login cards in outbound
                            ** requests as a HTTP cookie instead of as
                            ** part of the payload. Gets activated
                            ** on-demand based on xfer traffic
                            ** contents. Values, for
                            ** diagnostic/debugging purposes: 0x01=CLI
                            ** --flag, 0x02=http_exchange(),
                            ** 0x04=cgi_setup_query_string(),
                            ** 0x08=cgi_handle_cgi_request(),
                            ** 0x20=page_xfer(),
                            ** 0x40=client_sync(). */
    int remoteVersion;      /* Remote fossil version. Used for negotiating
                            ** how to handle the login card. */
  } syncInfo;
#ifdef FOSSIL_ENABLE_JSON
  struct FossilJsonBits {
    int isJsonMode;            /* True if running in JSON mode, else
                                  false. This changes how errors are







|
<






<
|
<
|
|







290
291
292
293
294
295
296
297

298
299
300
301
302
303

304

305
306
307
308
309
310
311
312
313
  int nPendingRequest;           /* # of HTTP requests in "fossil server" */
  int nRequest;                  /* Total # of HTTP request */
  int bAvoidDeltaManifests;      /* Avoid using delta manifests if true */

  /* State for communicating specific details between the inbound HTTP
  ** header parser (cgi.c), xfer.c, and http.c. */
  struct {
    char *zLoginCard;       /* Inbound "x-f-x-l" Cookie header. */

    int fLoginCardMode;     /* If non-0, emit login cards in outbound
                            ** requests as a HTTP cookie instead of as
                            ** part of the payload. Gets activated
                            ** on-demand based on xfer traffic
                            ** contents. Values, for
                            ** diagnostic/debugging purposes: 0x01=CLI

                            ** --flag, 0x02=cgi_setup_query_string(),

                            ** 0x04=page_xfer(),
                            ** 0x08=client_sync(). */
    int remoteVersion;      /* Remote fossil version. Used for negotiating
                            ** how to handle the login card. */
  } syncInfo;
#ifdef FOSSIL_ENABLE_JSON
  struct FossilJsonBits {
    int isJsonMode;            /* True if running in JSON mode, else
                                  false. This changes how errors are
Changes to src/xfer.c.
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
  }
  zScript = xfer_push_code();
  if( zScript ){ /* NOTE: Are TH1 transfer hooks enabled? */
    pzUuidList = &zUuidList;
    pnUuidList = &nUuidList;
  }
  if( g.syncInfo.zLoginCard ){
    /* Login card received via HTTP header "X-Fossil-Xfer-Login" or
    ** "x-f-x-l" URL parameter. */
    assert( g.syncInfo.fLoginCardMode && "Set via HTTP header/URL arg" );
    blob_zero(&xfer.line);
    blob_append(&xfer.line, g.syncInfo.zLoginCard, -1);
    xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken,
                                count(xfer.aToken));
    fossil_free( g.syncInfo.zLoginCard );
    g.syncInfo.zLoginCard = 0;
    if( xfer.nToken==4







|
<
|







1315
1316
1317
1318
1319
1320
1321
1322

1323
1324
1325
1326
1327
1328
1329
1330
  }
  zScript = xfer_push_code();
  if( zScript ){ /* NOTE: Are TH1 transfer hooks enabled? */
    pzUuidList = &zUuidList;
    pnUuidList = &nUuidList;
  }
  if( g.syncInfo.zLoginCard ){
    /* Login card received via HTTP Cookie header "x-f-x-l" */

    assert( g.syncInfo.fLoginCardMode && "Set via HTTP cookie" );
    blob_zero(&xfer.line);
    blob_append(&xfer.line, g.syncInfo.zLoginCard, -1);
    xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken,
                                count(xfer.aToken));
    fossil_free( g.syncInfo.zLoginCard );
    g.syncInfo.zLoginCard = 0;
    if( xfer.nToken==4
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
      ** is running.  The DATE and TIME are a pure numeric ISO8601 time
      ** for the specific check-in of the client.
      */
      if( xfer.nToken>=3 && blob_eq(&xfer.aToken[1], "client-version") ){
        xfer.remoteVersion = g.syncInfo.remoteVersion =
          atoi(blob_str(&xfer.aToken[2]));
        if( xfer.remoteVersion>=RELEASE_VERSION_NUMBER ){
          g.syncInfo.fLoginCardMode |= 0x20;
        }
        if( xfer.nToken>=5 ){
          xfer.remoteDate = atoi(blob_str(&xfer.aToken[3]));
          xfer.remoteTime = atoi(blob_str(&xfer.aToken[4]));
          @ pragma server-version %d(RELEASE_VERSION_NUMBER) \
          @ %d(MANIFEST_NUMERIC_DATE) %d(MANIFEST_NUMERIC_TIME)
        }







|







1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
      ** is running.  The DATE and TIME are a pure numeric ISO8601 time
      ** for the specific check-in of the client.
      */
      if( xfer.nToken>=3 && blob_eq(&xfer.aToken[1], "client-version") ){
        xfer.remoteVersion = g.syncInfo.remoteVersion =
          atoi(blob_str(&xfer.aToken[2]));
        if( xfer.remoteVersion>=RELEASE_VERSION_NUMBER ){
          g.syncInfo.fLoginCardMode |= 0x04;
        }
        if( xfer.nToken>=5 ){
          xfer.remoteDate = atoi(blob_str(&xfer.aToken[3]));
          xfer.remoteTime = atoi(blob_str(&xfer.aToken[4]));
          @ pragma server-version %d(RELEASE_VERSION_NUMBER) \
          @ %d(MANIFEST_NUMERIC_DATE) %d(MANIFEST_NUMERIC_TIME)
        }
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
        ** is running.  The DATE and TIME are a pure numeric ISO8601 time
        ** for the specific check-in of the client.
        */
        if( xfer.nToken>=3 && blob_eq(&xfer.aToken[1], "server-version") ){
          xfer.remoteVersion = g.syncInfo.remoteVersion =
            atoi(blob_str(&xfer.aToken[2]));
          if( xfer.remoteVersion>=RELEASE_VERSION_NUMBER ){
            g.syncInfo.fLoginCardMode |= 0x40;
          }
          if( xfer.nToken>=5 ){
            xfer.remoteDate = atoi(blob_str(&xfer.aToken[3]));
            xfer.remoteTime = atoi(blob_str(&xfer.aToken[4]));
          }
        }








|







2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
        ** is running.  The DATE and TIME are a pure numeric ISO8601 time
        ** for the specific check-in of the client.
        */
        if( xfer.nToken>=3 && blob_eq(&xfer.aToken[1], "server-version") ){
          xfer.remoteVersion = g.syncInfo.remoteVersion =
            atoi(blob_str(&xfer.aToken[2]));
          if( xfer.remoteVersion>=RELEASE_VERSION_NUMBER ){
            g.syncInfo.fLoginCardMode |= 0x08;
          }
          if( xfer.nToken>=5 ){
            xfer.remoteDate = atoi(blob_str(&xfer.aToken[3]));
            xfer.remoteTime = atoi(blob_str(&xfer.aToken[4]));
          }
        }