1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/blink/cache_util.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_version.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebCString.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebString.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLResponse.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::HttpVersion;
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLResponse;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace media {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum { kHttpOK = 200, kHttpPartialContent = 206 };
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 GetReasonsForUncacheability(const WebURLResponse& response) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 reasons = 0;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int code = response.httpStatusCode();
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int version = response.httpVersion();
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpVersion http_version =
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      version == WebURLResponse::HTTP_1_1 ? HttpVersion(1, 1) :
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      version == WebURLResponse::HTTP_1_0 ? HttpVersion(1, 0) :
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      version == WebURLResponse::HTTP_0_9 ? HttpVersion(0, 9) :
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HttpVersion();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (code != kHttpOK && code != kHttpPartialContent)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reasons |= kNoData;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (http_version < HttpVersion(1, 1) && code == kHttpPartialContent)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reasons |= kPre11PartialResponse;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (code == kHttpPartialContent &&
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !net::HttpUtil::HasStrongValidators(
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          http_version,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          response.httpHeaderField("etag").utf8(),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          response.httpHeaderField("Last-Modified").utf8(),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          response.httpHeaderField("Date").utf8())) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reasons |= kNoStrongValidatorOnPartialResponse;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string cache_control_header =
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response.httpHeaderField("cache-control").utf8();
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::StringToLowerASCII(&cache_control_header);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cache_control_header.find("no-cache") != std::string::npos)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reasons |= kNoCache;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cache_control_header.find("no-store") != std::string::npos)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reasons |= kNoStore;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cache_control_header.find("must-revalidate") != std::string::npos)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reasons |= kHasMustRevalidate;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta kMinimumAgeForUsefulness =
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TimeDelta::FromSeconds(3600);  // Arbitrary value.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kMaxAgePrefix[] = "max-age=";
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kMaxAgePrefixLen = arraysize(kMaxAgePrefix) - 1;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cache_control_header.substr(0, kMaxAgePrefixLen) == kMaxAgePrefix) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 max_age_seconds;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::StringToInt64(
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::StringPiece(cache_control_header.begin() + kMaxAgePrefixLen,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          cache_control_header.end()),
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &max_age_seconds);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (TimeDelta::FromSeconds(max_age_seconds) < kMinimumAgeForUsefulness)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reasons |= kShortMaxAge;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time date;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time expires;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (Time::FromString(response.httpHeaderField("Date").utf8().data(), &date) &&
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time::FromString(response.httpHeaderField("Expires").utf8().data(),
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       &expires) &&
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      date > Time() && expires > Time() &&
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (expires - date) < kMinimumAgeForUsefulness) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reasons |= kExpiresTooSoon;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return reasons;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace media
88