Fossil SCM
Send gzipped HTTP responses to clients that support it.
Commit
3f4b5d32f17b8e46f21faf766c370dfd5e312f8a
Parent
b78e07491c59e8e…
1 file changed
+28
-1
+28
-1
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -270,10 +270,20 @@ | ||
| 270 | 270 | } |
| 271 | 271 | |
| 272 | 272 | return 0; |
| 273 | 273 | } |
| 274 | 274 | #endif |
| 275 | + | |
| 276 | +/* | |
| 277 | +** Return true if the response should be sent with Content-Encoding: gzip. | |
| 278 | +*/ | |
| 279 | +static int is_gzippable(void){ | |
| 280 | + if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0; | |
| 281 | + return strncmp(zContentType, "text/", 5)==0 | |
| 282 | + || strglob("application/*xml", zContentType) | |
| 283 | + || strglob("application/*javascript", zContentType); | |
| 284 | +} | |
| 275 | 285 | |
| 276 | 286 | /* |
| 277 | 287 | ** Do a normal HTTP reply |
| 278 | 288 | */ |
| 279 | 289 | void cgi_reply(void){ |
| @@ -348,10 +358,25 @@ | ||
| 348 | 358 | cgi_combine_header_and_body(); |
| 349 | 359 | blob_compress(&cgiContent[0], &cgiContent[0]); |
| 350 | 360 | } |
| 351 | 361 | |
| 352 | 362 | if( iReplyStatus != 304 ) { |
| 363 | + if( is_gzippable() ){ | |
| 364 | + int i; | |
| 365 | + /* Using an arbitrary constant argument for gzip_begin() so the same | |
| 366 | + ** input always results in the same gzipped output. | |
| 367 | + **/ | |
| 368 | + gzip_begin(1); | |
| 369 | + for( i=0; i<2; i++ ){ | |
| 370 | + int size = blob_size(&cgiContent[i]); | |
| 371 | + if( size>0 ) gzip_step(blob_buffer(&cgiContent[i]), size); | |
| 372 | + blob_reset(&cgiContent[i]); | |
| 373 | + } | |
| 374 | + gzip_finish(&cgiContent[0]); | |
| 375 | + fprintf(g.httpOut, "Content-Encoding: gzip\r\n"); | |
| 376 | + fprintf(g.httpOut, "Vary: Accept-Encoding\r\n"); | |
| 377 | + } | |
| 353 | 378 | total_size = blob_size(&cgiContent[0]) + blob_size(&cgiContent[1]); |
| 354 | 379 | fprintf(g.httpOut, "Content-Length: %d\r\n", total_size); |
| 355 | 380 | }else{ |
| 356 | 381 | total_size = 0; |
| 357 | 382 | } |
| @@ -1302,11 +1327,13 @@ | ||
| 1302 | 1327 | while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; } |
| 1303 | 1328 | zVal[i] = 0; |
| 1304 | 1329 | for(i=0; zFieldName[i]; i++){ |
| 1305 | 1330 | zFieldName[i] = fossil_tolower(zFieldName[i]); |
| 1306 | 1331 | } |
| 1307 | - if( fossil_strcmp(zFieldName,"content-length:")==0 ){ | |
| 1332 | + if( fossil_strcmp(zFieldName,"accept-encoding:")==0 ){ | |
| 1333 | + cgi_setenv("HTTP_ACCEPT_ENCODING", zVal); | |
| 1334 | + }else if( fossil_strcmp(zFieldName,"content-length:")==0 ){ | |
| 1308 | 1335 | cgi_setenv("CONTENT_LENGTH", zVal); |
| 1309 | 1336 | }else if( fossil_strcmp(zFieldName,"content-type:")==0 ){ |
| 1310 | 1337 | cgi_setenv("CONTENT_TYPE", zVal); |
| 1311 | 1338 | }else if( fossil_strcmp(zFieldName,"cookie:")==0 ){ |
| 1312 | 1339 | cgi_setenv("HTTP_COOKIE", zVal); |
| 1313 | 1340 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -270,10 +270,20 @@ | |
| 270 | } |
| 271 | |
| 272 | return 0; |
| 273 | } |
| 274 | #endif |
| 275 | |
| 276 | /* |
| 277 | ** Do a normal HTTP reply |
| 278 | */ |
| 279 | void cgi_reply(void){ |
| @@ -348,10 +358,25 @@ | |
| 348 | cgi_combine_header_and_body(); |
| 349 | blob_compress(&cgiContent[0], &cgiContent[0]); |
| 350 | } |
| 351 | |
| 352 | if( iReplyStatus != 304 ) { |
| 353 | total_size = blob_size(&cgiContent[0]) + blob_size(&cgiContent[1]); |
| 354 | fprintf(g.httpOut, "Content-Length: %d\r\n", total_size); |
| 355 | }else{ |
| 356 | total_size = 0; |
| 357 | } |
| @@ -1302,11 +1327,13 @@ | |
| 1302 | while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; } |
| 1303 | zVal[i] = 0; |
| 1304 | for(i=0; zFieldName[i]; i++){ |
| 1305 | zFieldName[i] = fossil_tolower(zFieldName[i]); |
| 1306 | } |
| 1307 | if( fossil_strcmp(zFieldName,"content-length:")==0 ){ |
| 1308 | cgi_setenv("CONTENT_LENGTH", zVal); |
| 1309 | }else if( fossil_strcmp(zFieldName,"content-type:")==0 ){ |
| 1310 | cgi_setenv("CONTENT_TYPE", zVal); |
| 1311 | }else if( fossil_strcmp(zFieldName,"cookie:")==0 ){ |
| 1312 | cgi_setenv("HTTP_COOKIE", zVal); |
| 1313 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -270,10 +270,20 @@ | |
| 270 | } |
| 271 | |
| 272 | return 0; |
| 273 | } |
| 274 | #endif |
| 275 | |
| 276 | /* |
| 277 | ** Return true if the response should be sent with Content-Encoding: gzip. |
| 278 | */ |
| 279 | static int is_gzippable(void){ |
| 280 | if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0; |
| 281 | return strncmp(zContentType, "text/", 5)==0 |
| 282 | || strglob("application/*xml", zContentType) |
| 283 | || strglob("application/*javascript", zContentType); |
| 284 | } |
| 285 | |
| 286 | /* |
| 287 | ** Do a normal HTTP reply |
| 288 | */ |
| 289 | void cgi_reply(void){ |
| @@ -348,10 +358,25 @@ | |
| 358 | cgi_combine_header_and_body(); |
| 359 | blob_compress(&cgiContent[0], &cgiContent[0]); |
| 360 | } |
| 361 | |
| 362 | if( iReplyStatus != 304 ) { |
| 363 | if( is_gzippable() ){ |
| 364 | int i; |
| 365 | /* Using an arbitrary constant argument for gzip_begin() so the same |
| 366 | ** input always results in the same gzipped output. |
| 367 | **/ |
| 368 | gzip_begin(1); |
| 369 | for( i=0; i<2; i++ ){ |
| 370 | int size = blob_size(&cgiContent[i]); |
| 371 | if( size>0 ) gzip_step(blob_buffer(&cgiContent[i]), size); |
| 372 | blob_reset(&cgiContent[i]); |
| 373 | } |
| 374 | gzip_finish(&cgiContent[0]); |
| 375 | fprintf(g.httpOut, "Content-Encoding: gzip\r\n"); |
| 376 | fprintf(g.httpOut, "Vary: Accept-Encoding\r\n"); |
| 377 | } |
| 378 | total_size = blob_size(&cgiContent[0]) + blob_size(&cgiContent[1]); |
| 379 | fprintf(g.httpOut, "Content-Length: %d\r\n", total_size); |
| 380 | }else{ |
| 381 | total_size = 0; |
| 382 | } |
| @@ -1302,11 +1327,13 @@ | |
| 1327 | while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; } |
| 1328 | zVal[i] = 0; |
| 1329 | for(i=0; zFieldName[i]; i++){ |
| 1330 | zFieldName[i] = fossil_tolower(zFieldName[i]); |
| 1331 | } |
| 1332 | if( fossil_strcmp(zFieldName,"accept-encoding:")==0 ){ |
| 1333 | cgi_setenv("HTTP_ACCEPT_ENCODING", zVal); |
| 1334 | }else if( fossil_strcmp(zFieldName,"content-length:")==0 ){ |
| 1335 | cgi_setenv("CONTENT_LENGTH", zVal); |
| 1336 | }else if( fossil_strcmp(zFieldName,"content-type:")==0 ){ |
| 1337 | cgi_setenv("CONTENT_TYPE", zVal); |
| 1338 | }else if( fossil_strcmp(zFieldName,"cookie:")==0 ){ |
| 1339 | cgi_setenv("HTTP_COOKIE", zVal); |
| 1340 |