Fossil SCM

Based on discussions in [forum:f60dece061c364d1|forum thread f60dece061c364d1], (A) re-add the charset=utf-8 for text/* mimetypes, (B) extend the set of gzip-compressible mimetypes (e.g. JSON, wasm, tcl, tar), and (C) refactor (B)'s impl so that adding new types does not add a performance hit (it's faster now for most mimetypes).

stephan 2022-06-08 07:36 pikchrshow-wasm
Commit 86db2d94c60e23845362e5793280583223405f79c505f834c8aa13a60db9d9c5
1 file changed +47 -4
+47 -4
--- src/cgi.c
+++ src/cgi.c
@@ -330,13 +330,36 @@
330330
** Return true if the response should be sent with Content-Encoding: gzip.
331331
*/
332332
static int is_gzippable(void){
333333
if( g.fNoHttpCompress ) return 0;
334334
if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
335
- return strncmp(zContentType, "text/", 5)==0
336
- || sqlite3_strglob("application/*xml", zContentType)==0
337
- || sqlite3_strglob("application/*javascript", zContentType)==0;
335
+ /* Maintenance note: this oddball structure is intended to make
336
+ ** adding new mimetypes to this list less of a performance hit than
337
+ ** doing a strcmp/glob over a growing set of compressible types. */
338
+ switch(zContentType ? *zContentType : 0){
339
+ case (int)'a':
340
+ if(0==strncmp("application/",zContentType,12)){
341
+ const char * z = &zContentType[12];
342
+ switch(*z){
343
+ case (int)'j':
344
+ return fossil_strcmp("javascript", z)==0
345
+ || fossil_strcmp("json", z)==0;
346
+ case (int)'w': return fossil_strcmp("wasm", z)==0;
347
+ case (int)'x':
348
+ return fossil_strcmp("x-tcl", z)==0
349
+ || fossil_strcmp("x-tar", z)==0;
350
+ default:
351
+ return sqlite3_strglob("*xml", z)==0;
352
+ }
353
+ }
354
+ break;
355
+ case (int)'i':
356
+ return fossil_strcmp(zContentType, "image/svg+xml")==0;
357
+ case (int)'t':
358
+ return fossil_strncmp(zContentType, "text/", 5)==0;
359
+ }
360
+ return 0;
338361
}
339362
340363
341364
/*
342365
** The following routines read or write content from/to the wire for
@@ -419,10 +442,29 @@
419442
if( !g.httpUseSSL ){
420443
fflush(g.httpOut);
421444
}
422445
}
423446
447
+/*
448
+** Given a Content-Type value, returns a string suitable for appending
449
+** to the Content-Type header for adding (or not) the "; charset=..."
450
+** part. It returns an empty string for most types or if zContentType
451
+** is NULL.
452
+**
453
+** See forum post f60dece061c364d1 for the discussions which lead to
454
+** this. Previously we always appended the charset, but WASM loaders
455
+** are pedantic and refuse to load any responses which have a
456
+** charset. Also, adding a charset is not strictly appropriate for
457
+** most types (and not required for many others which may ostensibly
458
+** benefit from one, as detailed in that forum post).
459
+*/
460
+static const char * content_type_charset(const char *zContentType){
461
+ if(zContentType!=0){
462
+ if(0==strncmp(zContentType,"text/",5)) return "; charset=utf-8";
463
+ }
464
+ return "";
465
+}
424466
425467
/*
426468
** Generate the reply to a web request. The output might be an
427469
** full HTTP response, or a CGI response, depending on how things have
428470
** be set up.
@@ -493,11 +535,12 @@
493535
494536
/* Content intended for logged in users should only be cached in
495537
** the browser, not some shared location.
496538
*/
497539
if( iReplyStatus!=304 ) {
498
- blob_appendf(&hdr, "Content-Type: %s\r\n", zContentType);
540
+ blob_appendf(&hdr, "Content-Type: %s%s\r\n", zContentType,
541
+ content_type_charset(zContentType));
499542
if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
500543
cgi_combine_header_and_body();
501544
blob_compress(&cgiContent[0], &cgiContent[0]);
502545
}
503546
504547
--- src/cgi.c
+++ src/cgi.c
@@ -330,13 +330,36 @@
330 ** Return true if the response should be sent with Content-Encoding: gzip.
331 */
332 static int is_gzippable(void){
333 if( g.fNoHttpCompress ) return 0;
334 if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
335 return strncmp(zContentType, "text/", 5)==0
336 || sqlite3_strglob("application/*xml", zContentType)==0
337 || sqlite3_strglob("application/*javascript", zContentType)==0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338 }
339
340
341 /*
342 ** The following routines read or write content from/to the wire for
@@ -419,10 +442,29 @@
419 if( !g.httpUseSSL ){
420 fflush(g.httpOut);
421 }
422 }
423
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
424
425 /*
426 ** Generate the reply to a web request. The output might be an
427 ** full HTTP response, or a CGI response, depending on how things have
428 ** be set up.
@@ -493,11 +535,12 @@
493
494 /* Content intended for logged in users should only be cached in
495 ** the browser, not some shared location.
496 */
497 if( iReplyStatus!=304 ) {
498 blob_appendf(&hdr, "Content-Type: %s\r\n", zContentType);
 
499 if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
500 cgi_combine_header_and_body();
501 blob_compress(&cgiContent[0], &cgiContent[0]);
502 }
503
504
--- src/cgi.c
+++ src/cgi.c
@@ -330,13 +330,36 @@
330 ** Return true if the response should be sent with Content-Encoding: gzip.
331 */
332 static int is_gzippable(void){
333 if( g.fNoHttpCompress ) return 0;
334 if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
335 /* Maintenance note: this oddball structure is intended to make
336 ** adding new mimetypes to this list less of a performance hit than
337 ** doing a strcmp/glob over a growing set of compressible types. */
338 switch(zContentType ? *zContentType : 0){
339 case (int)'a':
340 if(0==strncmp("application/",zContentType,12)){
341 const char * z = &zContentType[12];
342 switch(*z){
343 case (int)'j':
344 return fossil_strcmp("javascript", z)==0
345 || fossil_strcmp("json", z)==0;
346 case (int)'w': return fossil_strcmp("wasm", z)==0;
347 case (int)'x':
348 return fossil_strcmp("x-tcl", z)==0
349 || fossil_strcmp("x-tar", z)==0;
350 default:
351 return sqlite3_strglob("*xml", z)==0;
352 }
353 }
354 break;
355 case (int)'i':
356 return fossil_strcmp(zContentType, "image/svg+xml")==0;
357 case (int)'t':
358 return fossil_strncmp(zContentType, "text/", 5)==0;
359 }
360 return 0;
361 }
362
363
364 /*
365 ** The following routines read or write content from/to the wire for
@@ -419,10 +442,29 @@
442 if( !g.httpUseSSL ){
443 fflush(g.httpOut);
444 }
445 }
446
447 /*
448 ** Given a Content-Type value, returns a string suitable for appending
449 ** to the Content-Type header for adding (or not) the "; charset=..."
450 ** part. It returns an empty string for most types or if zContentType
451 ** is NULL.
452 **
453 ** See forum post f60dece061c364d1 for the discussions which lead to
454 ** this. Previously we always appended the charset, but WASM loaders
455 ** are pedantic and refuse to load any responses which have a
456 ** charset. Also, adding a charset is not strictly appropriate for
457 ** most types (and not required for many others which may ostensibly
458 ** benefit from one, as detailed in that forum post).
459 */
460 static const char * content_type_charset(const char *zContentType){
461 if(zContentType!=0){
462 if(0==strncmp(zContentType,"text/",5)) return "; charset=utf-8";
463 }
464 return "";
465 }
466
467 /*
468 ** Generate the reply to a web request. The output might be an
469 ** full HTTP response, or a CGI response, depending on how things have
470 ** be set up.
@@ -493,11 +535,12 @@
535
536 /* Content intended for logged in users should only be cached in
537 ** the browser, not some shared location.
538 */
539 if( iReplyStatus!=304 ) {
540 blob_appendf(&hdr, "Content-Type: %s%s\r\n", zContentType,
541 content_type_charset(zContentType));
542 if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
543 cgi_combine_header_and_body();
544 blob_compress(&cgiContent[0], &cgiContent[0]);
545 }
546
547

Keyboard Shortcuts

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