| Index: components/offline_pages/request_header/offline_page_header.cc | 
| diff --git a/components/offline_pages/request_header/offline_page_header.cc b/components/offline_pages/request_header/offline_page_header.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..de9b8980465bca0203cc87cc6796850b62b01e52 | 
| --- /dev/null | 
| +++ b/components/offline_pages/request_header/offline_page_header.cc | 
| @@ -0,0 +1,114 @@ | 
| +// Copyright 2016 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 "components/offline_pages/request_header/offline_page_header.h" | 
| + | 
| +#include "base/strings/string_tokenizer.h" | 
| +#include "base/strings/string_util.h" | 
| + | 
| +namespace offline_pages { | 
| + | 
| +const char kOfflinePageHeader[] = "X-Chrome-offline"; | 
| +const char kOfflinePageHeaderReasonKey[] = "reason"; | 
| +const char kOfflinePageHeaderReasonValueDueToNetError[] = "error"; | 
| +const char kOfflinePageHeaderReasonValueFromDownload[] = "download"; | 
| +const char kOfflinePageHeaderReasonValueReload[] = "reload"; | 
| +const char kOfflinePageHeaderPersistKey[] = "persist"; | 
| +const char kOfflinePageHeaderIDKey[] = "id"; | 
| + | 
| +namespace { | 
| + | 
| +std::string ReasonToString(OfflinePageHeader::Reason reason) { | 
| +  switch (reason) { | 
| +    case OfflinePageHeader::Reason::NET_ERROR: | 
| +      return kOfflinePageHeaderReasonValueDueToNetError; | 
| +    case OfflinePageHeader::Reason::DOWNLOAD: | 
| +      return kOfflinePageHeaderReasonValueFromDownload; | 
| +    case OfflinePageHeader::Reason::RELOAD: | 
| +      return kOfflinePageHeaderReasonValueReload; | 
| +    default: | 
| +      NOTREACHED(); | 
| +      return ""; | 
| +  } | 
| +} | 
| + | 
| +}  // namespace | 
| + | 
| +OfflinePageHeader::OfflinePageHeader() | 
| +    : need_to_persist(false), | 
| +      reason(Reason::NONE) { | 
| +} | 
| + | 
| +OfflinePageHeader::~OfflinePageHeader() {} | 
| + | 
| +bool OfflinePageHeader::ParseFromHeaderValue(const std::string& header_value) { | 
| +  // If the offline header is not present, treat it as not parsed successfully. | 
| +  if (header_value.empty()) | 
| +    return false; | 
| + | 
| +  base::StringTokenizer tokenizer(header_value, ", "); | 
| +  while (tokenizer.GetNext()) { | 
| +    std::string pair = tokenizer.token(); | 
| +    std::size_t pos = pair.find('='); | 
| +    if (pos == std::string::npos) | 
| +      return false; | 
| +    std::string key = base::ToLowerASCII(pair.substr(0, pos)); | 
| +    std::string value = base::ToLowerASCII(pair.substr(pos + 1)); | 
| +    if (key == kOfflinePageHeaderPersistKey) { | 
| +      if (value == "1") | 
| +        need_to_persist = true; | 
| +      else if (value == "0") | 
| +        need_to_persist = false; | 
| +      else | 
| +        return false; | 
| +    } else if (key == kOfflinePageHeaderReasonKey) { | 
| +      if (value == kOfflinePageHeaderReasonValueDueToNetError) | 
| +        reason = Reason::NET_ERROR; | 
| +      else if (value == kOfflinePageHeaderReasonValueFromDownload) | 
| +        reason = Reason::DOWNLOAD; | 
| +      else if (value == kOfflinePageHeaderReasonValueReload) | 
| +        reason = Reason::RELOAD; | 
| +      else | 
| +        return false; | 
| +    } else if (key == kOfflinePageHeaderIDKey) { | 
| +      id = value; | 
| +    } | 
| +  } | 
| + | 
| +  return true; | 
| +} | 
| + | 
| +std::string OfflinePageHeader::GetCompleteHeaderString() const { | 
| +  if (reason == Reason::NONE) | 
| +    return std::string(); | 
| + | 
| +  std::string value(kOfflinePageHeader); | 
| +  value += ": "; | 
| + | 
| +  value += kOfflinePageHeaderPersistKey; | 
| +  value += "="; | 
| +  value += need_to_persist ? "1" : "0"; | 
| + | 
| +  value += " " ; | 
| +  value += kOfflinePageHeaderReasonKey; | 
| +  value += "="; | 
| +  value += ReasonToString(reason); | 
| + | 
| +  if (!id.empty()) { | 
| +    value += " " ; | 
| +    value += kOfflinePageHeaderIDKey; | 
| +    value += "="; | 
| +    value += id; | 
| +  } | 
| + | 
| +  return value; | 
| +} | 
| + | 
| +void OfflinePageHeader::Clear() { | 
| +  reason = Reason::NONE; | 
| +  need_to_persist = false; | 
| +  id.clear(); | 
| +} | 
| + | 
| +}  // namespace offline_pages | 
|  |