1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "webkit/media/cache_util.h"
9 #include "base/string_number_conversions.h"
10 #include "base/string_util.h"
11 #include "base/time.h"
12 #include "net/http/http_util.h"
13 #include "net/http/http_version.h"
14 #include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h"
15 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
16 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLResponse.h"
19 using base::TimeDelta
;
20 using net::HttpVersion
;
21 using WebKit::WebURLResponse
;
23 namespace webkit_media
{
25 enum { kHttpOK
= 200, kHttpPartialContent
= 206 };
27 uint32
GetReasonsForUncacheability(const WebURLResponse
& response
) {
29 const int code
= response
.httpStatusCode();
30 const int version
= response
.httpVersion();
31 const HttpVersion http_version
=
32 version
== WebURLResponse::HTTP_1_1
? HttpVersion(1, 1) :
33 version
== WebURLResponse::HTTP_1_0
? HttpVersion(1, 0) :
34 version
== WebURLResponse::HTTP_0_9
? HttpVersion(0, 9) :
36 if (code
!= kHttpOK
&& code
!= kHttpPartialContent
)
38 if (http_version
< HttpVersion(1, 1) && code
== kHttpPartialContent
)
39 reasons
|= kPre11PartialResponse
;
40 if (code
== kHttpPartialContent
&&
41 !net::HttpUtil::HasStrongValidators(
43 response
.httpHeaderField("etag").utf8(),
44 response
.httpHeaderField("Last-Modified").utf8(),
45 response
.httpHeaderField("Date").utf8())) {
46 reasons
|= kNoStrongValidatorOnPartialResponse
;
49 std::string cache_control_header
=
50 response
.httpHeaderField("cache-control").utf8();
51 StringToLowerASCII(&cache_control_header
);
52 if (cache_control_header
.find("no-cache") != std::string::npos
)
54 if (cache_control_header
.find("no-store") != std::string::npos
)
56 if (cache_control_header
.find("must-revalidate") != std::string::npos
)
57 reasons
|= kHasMustRevalidate
;
59 const TimeDelta kMinimumAgeForUsefulness
=
60 TimeDelta::FromSeconds(3600); // Arbitrary value.
62 const char kMaxAgePrefix
[] = "max-age=";
63 const size_t kMaxAgePrefixLen
= arraysize(kMaxAgePrefix
) - 1;
64 if (cache_control_header
.substr(0, kMaxAgePrefixLen
) == kMaxAgePrefix
) {
65 int64 max_age_seconds
;
67 base::StringPiece(cache_control_header
.begin() + kMaxAgePrefixLen
,
68 cache_control_header
.end()),
70 if (TimeDelta::FromSeconds(max_age_seconds
) < kMinimumAgeForUsefulness
)
71 reasons
|= kShortMaxAge
;
76 if (Time::FromString(response
.httpHeaderField("Date").utf8().data(), &date
) &&
77 Time::FromString(response
.httpHeaderField("Expires").utf8().data(),
79 date
> Time() && expires
> Time() &&
80 (expires
- date
) < kMinimumAgeForUsefulness
) {
81 reasons
|= kExpiresTooSoon
;
87 } // namespace webkit_media