Fossil

Check-in [9789e1dce7]
Login

Check-in [9789e1dce7]

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

Overview
Comment:Do not add the sync login cookie unless we know the remote supports it. It's harmless in that case but it doesn't need to be there. Rename the login cookie from the unweildy x-f-x-l (X-Fossil-Xfer-Login) to x-f-l-c (X-Fossil-Login-Card) because the former is unsightly.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | xfer-login-card
Files: files | file ages | folders
SHA3-256: 9789e1dce77ac767de11d325ea01469c5b0d89836312b13305fcb11288aefe55
User & Date: stephan 2025-07-25 18:47:07.717
Context
2025-07-27
11:07
Teach the sync protocol how to work with an out-of-band login card, saving an extra server-side copy of the sync content which is required only to account for an inlined login card. i.e. it saves RAM, potentially lots of it. The new login card mechanism is instead transported via an HTTP header. This also, not coincidentally, simplifies implementation of the login card in non-fossil(1) clients which are currently learning to speak the sync protocol. ... (check-in: 18628904c3 user: stephan tags: trunk)
2025-07-25
18:47
Do not add the sync login cookie unless we know the remote supports it. It's harmless in that case but it doesn't need to be there. Rename the login cookie from the unweildy x-f-x-l (X-Fossil-Xfer-Login) to x-f-l-c (X-Fossil-Login-Card) because the former is unsightly. ... (Closed-Leaf check-in: 9789e1dce7 user: stephan tags: xfer-login-card)
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 resolve the "post-2.26 trunk" incompatibility. ... (check-in: 86cc923de4 user: stephan tags: xfer-login-card)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/cgi.c.
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
/*
** Checks the QUERY_STRING environment variable, sets it up via
** add_param_list() and, if found, applies its "skin" setting. Returns
** 0 if no QUERY_STRING is set, else it returns a bitmask of:
**
** 0x01 = QUERY_STRING was set up
** 0x02 = "skin" URL param arg was processed
** 0x04 = "x-f-x-l" cookie arg was processed.
**
*  In the case of the skin, the cookie may still need flushing
** by the page, via cookie_render().
*/
int cgi_setup_query_string(void){
  int rc = 0;
  char * z = (char*)P("QUERY_STRING");







|







1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
/*
** Checks the QUERY_STRING environment variable, sets it up via
** add_param_list() and, if found, applies its "skin" setting. Returns
** 0 if no QUERY_STRING is set, else it returns a bitmask of:
**
** 0x01 = QUERY_STRING was set up
** 0x02 = "skin" URL param arg was processed
** 0x04 = "x-f-l-c" cookie arg was processed.
**
*  In the case of the skin, the cookie may still need flushing
** by the page, via cookie_render().
*/
int cgi_setup_query_string(void){
  int rc = 0;
  char * z = (char*)P("QUERY_STRING");
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
        ** implies the "udc" argument, so we force that into the
        ** environment here. */
        cgi_set_parameter_nocopy("udc", "1", 1);
      }
      fossil_free(zErr);
    }
  }
  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
** the QUERY_STRING environment variable (if it exists), from standard







|
|
|



|







1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
        ** implies the "udc" argument, so we force that into the
        ** environment here. */
        cgi_set_parameter_nocopy("udc", "1", 1);
      }
      fossil_free(zErr);
    }
  }
  if( !g.syncInfo.zLoginCard && 0!=(z=(char*)P("x-f-l-c")) ){
    /* x-f-l-c (X-Fossil-Login-Card 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-l-c");
  }
  return rc;
}

/*
** Initialize the query parameter database.  Information is pulled from
** the QUERY_STRING environment variable (if it exists), from standard
Changes to src/http.c.
156
157
158
159
160
161
162

163
164

165
166
167
168
169
170
171
172
    char *zEncoded = encode64(zCredentials, -1);
    blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded);
    fossil_free(zEncoded);
  }
  blob_appendf(pHdr, "Host: %s\r\n", g.url.hostname);
  blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent());
  if( g.url.isSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n");

  if( nPayload>0 && pLogin && blob_size(pLogin) ){
    /* Add login card via a transient cookie. */

    blob_appendf(pHdr, "Cookie: x-f-x-l=%T\r\n", blob_str(pLogin));
  }
  if( nPayload ){
    if( zAltMimetype ){
      blob_appendf(pHdr, "Content-Type: %s\r\n", zAltMimetype);
    }else if( g.fHttpTrace ){
      blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n");
    }else{







>
|
|
>
|







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    char *zEncoded = encode64(zCredentials, -1);
    blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded);
    fossil_free(zEncoded);
  }
  blob_appendf(pHdr, "Host: %s\r\n", g.url.hostname);
  blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent());
  if( g.url.isSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n");
  if( g.syncInfo.fLoginCardMode>0
      && nPayload>0 && pLogin && blob_size(pLogin) ){
    /* Add sync login card via a transient cookie. We can only do this
       if we know the remote supports it. */
    blob_appendf(pHdr, "Cookie: x-f-l-c=%T\r\n", blob_str(pLogin));
  }
  if( nPayload ){
    if( zAltMimetype ){
      blob_appendf(pHdr, "Content-Type: %s\r\n", zAltMimetype);
    }else if( g.fHttpTrace ){
      blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n");
    }else{
Changes to src/main.c.
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
  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(),







|







290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
  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-l-c" 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(),
Changes to src/xfer.c.
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
  }
  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;







|







1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
  }
  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 */
    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;