Ensure that we set a text/plain mimetype when a server delivers data with no mime_type and requested no sniffing.

Bug: 932767
Change-Id: I83a1af0cd2ac1626492624dbfd6b6010fc70ca0a
Reviewed-on: https://chromium-review.googlesource.com/c/1476176
Reviewed-by: Clark DuVall <cduvall@chromium.org>
Commit-Queue: John Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#632880}
diff --git a/content/browser/loader/loader_browsertest.cc b/content/browser/loader/loader_browsertest.cc
index 9c7dcc7..4fc86bc 100644
--- a/content/browser/loader/loader_browsertest.cc
+++ b/content/browser/loader/loader_browsertest.cc
@@ -153,6 +153,7 @@
   CheckTitleTest(
       net::URLRequestMockHTTPJob::GetMockUrl("content-sniffer-test0.html"),
       "Content Sniffer Test 0");
+  EXPECT_EQ("text/html", shell()->web_contents()->GetContentsMimeType());
 }
 
 IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, RespectNoSniffDirective) {
@@ -162,16 +163,18 @@
 
   CheckTitleTest(net::URLRequestMockHTTPJob::GetMockUrl("nosniff-test.html"),
                  "mock.http/nosniff-test.html");
+  EXPECT_EQ("text/plain", shell()->web_contents()->GetContentsMimeType());
 }
 
 IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, DoNotSniffHTMLFromTextPlain) {
-  // Covered by URLLoaderTest.DoNotSniffHTMLFromTextPlain.
+  // Covered by URLLoaderTest.SniffTextPlainDoesNotResultInHTML.
   if (base::FeatureList::IsEnabled(network::features::kNetworkService))
     return;
 
   CheckTitleTest(
       net::URLRequestMockHTTPJob::GetMockUrl("content-sniffer-test1.html"),
       "mock.http/content-sniffer-test1.html");
+  EXPECT_EQ("text/plain", shell()->web_contents()->GetContentsMimeType());
 }
 
 IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, DoNotSniffHTMLFromImageGIF) {
@@ -182,6 +185,7 @@
   CheckTitleTest(
       net::URLRequestMockHTTPJob::GetMockUrl("content-sniffer-test2.html"),
       "mock.http/content-sniffer-test2.html");
+  EXPECT_EQ("image/gif", shell()->web_contents()->GetContentsMimeType());
 }
 
 IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, SniffNoContentTypeNoData) {
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index 56bfbba..703072d4 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -816,9 +816,15 @@
       corb_analyzer_->LogAllowedResponse();
     }
   }
-  if ((options_ & mojom::kURLLoadOptionSniffMimeType) &&
-      ShouldSniffContent(url_request_.get(), response_.get())) {
-    is_more_mime_sniffing_needed_ = true;
+  if ((options_ & mojom::kURLLoadOptionSniffMimeType)) {
+    if (ShouldSniffContent(url_request_.get(), response_.get())) {
+      is_more_mime_sniffing_needed_ = true;
+    } else if (response_->head.mime_type.empty()) {
+      // Ugg.  The server told us not to sniff the content but didn't give us
+      // a mime type.  What's a browser to do?  Turns out, we're supposed to
+      // treat the response as "text/plain".  This is the most secure option.
+      response_->head.mime_type.assign("text/plain");
+    }
   }
   if (!is_more_mime_sniffing_needed_ && !is_more_corb_sniffing_needed_) {
     // Treat feed types as text/plain.
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc
index ec496847..2e73c43 100644
--- a/services/network/url_loader_unittest.cc
+++ b/services/network/url_loader_unittest.cc
@@ -829,7 +829,7 @@
   set_sniff();
   EXPECT_EQ(net::OK, Load(test_server()->GetURL("/nosniff-test.html")));
   EXPECT_FALSE(did_mime_sniff());
-  ASSERT_TRUE(mime_type().empty());
+  ASSERT_EQ(std::string("text/plain"), mime_type());
 }
 
 TEST_F(URLLoaderTest, SniffTextPlainDoesNotResultInHTML) {