// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/network/cross_origin_read_blocking.h"

#include <stddef.h>

#include <algorithm>
#include <set>
#include <string>
#include <unordered_set>
#include <vector>

#include "base/command_line.h"
#include "base/containers/flat_set.h"
#include "base/feature_list.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/stl_util.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "net/base/mime_sniffer.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/http/http_response_headers.h"
#include "services/network/cross_origin_resource_policy.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_response_info.h"
#include "services/network/public/mojom/network_context.mojom.h"

using base::StringPiece;
using MimeType = network::CrossOriginReadBlocking::MimeType;
using SniffingResult = network::CrossOriginReadBlocking::SniffingResult;

namespace network {

namespace {

// MIME types
const char kTextHtml[] = "text/html";
const char kTextXml[] = "text/xml";
const char kAppXml[] = "application/xml";
const char kAppJson[] = "application/json";
const char kImageSvg[] = "image/svg+xml";
const char kDashVideo[] = "application/dash+xml";  // https://crbug.com/947498
const char kTextJson[] = "text/json";
const char kTextPlain[] = "text/plain";

// Javascript MIME type suffixes for use in CORB protection logging. See also
// https://mimesniff.spec.whatwg.org/#javascript-mime-type.
const char* kJavaScriptSuffixes[] = {"ecmascript",
                                     "javascript",
                                     "x-ecmascript",
                                     "x-javascript",
                                     "javascript1.0",
                                     "javascript1.1",
                                     "javascript1.2",
                                     "javascript1.3",
                                     "javascript1.4",
                                     "javascript1.5",
                                     "jscript",
                                     "livescript",
                                     "js",
                                     "x-js"};

// TODO(lukasza): Remove kJsonProtobuf once this MIME type is not used in
// practice.  See also https://crbug.com/826756#c3
const char kJsonProtobuf[] = "application/json+protobuf";

// MIME type suffixes
const char kJsonSuffix[] = "+json";
const char kXmlSuffix[] = "+xml";

void AdvancePastWhitespace(StringPiece* data) {
  size_t offset = data->find_first_not_of(" \t\r\n");
  if (offset == base::StringPiece::npos) {
    // |data| was entirely whitespace.
    data->clear();
  } else {
    data->remove_prefix(offset);
  }
}

// Returns kYes if |data| starts with one of the string patterns in
// |signatures|, kMaybe if |data| is a prefix of one of the patterns in
// |signatures|, and kNo otherwise.
//
// When kYes is returned, the matching prefix is erased from |data|.
SniffingResult MatchesSignature(StringPiece* data,
                                const StringPiece signatures[],
                                size_t arr_size,
                                base::CompareCase compare_case) {
  for (size_t i = 0; i < arr_size; ++i) {
    if (signatures[i].length() <= data->length()) {
      if (base::StartsWith(*data, signatures[i], compare_case)) {
        // When |signatures[i]| is a prefix of |data|, it constitutes a match.
        // Strip the matching characters, and return.
        data->remove_prefix(signatures[i].length());
        return CrossOriginReadBlocking::kYes;
      }
    } else {
      if (base::StartsWith(signatures[i], *data, compare_case)) {
        // When |data| is a prefix of |signatures[i]|, that means that
        // subsequent bytes in the stream could cause a match to occur.
        return CrossOriginReadBlocking::kMaybe;
      }
    }
  }
  return CrossOriginReadBlocking::kNo;
}

size_t FindFirstJavascriptLineTerminator(const base::StringPiece& hay,
                                         size_t pos) {
  // https://www.ecma-international.org/ecma-262/8.0/index.html#prod-LineTerminator
  // defines LineTerminator ::= <LF> | <CR> | <LS> | <PS>.
  //
  // https://www.ecma-international.org/ecma-262/8.0/index.html#sec-line-terminators
  // defines <LF>, <CR>, <LS> ::= "\u2028", <PS> ::= "\u2029".
  //
  // In UTF8 encoding <LS> is 0xE2 0x80 0xA8 and <PS> is 0xE2 0x80 0xA9.
  while (true) {
    pos = hay.find_first_of("\n\r\xe2", pos);
    if (pos == base::StringPiece::npos)
      break;

    if (hay[pos] != '\xe2') {
      DCHECK(hay[pos] == '\r' || hay[pos] == '\n');
      break;
    }

    // TODO(lukasza): Prevent matching 3 bytes that span/straddle 2 UTF8
    // characters.
    base::StringPiece substr = hay.substr(pos);
    if (substr.starts_with("\u2028") || substr.starts_with("\u2029"))
      break;

    pos++;  // Skip the \xe2 character.
  }
  return pos;
}

// Checks if |data| starts with an HTML comment (i.e. with "<!-- ... -->").
// - If there is a valid, terminated comment then returns kYes.
// - If there is a start of a comment, but the comment is not completed (e.g.
//   |data| == "<!-" or |data| == "<!-- not terminated yet") then returns
//   kMaybe.
// - Returns kNo otherwise.
//
// Mutates |data| to advance past the comment when returning kYes.  Note that
// SingleLineHTMLCloseComment ECMAscript rule is taken into account which means
// that characters following an HTML comment are consumed up to the nearest line
// terminating character.
SniffingResult MaybeSkipHtmlComment(StringPiece* data) {
  constexpr StringPiece kStartString = "<!--";
  if (!data->starts_with(kStartString)) {
    if (kStartString.starts_with(*data))
      return CrossOriginReadBlocking::kMaybe;
    return CrossOriginReadBlocking::kNo;
  }

  constexpr StringPiece kEndString = "-->";
  size_t end_of_html_comment = data->find(kEndString, kStartString.length());
  if (end_of_html_comment == StringPiece::npos)
    return CrossOriginReadBlocking::kMaybe;
  end_of_html_comment += kEndString.length();

  // Skipping until the first line terminating character.  See
  // https://crbug.com/839945 for the motivation behind this.
  size_t end_of_line =
      FindFirstJavascriptLineTerminator(*data, end_of_html_comment);
  if (end_of_line == base::StringPiece::npos)
    return CrossOriginReadBlocking::kMaybe;

  // Found real end of the combined HTML/JS comment.
  data->remove_prefix(end_of_line);
  return CrossOriginReadBlocking::kYes;
}

// Removes headers that should be blocked in cross-origin case.
//
// Note that corbSanitizedResponse in https://fetch.spec.whatwg.org/#main-fetch
// has an empty list of headers, but the code below doesn't remove all the
// headers for improved user experience - for better error messages for CORS.
// See also https://github.com/whatwg/fetch/pull/686#issuecomment-383711732 and
// the http/tests/xmlhttprequest/origin-exact-matching/07.html layout test.
//
// Note that CORB doesn't block responses allowed through CORS - this means
// that the list of allowed headers below doesn't have to consider header
// names listed in the Access-Control-Expose-Headers header.
void BlockResponseHeaders(
    const scoped_refptr<net::HttpResponseHeaders>& headers) {
  DCHECK(headers);
  std::unordered_set<std::string> names_of_headers_to_remove;

  size_t it = 0;
  std::string name;
  std::string value;
  while (headers->EnumerateHeaderLines(&it, &name, &value)) {
    // Don't remove CORS headers - doing so would lead to incorrect error
    // messages for CORS-blocked responses (e.g. Blink would say "[...] No
    // 'Access-Control-Allow-Origin' header is present [...]" instead of saying
    // something like "[...] Access-Control-Allow-Origin' header has a value
    // 'http://www2.localhost:8000' that is not equal to the supplied origin
    // [...]").
    if (base::StartsWith(name, "Access-Control-",
                         base::CompareCase::INSENSITIVE_ASCII)) {
      continue;
    }

    // Remove all other headers.
    names_of_headers_to_remove.insert(base::ToLowerASCII(name));
  }

  headers->RemoveHeaders(names_of_headers_to_remove);
}

std::set<int>& GetPluginProxyingProcesses() {
  static base::NoDestructor<std::set<int>> set;
  return *set;
}

// The function below returns a set of MIME types below may be blocked by CORB
// without any confirmation sniffing (in contrast to HTML/JSON/XML which require
// confirmation sniffing because images, scripts, etc. are frequently
// mislabelled by http servers as HTML/JSON/XML).
base::flat_set<std::string>& GetNeverSniffedMimeTypes() {
  static base::NoDestructor<base::flat_set<std::string>> s_types{{
      // The list below has been populated based on most commonly used content
      // types according to HTTP Archive - see:
      // https://github.com/whatwg/fetch/issues/860#issuecomment-457330454
      //
      // TODO(lukasza): https://crbug.com/802836#c11: Add
      // application/signed-exchange.
      "application/gzip",
      "application/x-gzip",
      "application/x-protobuf",
      "application/zip",
      // Block multipart responses because a protected type (e.g. JSON) can
      // become multipart if returned in a range request with multiple parts.
      // This is compatible with the web because the renderer can only see into
      // the result of a fetch for a multipart file when the request is made
      // with CORS. Media tags only make single-range requests which will not
      // have the multipart type.
      "multipart/byteranges",
      "text/event-stream",
  }};

  // All items need to be lower-case, to support case-insensitive comparisons
  // later.
  DCHECK(std::all_of(
      s_types->begin(), s_types->end(),
      [](const std::string& s) { return s == base::ToLowerASCII(s); }));

  return *s_types;
}

}  // namespace

MimeType CrossOriginReadBlocking::GetCanonicalMimeType(
    base::StringPiece mime_type) {
  // Checking for image/svg+xml and application/dash+xml early ensures that they
  // won't get classified as MimeType::kXml by the presence of the "+xml"
  // suffix.
  if (base::LowerCaseEqualsASCII(mime_type, kImageSvg) ||
      base::LowerCaseEqualsASCII(mime_type, kDashVideo))
    return MimeType::kOthers;

  // See also https://mimesniff.spec.whatwg.org/#html-mime-type
  if (base::LowerCaseEqualsASCII(mime_type, kTextHtml))
    return MimeType::kHtml;

  // See also https://mimesniff.spec.whatwg.org/#json-mime-type
  constexpr auto kCaseInsensitive = base::CompareCase::INSENSITIVE_ASCII;
  if (base::LowerCaseEqualsASCII(mime_type, kAppJson) ||
      base::LowerCaseEqualsASCII(mime_type, kTextJson) ||
      base::LowerCaseEqualsASCII(mime_type, kJsonProtobuf) ||
      base::EndsWith(mime_type, kJsonSuffix, kCaseInsensitive)) {
    return MimeType::kJson;
  }

  // See also https://mimesniff.spec.whatwg.org/#xml-mime-type
  if (base::LowerCaseEqualsASCII(mime_type, kAppXml) ||
      base::LowerCaseEqualsASCII(mime_type, kTextXml) ||
      base::EndsWith(mime_type, kXmlSuffix, kCaseInsensitive)) {
    return MimeType::kXml;
  }

  if (base::LowerCaseEqualsASCII(mime_type, kTextPlain))
    return MimeType::kPlain;

  if (base::Contains(GetNeverSniffedMimeTypes(),
                     base::ToLowerASCII(mime_type))) {
    return MimeType::kNeverSniffed;
  }

  return MimeType::kOthers;
}

bool CrossOriginReadBlocking::IsBlockableScheme(const GURL& url) {
  // We exclude ftp:// from here. FTP doesn't provide a Content-Type
  // header which our policy depends on, so we cannot protect any
  // response from FTP servers.
  return url.SchemeIs(url::kHttpScheme) || url.SchemeIs(url::kHttpsScheme);
}

bool CrossOriginReadBlocking::IsValidCorsHeaderSet(
    const url::Origin& frame_origin,
    const std::string& access_control_origin) {
  // Many websites are sending back "\"*\"" instead of "*". This is
  // non-standard practice, and not supported by Chrome. Refer to
  // CrossOriginAccessControl::passesAccessControlCheck().

  // Note that "null" offers no more protection than "*" because it matches any
  // unique origin, such as data URLs. Any origin can thus access it, so don't
  // bother trying to block this case.

  // TODO(dsjang): * is not allowed for the response from a request
  // with cookies. This allows for more than what the renderer will
  // eventually be able to receive, so we won't see illegal cross-site
  // documents allowed by this. We have to find a way to see if this
  // response is from a cookie-tagged request or not in the future.
  if (access_control_origin == "*" || access_control_origin == "null")
    return true;

  return frame_origin.IsSameOriginWith(
      url::Origin::Create(GURL(access_control_origin)));
}

// This function is a slight modification of |net::SniffForHTML|.
SniffingResult CrossOriginReadBlocking::SniffForHTML(StringPiece data) {
  // The content sniffers used by Chrome and Firefox are using "<!--" as one of
  // the HTML signatures, but it also appears in valid JavaScript, considered as
  // well-formed JS by the browser.  Since we do not want to block any JS, we
  // exclude it from our HTML signatures. This can weaken our CORB policy,
  // but we can break less websites.
  //
  // Note that <body> and <br> are not included below, since <b is a prefix of
  // them.
  //
  // TODO(dsjang): parameterize |net::SniffForHTML| with an option that decides
  // whether to include <!-- or not, so that we can remove this function.
  // TODO(dsjang): Once CrossOriginReadBlocking is moved into the browser
  // process, we should do single-thread checking here for the static
  // initializer.
  static constexpr StringPiece kHtmlSignatures[] = {
      StringPiece("<!doctype html"),  // HTML5 spec
      StringPiece("<script"),         // HTML5 spec, Mozilla
      StringPiece("<html"),           // HTML5 spec, Mozilla
      StringPiece("<head"),           // HTML5 spec, Mozilla
      StringPiece("<iframe"),         // Mozilla
      StringPiece("<h1"),             // Mozilla
      StringPiece("<div"),            // Mozilla
      StringPiece("<font"),           // Mozilla
      StringPiece("<table"),          // Mozilla
      StringPiece("<a"),              // Mozilla
      StringPiece("<style"),          // Mozilla
      StringPiece("<title"),          // Mozilla
      StringPiece("<b"),              // Mozilla (note: subsumes <body>, <br>)
      StringPiece("<p")               // Mozilla
  };

  while (data.length() > 0) {
    AdvancePastWhitespace(&data);

    SniffingResult signature_match =
        MatchesSignature(&data, kHtmlSignatures, base::size(kHtmlSignatures),
                         base::CompareCase::INSENSITIVE_ASCII);
    if (signature_match != kNo)
      return signature_match;

    SniffingResult comment_match = MaybeSkipHtmlComment(&data);
    if (comment_match != kYes)
      return comment_match;
  }

  // All of |data| was consumed, without a clear determination.
  return kMaybe;
}

SniffingResult CrossOriginReadBlocking::SniffForXML(base::StringPiece data) {
  // TODO(dsjang): Once CrossOriginReadBlocking is moved into the browser
  // process, we should do single-thread checking here for the static
  // initializer.
  AdvancePastWhitespace(&data);
  static constexpr StringPiece kXmlSignatures[] = {StringPiece("<?xml")};
  return MatchesSignature(&data, kXmlSignatures, base::size(kXmlSignatures),
                          base::CompareCase::SENSITIVE);
}

SniffingResult CrossOriginReadBlocking::SniffForJSON(base::StringPiece data) {
  // Currently this function looks for an opening brace ('{'), followed by a
  // double-quoted string literal, followed by a colon. Importantly, such a
  // sequence is a Javascript syntax error: although the JSON object syntax is
  // exactly Javascript's object-initializer syntax, a Javascript object-
  // initializer expression is not valid as a standalone Javascript statement.
  //
  // TODO(nick): We have to come up with a better way to sniff JSON. The
  // following are known limitations of this function:
  // https://crbug.com/795470/ Support non-dictionary values (e.g. lists)
  enum {
    kStartState,
    kLeftBraceState,
    kLeftQuoteState,
    kEscapeState,
    kRightQuoteState,
  } state = kStartState;

  for (size_t i = 0; i < data.length(); ++i) {
    const char c = data[i];
    if (state != kLeftQuoteState && state != kEscapeState) {
      // Whitespace is ignored (outside of string literals)
      if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
        continue;
    } else {
      // Inside string literals, control characters should result in rejection.
      if ((c >= 0 && c < 32) || c == 127)
        return kNo;
    }

    switch (state) {
      case kStartState:
        if (c == '{')
          state = kLeftBraceState;
        else
          return kNo;
        break;
      case kLeftBraceState:
        if (c == '"')
          state = kLeftQuoteState;
        else
          return kNo;
        break;
      case kLeftQuoteState:
        if (c == '"')
          state = kRightQuoteState;
        else if (c == '\\')
          state = kEscapeState;
        break;
      case kEscapeState:
        // Simplification: don't bother rejecting hex escapes.
        state = kLeftQuoteState;
        break;
      case kRightQuoteState:
        if (c == ':')
          return kYes;
        else
          return kNo;
        break;
    }
  }
  return kMaybe;
}

SniffingResult CrossOriginReadBlocking::SniffForFetchOnlyResource(
    base::StringPiece data) {
  // kScriptBreakingPrefixes contains prefixes that are conventionally used to
  // prevent a JSON response from becoming a valid Javascript program (an attack
  // vector known as XSSI). The presence of such a prefix is a strong signal
  // that the resource is meant to be consumed only by the fetch API or
  // XMLHttpRequest, and is meant to be protected from use in non-CORS, cross-
  // origin contexts like <script>, <img>, etc.
  //
  // These prefixes work either by inducing a syntax error, or inducing an
  // infinite loop. In either case, the prefix must create a guarantee that no
  // matter what bytes follow it, the entire response would be worthless to
  // execute as a <script>.
  static constexpr StringPiece kScriptBreakingPrefixes[] = {
      // Parser breaker prefix.
      //
      // Built into angular.js (followed by a comma and a newline):
      //   https://docs.angularjs.org/api/ng/service/$http
      //
      // Built into the Java Spring framework (followed by a comma and a space):
      //   https://goo.gl/xP7FWn
      //
      // Observed on google.com (without a comma, followed by a newline).
      StringPiece(")]}'"),

      // Apache struts: https://struts.apache.org/plugins/json/#prefix
      StringPiece("{}&&"),

      // Spring framework (historically): https://goo.gl/JYPFAv
      StringPiece("{} &&"),

      // Infinite loops.
      StringPiece("for(;;);"),  // observed on facebook.com
      StringPiece("while(1);"),
      StringPiece("for (;;);"),
      StringPiece("while (1);"),
  };
  SniffingResult has_parser_breaker = MatchesSignature(
      &data, kScriptBreakingPrefixes, base::size(kScriptBreakingPrefixes),
      base::CompareCase::SENSITIVE);
  if (has_parser_breaker != kNo)
    return has_parser_breaker;

  // A non-empty JSON object also effectively introduces a JS syntax error.
  return SniffForJSON(data);
}

// static
void CrossOriginReadBlocking::SanitizeBlockedResponse(
    network::ResourceResponseInfo* response) {
  DCHECK(response);
  response->content_length = 0;
  if (response->headers)
    BlockResponseHeaders(response->headers);
}

// static
void CrossOriginReadBlocking::LogAction(Action action) {
  UMA_HISTOGRAM_ENUMERATION("SiteIsolation.XSD.Browser.Action", action);
}

// An interface to enable incremental content sniffing. These are instantiated
// for each each request; thus they can be stateful.
class CrossOriginReadBlocking::ResponseAnalyzer::ConfirmationSniffer {
 public:
  virtual ~ConfirmationSniffer() = default;

  // Called after data is read from the network. |sniffing_buffer| contains the
  // entire response body delivered thus far. To support streaming,
  // |new_data_offset| gives the offset into |sniffing_buffer| at which new data
  // was appended since the last read.
  virtual void OnDataAvailable(base::StringPiece sniffing_buffer,
                               size_t new_data_offset) = 0;

  // Returns true if the return value of IsConfirmedContentType() might change
  // with the addition of more data. Returns false if a final decision is
  // available.
  virtual bool WantsMoreData() const = 0;

  // Returns true if the data has been confirmed to be of the CORB-protected
  // content type that this sniffer is intended to detect.
  virtual bool IsConfirmedContentType() const = 0;
};

// A ConfirmationSniffer that wraps one of the sniffing functions from
// network::CrossOriginReadBlocking.
class CrossOriginReadBlocking::ResponseAnalyzer::SimpleConfirmationSniffer
    : public CrossOriginReadBlocking::ResponseAnalyzer::ConfirmationSniffer {
 public:
  // The function pointer type corresponding to one of the available sniffing
  // functions from network::CrossOriginReadBlocking.
  using SnifferFunction =
      decltype(&network::CrossOriginReadBlocking::SniffForHTML);

  explicit SimpleConfirmationSniffer(SnifferFunction sniffer_function)
      : sniffer_function_(sniffer_function) {}
  ~SimpleConfirmationSniffer() override = default;

  void OnDataAvailable(base::StringPiece sniffing_buffer,
                       size_t new_data_offset) final {
    DCHECK_LE(new_data_offset, sniffing_buffer.length());
    if (new_data_offset == sniffing_buffer.length()) {
      // No new data -- do nothing. This happens at end-of-stream.
      return;
    }
    // The sniffing functions don't support streaming, so with each new chunk of
    // data, call the sniffer on the whole buffer.
    last_sniff_result_ = (*sniffer_function_)(sniffing_buffer);
  }

  bool WantsMoreData() const final {
    // kNo and kYes results are final, meaning that sniffing can stop once they
    // occur. A kMaybe result corresponds to an indeterminate state, that could
    // change to kYes or kNo with more data.
    return last_sniff_result_ == SniffingResult::kMaybe;
  }

  bool IsConfirmedContentType() const final {
    // Only confirm the mime type if an affirmative pattern (e.g. an HTML tag,
    // if using the HTML sniffer) was detected.
    //
    // Note that if the stream ends (or net::kMaxBytesToSniff has been reached)
    // and |last_sniff_result_| is kMaybe, the response is allowed to go
    // through.
    return last_sniff_result_ == SniffingResult::kYes;
  }

 private:
  // The function that actually knows how to sniff for a content type.
  SnifferFunction sniffer_function_;

  // Result of sniffing the data available thus far.
  SniffingResult last_sniff_result_ = SniffingResult::kMaybe;

  DISALLOW_COPY_AND_ASSIGN(SimpleConfirmationSniffer);
};

CrossOriginReadBlocking::ResponseAnalyzer::ResponseAnalyzer(
    const GURL& request_url,
    const base::Optional<url::Origin>& request_initiator,
    const ResourceResponseInfo& response,
    base::Optional<url::Origin> request_initiator_site_lock,
    mojom::RequestMode request_mode)
    : seems_sensitive_from_cors_heuristic_(
          SeemsSensitiveFromCORSHeuristic(response)),
      seems_sensitive_from_cache_heuristic_(
          SeemsSensitiveFromCacheHeuristic(response)),
      supports_range_requests_(SupportsRangeRequests(response)),
      has_nosniff_header_(HasNoSniff(response)),
      content_length_(response.content_length),
      http_response_code_(response.headers ? response.headers->response_code()
                                           : 0) {
  // CORB should look directly at the Content-Type header if one has been
  // received from the network. Ignoring |response.mime_type| helps avoid
  // breaking legitimate websites (which might happen more often when blocking
  // would be based on the mime type sniffed by MimeSniffingResourceHandler).
  //
  // This value could be computed later in ShouldBlockBasedOnHeaders after
  // has_nosniff_header, but we compute it here to keep
  // ShouldBlockBasedOnHeaders (which is called twice) const.
  //
  // TODO(nick): What if the mime type is omitted? Should that be treated the
  // same as text/plain? https://crbug.com/795971
  std::string mime_type;
  if (response.headers)
    response.headers->GetMimeType(&mime_type);
  // Canonicalize the MIME type.  Note that even if it doesn't claim to be a
  // blockable type (i.e., HTML, XML, JSON, or plain text), it may still fail
  // the checks during the SniffForFetchOnlyResource() phase.
  canonical_mime_type_ =
      network::CrossOriginReadBlocking::GetCanonicalMimeType(mime_type);

  should_block_based_on_headers_ = ShouldBlockBasedOnHeaders(
      request_mode, request_url, request_initiator, response,
      request_initiator_site_lock, canonical_mime_type_);

  // Check if the response seems sensitive and if so include in our CORB
  // protection logging. We have not sniffed yet, so the answer might be
  // kNeedToSniffMore.
  if (seems_sensitive_from_cors_heuristic_ ||
      seems_sensitive_from_cache_heuristic_) {
    // Create a new Origin with a unique internal identifier so we can pretend
    // the request is cross-origin.
    url::Origin cross_origin_request_initiator = url::Origin();
    BlockingDecision would_protect_based_on_headers = ShouldBlockBasedOnHeaders(
        request_mode, request_url, cross_origin_request_initiator, response,
        cross_origin_request_initiator, canonical_mime_type_);
    corb_protection_logging_needs_sniffing_ =
        (would_protect_based_on_headers ==
         BlockingDecision::kNeedToSniffMore) &&
        base::FeatureList::IsEnabled(
            network::features::kCORBProtectionSniffing);
    hypothetical_sniffing_mode_ =
        corb_protection_logging_needs_sniffing_ &&
        should_block_based_on_headers_ != BlockingDecision::kNeedToSniffMore;
    mime_type_bucket_ = GetMimeTypeBucket(response);
    UMA_HISTOGRAM_BOOLEAN("SiteIsolation.CORBProtection.SensitiveResource",
                          true);
    if (!corb_protection_logging_needs_sniffing_) {
      // If we are not going to sniff, then we can and must log everything now.
      LogSensitiveResponseProtection(
          BlockingDecisionToProtectionDecision(would_protect_based_on_headers));
    }
  } else {
    UMA_HISTOGRAM_BOOLEAN("SiteIsolation.CORBProtection.SensitiveResource",
                          false);
  }
  if (needs_sniffing())
    CreateSniffers();
}

CrossOriginReadBlocking::ResponseAnalyzer::~ResponseAnalyzer() = default;

// static
CrossOriginReadBlocking::ResponseAnalyzer::BlockingDecision
CrossOriginReadBlocking::ResponseAnalyzer::ShouldBlockBasedOnHeaders(
    mojom::RequestMode request_mode,
    const GURL& request_url,
    const base::Optional<url::Origin>& request_initiator,
    const ResourceResponseInfo& response,
    const base::Optional<url::Origin>& request_initiator_site_lock,
    MimeType canonical_mime_type) {
  // The checks in this method are ordered to rule out blocking in most cases as
  // quickly as possible.  Checks that are likely to lead to returning false or
  // that are inexpensive should be near the top.
  url::Origin target_origin = url::Origin::Create(request_url);

  // Compute the |initiator| of the request, falling back to a unique origin if
  // there was no initiator or if it was incompatible with the lock. Using a
  // unique origin makes CORB treat the response as cross-origin and thus
  // considers it eligible for blocking (based on content-type, sniffing, etc.).
  url::Origin initiator =
      GetTrustworthyInitiator(request_initiator_site_lock, request_initiator);

  // Don't block same-origin documents.
  if (initiator.IsSameOriginWith(target_origin))
    return kAllow;

  // Only block documents from HTTP(S) schemes.  Checking the scheme of
  // |target_origin| ensures that we also protect content of blob: and
  // filesystem: URLs if their nested origins have a HTTP(S) scheme.
  if (!IsBlockableScheme(target_origin.GetURL()))
    return kAllow;

  // Allow the response through if this is a CORS request and the response has
  // valid CORS headers.
  switch (request_mode) {
    case mojom::RequestMode::kNavigate:
    case mojom::RequestMode::kNavigateNestedFrame:
    case mojom::RequestMode::kNavigateNestedObject:
    case mojom::RequestMode::kNoCors:
    case mojom::RequestMode::kSameOrigin:
      break;

    case mojom::RequestMode::kCors:
    case mojom::RequestMode::kCorsWithForcedPreflight:
      std::string cors_header;
      response.headers->GetNormalizedHeader("access-control-allow-origin",
                                            &cors_header);
      if (IsValidCorsHeaderSet(initiator, cors_header))
        return kAllow;
      break;
  }

  // Requests from foo.example.com will consult foo.example.com's service worker
  // first (if one has been registered).  The service worker can handle requests
  // initiated by foo.example.com even if they are cross-origin (e.g. requests
  // for bar.example.com).  This is okay and should not be blocked by CORB,
  // unless the initiator opted out of CORS / opted into receiving an opaque
  // response.  See also https://crbug.com/803672.
  if (response.was_fetched_via_service_worker) {
    switch (response.response_type) {
      case network::mojom::FetchResponseType::kBasic:
      case network::mojom::FetchResponseType::kCors:
      case network::mojom::FetchResponseType::kDefault:
      case network::mojom::FetchResponseType::kError:
        // Non-opaque responses shouldn't be blocked.
        return kAllow;
      case network::mojom::FetchResponseType::kOpaque:
      case network::mojom::FetchResponseType::kOpaqueRedirect:
        // Opaque responses are eligible for blocking. Continue on...
        break;
    }
  }

  // Some types (e.g. ZIP) are protected without any confirmation sniffing.
  if (canonical_mime_type == MimeType::kNeverSniffed)
    return kBlock;

  // CORS is currently implemented in the renderer process, so it's useful for
  // CORB to filter failed "cors" mode fetches to avoid leaking the responses to
  // the renderer when possible (e.g., depending on MIME type and sniffing).
  // This will eventually be fixed with OOR-CORS.
  //
  // In the mean time, we can try to filter a few additional failed CORS
  // fetches, treating the Cross-Origin-Resource-Policy (CORP) header as an
  // opt-in to CORB.  CORP headers are enforced elsewhere and normally only
  // apply to "no-cors" mode fetches.  If such a header happens to be on the
  // response during other fetch modes, and if the same-origin and
  // IsValidCorsHeaderSet checks above have failed (and thus the request will
  // fail in the renderer), then we can let CORB filter the response without
  // caring about MIME type or sniffing.
  //
  // To make CrossOriginResourcePolicy::Verify apply to all fetch modes in this
  // case and not just "no-cors", we pass kNoCors as a hard-coded value.  This
  // does not affect the usual enforcement of CORP headers.
  //
  // TODO(lukasza): Once OOR-CORS launches (https://crbug.com/736308), this code
  // block will no longer be necessary since all failed CORS requests will be
  // blocked before reaching the renderer process (even without CORB's help).
  // Of course this assumes that OOR-CORS will use trustworthy
  // |request_initiator| (i.e. vetted against |request_initiator|site_lock|).
  constexpr mojom::RequestMode kOverreachingRequestMode =
      mojom::RequestMode::kNoCors;
  // COEP is not supported when OOR-CORS is disabled.
  if (CrossOriginResourcePolicy::kBlock ==
      CrossOriginResourcePolicy::Verify(
          request_url, request_initiator, response, kOverreachingRequestMode,
          request_initiator_site_lock,
          mojom::CrossOriginEmbedderPolicy::kNone)) {
    // Ignore mime types and/or sniffing and have CORB block all responses with
    // COR*P* header.
    return kBlock;
  }

  // If this is a partial response, sniffing is not possible, so allow the
  // response if it's not a protected mime type.
  std::string range_header;
  response.headers->GetNormalizedHeader("content-range", &range_header);
  bool has_range_header = !range_header.empty();
  if (has_range_header) {
    switch (canonical_mime_type) {
      case MimeType::kOthers:
      case MimeType::kPlain:  // See also https://crbug.com/801709
        return kAllow;
      case MimeType::kHtml:
      case MimeType::kJson:
      case MimeType::kXml:
        return kBlock;
      case MimeType::kInvalidMimeType:
      case MimeType::kNeverSniffed:  // Handled much earlier.
        NOTREACHED();
        return kBlock;
    }
  }

  // We intend to block the response at this point.  However, we will usually
  // sniff the contents to confirm the MIME type, to avoid blocking incorrectly
  // labeled JavaScript, JSONP, etc files.
  //
  // Note: if there is a nosniff header, it means we should honor the response
  // mime type without trying to confirm it.
  //
  // Decide whether to block based on the MIME type.
  switch (canonical_mime_type) {
    case MimeType::kHtml:
    case MimeType::kXml:
    case MimeType::kJson:
    case MimeType::kPlain:
      if (HasNoSniff(response))
        return kBlock;
      else
        return kNeedToSniffMore;
      break;

    case MimeType::kOthers:
      // Stylesheets shouldn't be sniffed for JSON parser breakers - see
      // https://crbug.com/809259.
      if (base::LowerCaseEqualsASCII(response.mime_type, "text/css"))
        return kAllow;
      else
        return kNeedToSniffMore;
      break;

    case MimeType::kInvalidMimeType:
    case MimeType::kNeverSniffed:  // Handled much earlier.
      NOTREACHED();
      return kBlock;
  }
  NOTREACHED();
  return kBlock;
}

// static
bool CrossOriginReadBlocking::ResponseAnalyzer::HasNoSniff(
    const ResourceResponseInfo& response) {
  if (!response.headers)
    return false;
  std::string nosniff_header;
  response.headers->GetNormalizedHeader("x-content-type-options",
                                        &nosniff_header);
  return base::LowerCaseEqualsASCII(nosniff_header, "nosniff");
}

// static
bool CrossOriginReadBlocking::ResponseAnalyzer::SeemsSensitiveFromCORSHeuristic(
    const ResourceResponseInfo& response) {
  // Check if the response has an Access-Control-Allow-Origin with a value other
  // than "*" or "null" ("null" offers no more protection than "*" because it
  // matches any unique origin).
  if (!response.headers)
    return false;
  std::string cors_header_value;
  response.headers->GetNormalizedHeader("access-control-allow-origin",
                                        &cors_header_value);
  if (cors_header_value != "*" && cors_header_value != "null" &&
      cors_header_value != "") {
    return true;
  }
  return false;
}

// static
bool CrossOriginReadBlocking::ResponseAnalyzer::
    SeemsSensitiveFromCacheHeuristic(const ResourceResponseInfo& response) {
  // Check if the response has both Vary: Origin and Cache-Control: Private
  // headers, which we take as a signal that it may be a sensitive resource. We
  // require both to reduce the number of false positives (as both headers are
  // sometimes used on non-sensitive resources). Cache-Control: no-store appears
  // on non-sensitive resources that change frequently, so we ignore it here.
  if (!response.headers)
    return false;
  bool has_vary_origin = response.headers->HasHeaderValue("vary", "origin");
  bool has_cache_private =
      response.headers->HasHeaderValue("cache-control", "private");
  return has_vary_origin && has_cache_private;
}

// static
bool CrossOriginReadBlocking::ResponseAnalyzer::SupportsRangeRequests(
    const ResourceResponseInfo& response) {
  if (response.headers) {
    std::string value;
    response.headers->GetNormalizedHeader("accept-ranges", &value);
    if (!value.empty() && !base::LowerCaseEqualsASCII(value, "none")) {
      return true;
    }
  }
  return false;
}

// static
CrossOriginReadBlocking::ResponseAnalyzer::MimeTypeBucket
CrossOriginReadBlocking::ResponseAnalyzer::GetMimeTypeBucket(
    const ResourceResponseInfo& response) {
  std::string mime_type;
  if (response.headers)
    response.headers->GetMimeType(&mime_type);
  MimeType canonical_mime_type = GetCanonicalMimeType(mime_type);
  switch (canonical_mime_type) {
    case MimeType::kHtml:
    case MimeType::kXml:
    case MimeType::kJson:
    case MimeType::kNeverSniffed:
    case MimeType::kPlain:
      return kProtected;
      break;
    case MimeType::kOthers:
      break;
    case MimeType::kInvalidMimeType:
      NOTREACHED();
      break;
  }

  // Javascript is assumed public. See also
  // https://mimesniff.spec.whatwg.org/#javascript-mime-type.
  constexpr auto kCaseInsensitive = base::CompareCase::INSENSITIVE_ASCII;
  for (const std::string& suffix : kJavaScriptSuffixes) {
    if (base::EndsWith(mime_type, suffix, kCaseInsensitive)) {
      return kPublic;
    }
  }

  // Images are assumed public. See also
  // https://mimesniff.spec.whatwg.org/#image-mime-type.
  if (base::StartsWith(mime_type, "image", kCaseInsensitive)) {
    return kPublic;
  }

  // Audio and video are assumed public. See also
  // https://mimesniff.spec.whatwg.org/#audio-or-video-mime-type.
  if (base::StartsWith(mime_type, "audio", kCaseInsensitive) ||
      base::StartsWith(mime_type, "video", kCaseInsensitive) ||
      base::LowerCaseEqualsASCII(mime_type, "application/ogg") ||
      base::LowerCaseEqualsASCII(mime_type, "application/dash+xml")) {
    return kPublic;
  }

  // CSS files are assumed public and must be sent with text/css.
  if (base::LowerCaseEqualsASCII(mime_type, "text/css")) {
    return kPublic;
  }
  return kOther;
}

void CrossOriginReadBlocking::ResponseAnalyzer::CreateSniffers() {
  // Create one or more |sniffers_| to confirm that the body is actually the
  // MIME type advertised in the Content-Type header.
  DCHECK(needs_sniffing());
  DCHECK(sniffers_.empty());

  // When the MIME type is "text/plain", create sniffers for HTML, XML and
  // JSON. If any of these sniffers match, the response will be blocked.
  const bool use_all = canonical_mime_type_ == MimeType::kPlain;

  // HTML sniffer.
  if (use_all || canonical_mime_type_ == MimeType::kHtml) {
    sniffers_.push_back(std::make_unique<SimpleConfirmationSniffer>(
        &network::CrossOriginReadBlocking::SniffForHTML));
  }

  // XML sniffer.
  if (use_all || canonical_mime_type_ == MimeType::kXml) {
    sniffers_.push_back(std::make_unique<SimpleConfirmationSniffer>(
        &network::CrossOriginReadBlocking::SniffForXML));
  }

  // JSON sniffer.
  if (use_all || canonical_mime_type_ == MimeType::kJson) {
    sniffers_.push_back(std::make_unique<SimpleConfirmationSniffer>(
        &network::CrossOriginReadBlocking::SniffForJSON));
  }

  // Parser-breaker sniffer.
  //
  // Because these prefixes are an XSSI-defeating mechanism, CORB considers
  // them distinctive enough to be worth blocking no matter the Content-Type
  // header. So this sniffer is created unconditionally.
  //
  // For MimeType::kOthers, this will be the only sniffer that's active.
  sniffers_.push_back(std::make_unique<SimpleConfirmationSniffer>(
      &network::CrossOriginReadBlocking::SniffForFetchOnlyResource));
}

void CrossOriginReadBlocking::ResponseAnalyzer::SniffResponseBody(
    base::StringPiece data,
    size_t new_data_offset) {
  DCHECK(needs_sniffing());
  DCHECK(!sniffers_.empty());
  DCHECK(!found_blockable_content_);

  DCHECK_LE(data.size(), static_cast<size_t>(net::kMaxBytesToSniff));
  DCHECK_LE(new_data_offset, data.size());
  bool has_new_data = (new_data_offset < data.size());

  for (size_t i = 0; i < sniffers_.size();) {
    if (has_new_data)
      sniffers_[i]->OnDataAvailable(data, new_data_offset);

    if (sniffers_[i]->WantsMoreData()) {
      i++;
      continue;
    }

    if (sniffers_[i]->IsConfirmedContentType()) {
      found_blockable_content_ = true;
      sniffers_.clear();
      break;
    } else {
      // This response is CORB-exempt as far as this sniffer is concerned;
      // remove it from the list.
      sniffers_.erase(sniffers_.begin() + i);
    }
  }
}

bool CrossOriginReadBlocking::ResponseAnalyzer::ShouldAllow() const {
  // If we're in hypothetical mode then CORB must have decided to kAllow (see
  // comment in ShouldBlock). Thus we just need to wait until the sniffers are
  // all done (i.e. empty).
  if (hypothetical_sniffing_mode_) {
    DCHECK_EQ(should_block_based_on_headers_, kAllow);
    return sniffers_.empty();
  }
  switch (should_block_based_on_headers_) {
    case kAllow:
      return true;
    case kNeedToSniffMore:
      return sniffers_.empty() && !found_blockable_content_;
    case kBlock:
      return false;
  }
}

bool CrossOriginReadBlocking::ResponseAnalyzer::ShouldBlock() const {
  // If we're in *hypothetical* sniffing mode then the following must be true:
  // (1) We are only sniffing to find out if CORB would have blocked the request
  // were it made cross origin (CORB itself did *not* need to sniff the file).
  // (2) CORB must have decided to kAllow (if it was kBlock then the protection
  // decision would have been kBlock as well, no hypothetical mode needed).
  if (hypothetical_sniffing_mode_) {
    DCHECK_EQ(should_block_based_on_headers_, kAllow);
    return false;
  }
  switch (should_block_based_on_headers_) {
    case kAllow:
      return false;
    case kNeedToSniffMore:
      return sniffers_.empty() && found_blockable_content_;
    case kBlock:
      return true;
  }
}

bool CrossOriginReadBlocking::ResponseAnalyzer::ShouldReportBlockedResponse()
    const {
  if (!ShouldBlock())
    return false;

  // Don't bother showing a warning message when blocking responses that are
  // already empty.
  if (content_length_ == 0)
    return false;
  if (http_response_code_ == 204)
    return false;

  // Don't bother showing a warning message when blocking responses that are
  // associated with error responses (e.g. it is quite common to serve a
  // text/html 404 error page for an <img> tag pointing to a wrong URL).
  if (400 <= http_response_code_ && http_response_code_ <= 599)
    return false;

  return true;
}

void CrossOriginReadBlocking::ResponseAnalyzer::LogAllowedResponse() {
  if (corb_protection_logging_needs_sniffing_) {
    LogSensitiveResponseProtection(
        SniffingDecisionToProtectionDecision(found_blockable_content_));
  }
  // Note that if a response is allowed because of hitting EOF or
  // kMaxBytesToSniff, then |sniffers_| are not emptied and consequently
  // ShouldAllow doesn't start returning true.  This means that we can't
  // DCHECK(ShouldAllow()) or DCHECK(sniffers_.empty()) here - the decision to
  // allow the response could have been made in the
  // CrossSiteDocumentResourceHandler layer without CrossOriginReadBlocking
  // realizing that it has hit EOF or kMaxBytesToSniff.

  // Note that the response might be allowed even if ShouldBlock() returns true
  // - for example to allow responses to requests initiated by content scripts.
  // This means that we cannot DCHECK(!ShouldBlock()) here.

  CrossOriginReadBlocking::LogAction(
      needs_sniffing()
          ? network::CrossOriginReadBlocking::Action::kAllowedAfterSniffing
          : network::CrossOriginReadBlocking::Action::kAllowedWithoutSniffing);
}

void CrossOriginReadBlocking::ResponseAnalyzer::LogBlockedResponse() {
  DCHECK(!ShouldAllow());
  DCHECK(ShouldBlock());
  DCHECK(sniffers_.empty());

  if (corb_protection_logging_needs_sniffing_) {
    LogSensitiveResponseProtection(
        SniffingDecisionToProtectionDecision(found_blockable_content_));
  }

  CrossOriginReadBlocking::LogAction(
      needs_sniffing()
          ? network::CrossOriginReadBlocking::Action::kBlockedAfterSniffing
          : network::CrossOriginReadBlocking::Action::kBlockedWithoutSniffing);

  UMA_HISTOGRAM_ENUMERATION(
      "SiteIsolation.XSD.Browser.Blocked.CanonicalMimeType",
      canonical_mime_type_);
}

// static
CrossOriginReadBlocking::ResponseAnalyzer::CrossOriginProtectionDecision
CrossOriginReadBlocking::ResponseAnalyzer::BlockingDecisionToProtectionDecision(
    BlockingDecision blocking_decision) {
  switch (blocking_decision) {
    case kAllow:
      return CrossOriginProtectionDecision::kAllow;
    case kBlock:
      return CrossOriginProtectionDecision::kBlock;
    case kNeedToSniffMore:
      return CrossOriginProtectionDecision::kNeedToSniffMore;
  }
}

// static
CrossOriginReadBlocking::ResponseAnalyzer::CrossOriginProtectionDecision
CrossOriginReadBlocking::ResponseAnalyzer::SniffingDecisionToProtectionDecision(
    bool found_blockable_content) {
  if (found_blockable_content)
    return CrossOriginProtectionDecision::kBlockedAfterSniffing;
  return CrossOriginProtectionDecision::kAllowedAfterSniffing;
}

void CrossOriginReadBlocking::ResponseAnalyzer::LogSensitiveResponseProtection(
    CrossOriginProtectionDecision protection_decision) const {
  DCHECK(seems_sensitive_from_cors_heuristic_ ||
         seems_sensitive_from_cache_heuristic_);
  if (seems_sensitive_from_cors_heuristic_) {
    switch (mime_type_bucket_) {
      case kProtected:
        UMA_HISTOGRAM_ENUMERATION(
            "SiteIsolation.CORBProtection.CORSHeuristic.ProtectedMimeType",
            protection_decision);
        // We report if a response with a protected MIME type supports range
        // requests since we want to measure how often making a multipart range
        // requests would have allowed bypassing CORB.
        if (protection_decision == CrossOriginProtectionDecision::kBlock) {
          UMA_HISTOGRAM_BOOLEAN(
              "SiteIsolation.CORBProtection.CORSHeuristic.ProtectedMimeType."
              "BlockedWithRangeSupport",
              supports_range_requests_);
          UMA_HISTOGRAM_BOOLEAN(
              "SiteIsolation.CORBProtection.CORSHeuristic.ProtectedMimeType."
              "BlockedWithoutSniffing.HasNoSniff",
              has_nosniff_header_);
        } else if (protection_decision ==
                   CrossOriginProtectionDecision::kBlockedAfterSniffing) {
          UMA_HISTOGRAM_BOOLEAN(
              "SiteIsolation.CORBProtection.CORSHeuristic.ProtectedMimeType."
              "BlockedAfterSniffingWithRangeSupport",
              supports_range_requests_);
        }
        break;
      case kPublic:
        UMA_HISTOGRAM_ENUMERATION(
            "SiteIsolation.CORBProtection.CORSHeuristic.PublicMimeType",
            protection_decision);
        break;
      case kOther:
        UMA_HISTOGRAM_ENUMERATION(
            "SiteIsolation.CORBProtection.CORSHeuristic.OtherMimeType",
            protection_decision);
    }
  }
  if (seems_sensitive_from_cache_heuristic_) {
    switch (mime_type_bucket_) {
      case kProtected:
        UMA_HISTOGRAM_ENUMERATION(
            "SiteIsolation.CORBProtection.CacheHeuristic.ProtectedMimeType",
            protection_decision);
        if (protection_decision == CrossOriginProtectionDecision::kBlock) {
          UMA_HISTOGRAM_BOOLEAN(
              "SiteIsolation.CORBProtection.CacheHeuristic.ProtectedMimeType."
              "BlockedWithRangeSupport",
              supports_range_requests_);
          UMA_HISTOGRAM_BOOLEAN(
              "SiteIsolation.CORBProtection.CacheHeuristic.ProtectedMimeType."
              "BlockedWithoutSniffing.HasNoSniff",
              has_nosniff_header_);
        } else if (protection_decision ==
                   CrossOriginProtectionDecision::kBlockedAfterSniffing) {
          UMA_HISTOGRAM_BOOLEAN(
              "SiteIsolation.CORBProtection.CacheHeuristic.ProtectedMimeType."
              "BlockedAfterSniffingWithRangeSupport",
              supports_range_requests_);
        }
        break;
      case kPublic:
        UMA_HISTOGRAM_ENUMERATION(
            "SiteIsolation.CORBProtection.CacheHeuristic.PublicMimeType",
            protection_decision);
        break;
      case kOther:
        UMA_HISTOGRAM_ENUMERATION(
            "SiteIsolation.CORBProtection.CacheHeuristic.OtherMimeType",
            protection_decision);
    }
  }
  // Also log if the server supports range requests, since these may allow
  // bypassing CORB.
  UMA_HISTOGRAM_BOOLEAN(
      "SiteIsolation.CORBProtection.SensitiveWithRangeSupport",
      supports_range_requests_);
}

// static
void CrossOriginReadBlocking::AddExceptionForPlugin(int process_id) {
  std::set<int>& plugin_proxies = GetPluginProxyingProcesses();
  plugin_proxies.insert(process_id);
}

// static
bool CrossOriginReadBlocking::ShouldAllowForPlugin(int process_id) {
  std::set<int>& plugin_proxies = GetPluginProxyingProcesses();
  return base::Contains(plugin_proxies, process_id);
}

// static
void CrossOriginReadBlocking::RemoveExceptionForPlugin(int process_id) {
  std::set<int>& plugin_proxies = GetPluginProxyingProcesses();
  size_t number_of_elements_removed = plugin_proxies.erase(process_id);
  DCHECK_EQ(1u, number_of_elements_removed);
}

// static
void CrossOriginReadBlocking::AddExtraMimeTypesForCorb(
    const std::vector<std::string>& mime_types) {
  // All items need to be lower-case, to support case-insensitive comparisons.
  DCHECK(std::all_of(
      mime_types.begin(), mime_types.end(),
      [](const std::string& s) { return s == base::ToLowerASCII(s); }));
  base::flat_set<std::string>& never_sniffed_types = GetNeverSniffedMimeTypes();
  never_sniffed_types.insert(mime_types.begin(), mime_types.end());
  never_sniffed_types.shrink_to_fit();
}

}  // namespace network
