Fossil SCM

Enhance the Cache-control: header for tarballs and archives so that if the object is uniquely identified by a hash the download has a 10-year timeout and an "immutable" tag.

drh 2021-07-11 19:30 trunk
Commit 44339d537869206a9a935a55dc327d75524eda8605b4d707a83ef546f55b742c
+1 -1
--- src/cgi.c
+++ src/cgi.c
@@ -313,11 +313,11 @@
313313
cgi_rfc822_datestamp(etag_mtime()));
314314
}
315315
}else if( g.isConst ){
316316
/* isConst means that the reply is guaranteed to be invariant, even
317317
** after configuration changes and/or Fossil binary recompiles. */
318
- fprintf(g.httpOut, "Cache-Control: max-age=31536000\r\n");
318
+ fprintf(g.httpOut, "Cache-Control: max-age=315360000, immutable\r\n");
319319
}else{
320320
fprintf(g.httpOut, "Cache-control: no-cache\r\n");
321321
}
322322
323323
if( blob_size(&extraHeader)>0 ){
324324
--- src/cgi.c
+++ src/cgi.c
@@ -313,11 +313,11 @@
313 cgi_rfc822_datestamp(etag_mtime()));
314 }
315 }else if( g.isConst ){
316 /* isConst means that the reply is guaranteed to be invariant, even
317 ** after configuration changes and/or Fossil binary recompiles. */
318 fprintf(g.httpOut, "Cache-Control: max-age=31536000\r\n");
319 }else{
320 fprintf(g.httpOut, "Cache-control: no-cache\r\n");
321 }
322
323 if( blob_size(&extraHeader)>0 ){
324
--- src/cgi.c
+++ src/cgi.c
@@ -313,11 +313,11 @@
313 cgi_rfc822_datestamp(etag_mtime()));
314 }
315 }else if( g.isConst ){
316 /* isConst means that the reply is guaranteed to be invariant, even
317 ** after configuration changes and/or Fossil binary recompiles. */
318 fprintf(g.httpOut, "Cache-Control: max-age=315360000, immutable\r\n");
319 }else{
320 fprintf(g.httpOut, "Cache-control: no-cache\r\n");
321 }
322
323 if( blob_size(&extraHeader)>0 ){
324
+17 -1
--- src/etag.c
+++ src/etag.c
@@ -173,10 +173,26 @@
173173
cgi_set_status(304, "Not Modified");
174174
cgi_reply();
175175
db_close(0);
176176
fossil_exit(0);
177177
}
178
+
179
+/*
180
+** If the output is determined purely by hash parameter and the hash
181
+** is long enough to be invariant, then set the g.isConst flag, indicating
182
+** that the output will never change.
183
+*/
184
+void etag_check_for_invariant_name(const char *zHash){
185
+ size_t nHash = strlen(zHash);
186
+ if( nHash<HNAME_MIN ){
187
+ return; /* Name is too short */
188
+ }
189
+ if( !validate16(zHash, (int)nHash) ){
190
+ return; /* Name is not pure hex */
191
+ }
192
+ g.isConst = 1; /* A long hex identifier must be a unique hash */
193
+}
178194
179195
/*
180196
** Accept a new Last-Modified time. This routine should be called by
181197
** page generators that know a valid last-modified time. This routine
182198
** might generate a 304 Not Modified reply and exit(), never returning.
@@ -212,11 +228,11 @@
212228
}
213229
214230
/* Return the ETag, if there is one.
215231
*/
216232
const char *etag_tag(void){
217
- return zETag;
233
+ return g.isConst ? "" : zETag;
218234
}
219235
220236
/* Return the recommended max-age
221237
*/
222238
int etag_maxage(void){
223239
--- src/etag.c
+++ src/etag.c
@@ -173,10 +173,26 @@
173 cgi_set_status(304, "Not Modified");
174 cgi_reply();
175 db_close(0);
176 fossil_exit(0);
177 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
179 /*
180 ** Accept a new Last-Modified time. This routine should be called by
181 ** page generators that know a valid last-modified time. This routine
182 ** might generate a 304 Not Modified reply and exit(), never returning.
@@ -212,11 +228,11 @@
212 }
213
214 /* Return the ETag, if there is one.
215 */
216 const char *etag_tag(void){
217 return zETag;
218 }
219
220 /* Return the recommended max-age
221 */
222 int etag_maxage(void){
223
--- src/etag.c
+++ src/etag.c
@@ -173,10 +173,26 @@
173 cgi_set_status(304, "Not Modified");
174 cgi_reply();
175 db_close(0);
176 fossil_exit(0);
177 }
178
179 /*
180 ** If the output is determined purely by hash parameter and the hash
181 ** is long enough to be invariant, then set the g.isConst flag, indicating
182 ** that the output will never change.
183 */
184 void etag_check_for_invariant_name(const char *zHash){
185 size_t nHash = strlen(zHash);
186 if( nHash<HNAME_MIN ){
187 return; /* Name is too short */
188 }
189 if( !validate16(zHash, (int)nHash) ){
190 return; /* Name is not pure hex */
191 }
192 g.isConst = 1; /* A long hex identifier must be a unique hash */
193 }
194
195 /*
196 ** Accept a new Last-Modified time. This routine should be called by
197 ** page generators that know a valid last-modified time. This routine
198 ** might generate a 304 Not Modified reply and exit(), never returning.
@@ -212,11 +228,11 @@
228 }
229
230 /* Return the ETag, if there is one.
231 */
232 const char *etag_tag(void){
233 return g.isConst ? "" : zETag;
234 }
235
236 /* Return the recommended max-age
237 */
238 int etag_maxage(void){
239
+3
--- src/tar.c
+++ src/tar.c
@@ -774,10 +774,13 @@
774774
nRid = strlen(zRid);
775775
zInclude = P("in");
776776
if( zInclude ) pInclude = glob_create(zInclude);
777777
zExclude = P("ex");
778778
if( zExclude ) pExclude = glob_create(zExclude);
779
+ if( zInclude==0 && zExclude==0 ){
780
+ etag_check_for_invariant_name(z);
781
+ }
779782
nName = strlen(zName);
780783
if( nName>7 && fossil_strcmp(&zName[nName-7], ".tar.gz")==0 ){
781784
/* Special case: Remove the ".tar.gz" suffix. */
782785
nName -= 7;
783786
zName[nName] = 0;
784787
--- src/tar.c
+++ src/tar.c
@@ -774,10 +774,13 @@
774 nRid = strlen(zRid);
775 zInclude = P("in");
776 if( zInclude ) pInclude = glob_create(zInclude);
777 zExclude = P("ex");
778 if( zExclude ) pExclude = glob_create(zExclude);
 
 
 
779 nName = strlen(zName);
780 if( nName>7 && fossil_strcmp(&zName[nName-7], ".tar.gz")==0 ){
781 /* Special case: Remove the ".tar.gz" suffix. */
782 nName -= 7;
783 zName[nName] = 0;
784
--- src/tar.c
+++ src/tar.c
@@ -774,10 +774,13 @@
774 nRid = strlen(zRid);
775 zInclude = P("in");
776 if( zInclude ) pInclude = glob_create(zInclude);
777 zExclude = P("ex");
778 if( zExclude ) pExclude = glob_create(zExclude);
779 if( zInclude==0 && zExclude==0 ){
780 etag_check_for_invariant_name(z);
781 }
782 nName = strlen(zName);
783 if( nName>7 && fossil_strcmp(&zName[nName-7], ".tar.gz")==0 ){
784 /* Special case: Remove the ".tar.gz" suffix. */
785 nName -= 7;
786 zName[nName] = 0;
787
+3
--- src/zip.c
+++ src/zip.c
@@ -940,10 +940,13 @@
940940
nRid = strlen(zRid);
941941
zInclude = P("in");
942942
if( zInclude ) pInclude = glob_create(zInclude);
943943
zExclude = P("ex");
944944
if( zExclude ) pExclude = glob_create(zExclude);
945
+ if( zInclude==0 && zExclude==0 ){
946
+ etag_check_for_invariant_name(z);
947
+ }
945948
if( eType==ARCHIVE_ZIP
946949
&& nName>4
947950
&& fossil_strcmp(&zName[nName-4], ".zip")==0
948951
){
949952
/* Special case: Remove the ".zip" suffix. */
950953
--- src/zip.c
+++ src/zip.c
@@ -940,10 +940,13 @@
940 nRid = strlen(zRid);
941 zInclude = P("in");
942 if( zInclude ) pInclude = glob_create(zInclude);
943 zExclude = P("ex");
944 if( zExclude ) pExclude = glob_create(zExclude);
 
 
 
945 if( eType==ARCHIVE_ZIP
946 && nName>4
947 && fossil_strcmp(&zName[nName-4], ".zip")==0
948 ){
949 /* Special case: Remove the ".zip" suffix. */
950
--- src/zip.c
+++ src/zip.c
@@ -940,10 +940,13 @@
940 nRid = strlen(zRid);
941 zInclude = P("in");
942 if( zInclude ) pInclude = glob_create(zInclude);
943 zExclude = P("ex");
944 if( zExclude ) pExclude = glob_create(zExclude);
945 if( zInclude==0 && zExclude==0 ){
946 etag_check_for_invariant_name(z);
947 }
948 if( eType==ARCHIVE_ZIP
949 && nName>4
950 && fossil_strcmp(&zName[nName-4], ".zip")==0
951 ){
952 /* Special case: Remove the ".zip" suffix. */
953

Keyboard Shortcuts

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