31
31
#include " pagespeed/kernel/base/statistics.h"
32
32
#include " pagespeed/kernel/base/string.h"
33
33
#include " pagespeed/kernel/base/string_util.h"
34
- #include " pagespeed/kernel/base/string_writer.h"
35
34
#include " pagespeed/kernel/base/timer.h"
36
35
#include " pagespeed/kernel/cache/cache_interface.h"
36
+ #include " pagespeed/kernel/http/content_type.h"
37
37
#include " pagespeed/kernel/http/google_url.h"
38
38
#include " pagespeed/kernel/http/http_names.h"
39
39
#include " pagespeed/kernel/http/response_headers.h"
@@ -229,7 +229,17 @@ class HTTPCacheCallback : public CacheInterface::Callback {
229
229
headers->IsProxyCacheable (callback_->req_properties (),
230
230
callback_->RespectVaryOnResources (),
231
231
ResponseHeaders::kHasValidator )) {
232
- callback_->fallback_http_value ()->Link (callback_->http_value ());
232
+ ResponseHeaders fallback_headers;
233
+ if (callback_->request_context ()->accepts_gzip () ||
234
+ !callback_->http_value ()->ExtractHeaders (&fallback_headers,
235
+ handler_) ||
236
+ !InflatingFetch::UnGzipValueIfCompressed (
237
+ *callback_->http_value (), &fallback_headers,
238
+ callback_->fallback_http_value (), handler_)) {
239
+ // If we don't need to unzip, or can't unzip, then just
240
+ // link the value and fallback together.
241
+ callback_->fallback_http_value ()->Link (callback_->http_value ());
242
+ }
233
243
}
234
244
}
235
245
}
@@ -249,10 +259,14 @@ class HTTPCacheCallback : public CacheInterface::Callback {
249
259
if (result_.status != HTTPCache::kFound ) {
250
260
headers->Clear ();
251
261
callback_->http_value ()->Clear ();
252
- }
253
- if (!callback_->request_context ()->accepts_gzip ()) {
254
- HTTPValue* http_value = callback_->http_value ();
255
- InflatingFetch::UnGzipValueIfCompressed (http_value, headers, handler_);
262
+ } else if (!callback_->request_context ()->accepts_gzip () &&
263
+ headers->IsGzipped ()) {
264
+ HTTPValue new_value;
265
+ GoogleString inflated;
266
+ if (InflatingFetch::UnGzipValueIfCompressed (
267
+ *callback_->http_value (), headers, &new_value, handler_)) {
268
+ callback_->http_value ()->Link (&new_value);
269
+ }
256
270
}
257
271
start_ms_ = now_ms;
258
272
start_us_ = now_us;
@@ -380,7 +394,8 @@ HTTPValue* HTTPCache::ApplyHeaderChangesForPut(
380
394
return value;
381
395
}
382
396
383
- void HTTPCache::PutInternal (const GoogleString& key,
397
+ void HTTPCache::PutInternal (bool preserve_response_headers,
398
+ const GoogleString& key,
384
399
const GoogleString& fragment, int64 start_us,
385
400
HTTPValue* value, ResponseHeaders* response_headers,
386
401
MessageHandler* handler) {
@@ -394,13 +409,23 @@ void HTTPCache::PutInternal(const GoogleString& key,
394
409
if (!value->Empty () && compression_level_ != 0 ) {
395
410
const ContentType* type = response_headers->DetermineContentType ();
396
411
if ((type != NULL ) && type->IsCompressible () &&
397
- !response_headers->IsGzipped () &&
398
- InflatingFetch::GzipValue (compression_level_, value, &compressed_value,
399
- response_headers, handler)) {
400
- // The resource is text (js, css, html, svg, etc.), and not previously
401
- // compressed, so we'll compress it and stick the new compressed version
402
- // in the cache.
403
- value = &compressed_value;
412
+ !response_headers->IsGzipped ()) {
413
+ ResponseHeaders* headers_to_gzip = response_headers;
414
+ ResponseHeaders headers_copy;
415
+ if (preserve_response_headers) {
416
+ headers_copy.CopyFrom (*response_headers);
417
+ headers_to_gzip = &headers_copy;
418
+ }
419
+ headers_to_gzip->ComputeCaching ();
420
+
421
+ if (InflatingFetch::GzipValue (compression_level_, *value,
422
+ &compressed_value, headers_to_gzip,
423
+ handler)) {
424
+ // The resource is text (js, css, html, svg, etc.), and not previously
425
+ // compressed, so we'll compress it and stick the new compressed version
426
+ // in the cache.
427
+ value = &compressed_value;
428
+ }
404
429
}
405
430
}
406
431
// TODO(jcrowell): prevent the unzip-rezip flow when sending compressed data
@@ -442,7 +467,8 @@ void HTTPCache::Put(const GoogleString& key, const GoogleString& fragment,
442
467
start_us, NULL , &headers, value, handler);
443
468
// Put into underlying cache.
444
469
if (new_value != NULL ) {
445
- PutInternal (key, fragment, start_us, new_value, &headers, handler);
470
+ PutInternal (false /* preserve_response_headers */ ,
471
+ key, fragment, start_us, new_value, &headers, handler);
446
472
if (cache_inserts_ != NULL ) {
447
473
cache_inserts_->Add (1 );
448
474
}
@@ -478,7 +504,8 @@ void HTTPCache::Put(const GoogleString& key, const GoogleString& fragment,
478
504
ApplyHeaderChangesForPut (start_us, &content, headers, NULL , handler));
479
505
// Put into underlying cache.
480
506
if (value.get () != NULL ) {
481
- PutInternal (key, fragment, start_us, value.get (), headers, handler);
507
+ PutInternal (true /* preserve_response_headers */ ,
508
+ key, fragment, start_us, value.get (), headers, handler);
482
509
if (cache_inserts_ != NULL ) {
483
510
cache_inserts_->Add (1 );
484
511
}
0 commit comments