Fossil

Check-in [54a8243b]
Login

Check-in [54a8243b]

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

Overview
Comment:Add the fossil_exe_id() internal interface that returns a unique hash that changes whenever Fossil is recompiled (more precisely, whenever the MANIFEST_UUID changes or the etag.c source file is recompiled).
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 54a8243bf5e4b24b5760b29b42299bb7368b7b2f0058f2e1593597d9f92531e6
User & Date: drh 2020-05-10 13:58:02
Context
2020-05-10
14:51
Shift the computation of the hash returned by fossil_exe_id() from run-time to compile-time. (check-in: 22fc5a79 user: drh tags: trunk)
14:50
Merge in trunk for fossil_exe_id() and use it, instead of md5, as the builtin/*.js cache-buster value. (check-in: 7e43119a user: stephan tags: fileedit-ajaxify)
13:58
Add the fossil_exe_id() internal interface that returns a unique hash that changes whenever Fossil is recompiled (more precisely, whenever the MANIFEST_UUID changes or the etag.c source file is recompiled). (check-in: 54a8243b user: drh tags: trunk)
12:58
Proof-of-concept ETag caching for the /timeline page. Seems to work. Most other webpages could easily add ETag caching now. (check-in: 7eaecedd user: drh tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/etag.c.

64
65
66
67
68
69
70



















71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#define ETAG_HASH     0x08 /* Output depends on a hash */
#define ETAG_QUERY    0x10 /* Output depends on PATH_INFO and QUERY_STRING */
#endif

static char zETag[33];      /* The generated ETag */
static int iMaxAge = 0;     /* The max-age parameter in the reply */
static sqlite3_int64 iEtagMtime = 0;  /* Last-Modified time */




















/*
** Generate an ETag
*/
void etag_check(unsigned eFlags, const char *zHash){
  sqlite3_int64 mtime;
  const char *zIfNoneMatch;
  char zBuf[50];
  assert( zETag[0]==0 );  /* Only call this routine once! */

  iMaxAge = 86400;
  md5sum_init();

  /* Always include the mtime of the executable as part of the hash */
  mtime = file_mtime(g.nameOfExe, ExtFILE);
  sqlite3_snprintf(sizeof(zBuf),zBuf,"mtime: %lld\n", mtime);
  md5sum_step_text(zBuf, -1);
  
  if( (eFlags & ETAG_HASH)!=0 && zHash ){
    md5sum_step_text("hash: ", -1);
    md5sum_step_text(zHash, -1);
    md5sum_step_text("\n", 1);
    iMaxAge = 0;
  }else if( eFlags & ETAG_DATA ){







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





<







|
|
|
|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#define ETAG_HASH     0x08 /* Output depends on a hash */
#define ETAG_QUERY    0x10 /* Output depends on PATH_INFO and QUERY_STRING */
#endif

static char zETag[33];      /* The generated ETag */
static int iMaxAge = 0;     /* The max-age parameter in the reply */
static sqlite3_int64 iEtagMtime = 0;  /* Last-Modified time */

/*
** Return a hash that changes every time the Fossil source code is
** rebuilt.
**
** The current implementation is a hash of MANIFEST_UUID, __DATE__, and
** __TIME__.  But this might change in the future if we think of a better
** way to compute an identifier that changes with each build.
*/
const char *fossil_exe_id(void){
  static char zExecId[33];
  if( zExecId[0]==0 ){
    Blob x;
    blob_init(&x, MANIFEST_UUID "," __DATE__ "," __TIME__, -1);
    md5sum_blob(&x, &x);
    memcpy(zExecId, x.aData, 32);
  }
  return zExecId;
}

/*
** Generate an ETag
*/
void etag_check(unsigned eFlags, const char *zHash){

  const char *zIfNoneMatch;
  char zBuf[50];
  assert( zETag[0]==0 );  /* Only call this routine once! */

  iMaxAge = 86400;
  md5sum_init();

  /* Always include the executable ID as part of the hash */
  md5sum_step_text("exe-id: ", -1);
  md5sum_step_text(fossil_exe_id(), -1);
  md5sum_step_text("\n", 1);
  
  if( (eFlags & ETAG_HASH)!=0 && zHash ){
    md5sum_step_text("hash: ", -1);
    md5sum_step_text(zHash, -1);
    md5sum_step_text("\n", 1);
    iMaxAge = 0;
  }else if( eFlags & ETAG_DATA ){

Changes to src/style.c.

705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
  needCopyBtnJs = 1;
}

/*
** Generate code to load a single javascript file
*/
void style_load_one_js_file(const char *zFile){
  @ <script src='%R/builtin/%s(zFile)?id=%S(MANIFEST_UUID)'></script>
}

/*
** All extra JS files to load.
*/
static const char *azJsToLoad[4];
static int nJsToLoad = 0;







|







705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
  needCopyBtnJs = 1;
}

/*
** Generate code to load a single javascript file
*/
void style_load_one_js_file(const char *zFile){
  @ <script src='%R/builtin/%s(zFile)?id=%S(fossil_exe_id())'></script>
}

/*
** All extra JS files to load.
*/
static const char *azJsToLoad[4];
static int nJsToLoad = 0;
1257
1258
1259
1260
1261
1262
1263

1264
1265
1266
1267
1268
1269
1270
    @ capabilities = %s(find_capabilities(zCap))<br />
    if( zCap[0] ){
      @ anonymous-adds = %s(find_anon_capabilities(zCap))<br />
    }
    @ g.zRepositoryName = %h(g.zRepositoryName)<br />
    @ load_average() = %f(load_average())<br />
    @ cgi_csrf_safe(0) = %d(cgi_csrf_safe(0))<br />

    @ <hr />
    P("HTTP_USER_AGENT");
    cgi_print_all(showAll, 0);
    if( showAll && blob_size(&g.httpHeader)>0 ){
      @ <hr />
      @ <pre>
      @ %h(blob_str(&g.httpHeader))







>







1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
    @ capabilities = %s(find_capabilities(zCap))<br />
    if( zCap[0] ){
      @ anonymous-adds = %s(find_anon_capabilities(zCap))<br />
    }
    @ g.zRepositoryName = %h(g.zRepositoryName)<br />
    @ load_average() = %f(load_average())<br />
    @ cgi_csrf_safe(0) = %d(cgi_csrf_safe(0))<br />
    @ fossil_exe_id() = %h(fossil_exe_id())<br />
    @ <hr />
    P("HTTP_USER_AGENT");
    cgi_print_all(showAll, 0);
    if( showAll && blob_size(&g.httpHeader)>0 ){
      @ <hr />
      @ <pre>
      @ %h(blob_str(&g.httpHeader))