Explore emitting Cache-Control:immutable
diff --git a/net/instaweb/rewriter/css_combine_filter_test.cc b/net/instaweb/rewriter/css_combine_filter_test.cc
index 45599da..3858e38 100644
--- a/net/instaweb/rewriter/css_combine_filter_test.cc
+++ b/net/instaweb/rewriter/css_combine_filter_test.cc
@@ -2029,7 +2029,7 @@
       "Content-Type: text/css\r\n"
       "Date: Tue, 02 Feb 2010 18:51:26 GMT\r\n"
       "Expires: Wed, 02 Feb 2011 18:51:26 GMT\r\n"
-      "Cache-Control: max-age=31536000\r\n"
+      "Cache-Control: max-age=31536000,immutable\r\n"
       "Etag: W/\"0\"\r\n"
       "Last-Modified: Tue, 02 Feb 2010 18:51:26 GMT\r\n"
       "X-Original-Content-Length: 85\r\n"
diff --git a/net/instaweb/rewriter/rewrite_context_test.cc b/net/instaweb/rewriter/rewrite_context_test.cc
index 5cd67e2..5530757 100644
--- a/net/instaweb/rewriter/rewrite_context_test.cc
+++ b/net/instaweb/rewriter/rewrite_context_test.cc
@@ -1442,8 +1442,8 @@
     EXPECT_TRUE(FetchResource(
         kTestDomain, "ce", "test.css", "css", &content, &headers));
     EXPECT_EQ("", content);
-    EXPECT_STREQ("max-age=31536000",
-                 headers.Lookup1(HttpAttributes::kCacheControl));
+    EXPECT_TRUE(headers.HasValue(HttpAttributes::kCacheControl,
+                "max-age=31536000"));
   }
 }
 
@@ -1529,8 +1529,8 @@
         kTestDomain, "cf", "test.css", "css", &content, &headers));
     EXPECT_EQ("", content);  // Result is empty. That's fine.
     // And serves with full public 1year cache lifetime.
-    EXPECT_STREQ("max-age=31536000",
-                 headers.Lookup1(HttpAttributes::kCacheControl));
+    EXPECT_TRUE(headers.HasValue(HttpAttributes::kCacheControl,
+                "max-age=31536000"));
   }
 }
 
@@ -1797,11 +1797,13 @@
                               "css",
                               &content,
                               &headers));
-    EXPECT_EQ("a", content);
+    EXPECT_EQ("a", content);        
+    EXPECT_TRUE(headers.HasValue(HttpAttributes::kCacheControl,
+                "max-age=31536000"));
     EXPECT_STREQ(StringPrintf("max-age=%lld",
                               static_cast<long long int>(
                                   ServerContext::kGeneratedMaxAgeMs / 1000)),
-                 headers.Lookup1(HttpAttributes::kCacheControl));
+                 "max-age=31536000");
   }
 }
 
diff --git a/net/instaweb/rewriter/server_context.cc b/net/instaweb/rewriter/server_context.cc
index 3433a51..606bf2c 100644
--- a/net/instaweb/rewriter/server_context.cc
+++ b/net/instaweb/rewriter/server_context.cc
@@ -361,8 +361,9 @@
   }
 
   int64 now_ms = timer()->NowMs();
-  header->SetDateAndCaching(now_ms, kGeneratedMaxAgeMs, suffix);
-
+  GoogleString s_suffix(suffix.as_string());
+  StrAppend(&s_suffix, ",immutable");
+  header->SetDateAndCaching(now_ms, kGeneratedMaxAgeMs, s_suffix);
   // While PageSpeed claims the "Vary" header is needed to avoid proxy cache
   // issues for clients where some accept gzipped content and some don't, it
   // should not be done here.  It should instead be done by whatever code is
@@ -375,7 +376,6 @@
   // we sign URLs, there is no reason to have a unique signature in
   // the ETag.
   header->Replace(HttpAttributes::kEtag, kResourceEtagValue);
-
   // TODO(jmarantz): Replace last-modified headers by default?
   ConstStringStarVector v;
   if (!header->Lookup(HttpAttributes::kLastModified, &v)) {
diff --git a/net/instaweb/rewriter/server_context_test.cc b/net/instaweb/rewriter/server_context_test.cc
index dd0ca19..b8a8031 100644
--- a/net/instaweb/rewriter/server_context_test.cc
+++ b/net/instaweb/rewriter/server_context_test.cc
@@ -1588,8 +1588,9 @@
   resources_.push_back(implicit_public_100_);
   resources_.push_back(implicit_public_200_);
   server_context()->ApplyInputCacheControl(resources_, &response_headers_);
-  EXPECT_STREQ(LongCacheTtl(),
-               response_headers_.Lookup1(HttpAttributes::kCacheControl));
+  EXPECT_TRUE(response_headers_.HasValue(HttpAttributes::kCacheControl,
+                                         "max-age=31536000"));
+  EXPECT_STREQ(LongCacheTtl(), "max-age=31536000");
 }
 
 TEST_F(ServerContextCacheControlTest, ExplicitPublic) {
diff --git a/pagespeed/kernel/http/response_headers.cc b/pagespeed/kernel/http/response_headers.cc
index b893157..cfbe8a7 100644
--- a/pagespeed/kernel/http/response_headers.cc
+++ b/pagespeed/kernel/http/response_headers.cc
@@ -821,6 +821,9 @@
   if (HasValue(HttpAttributes::kCacheControl, "no-store")) {
     to_preserve += ", no-store";
   }
+  if (HasValue(HttpAttributes::kCacheControl, "immutable")) {
+    to_preserve += ", immutable";
+  }
 
   ConstStringStarVector cc_values;
   Lookup(HttpAttributes::kCacheControl, &cc_values);