[WK2][NetworkCache] We only cache responses with status codes that are cacheable...
[WebKit-https.git] / Source / WebCore / platform / network / ResourceResponseBase.h
1 /*
2  * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
3  * Copyright (C) 2009 Google Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #ifndef ResourceResponseBase_h
28 #define ResourceResponseBase_h
29
30 #include "CacheValidation.h"
31 #include "CertificateInfo.h"
32 #include "HTTPHeaderMap.h"
33 #include "URL.h"
34 #include "ResourceLoadTiming.h"
35
36 #include <wtf/PassOwnPtr.h>
37 #include <wtf/RefPtr.h>
38
39 #if OS(SOLARIS)
40 #include <sys/time.h> // For time_t structure.
41 #endif
42
43 namespace WebCore {
44
45 class ResourceResponse;
46 struct CrossThreadResourceResponseData;
47
48 // Do not use this class directly, use the class ResponseResponse instead
49 class ResourceResponseBase {
50     WTF_MAKE_FAST_ALLOCATED;
51 public:
52     static PassOwnPtr<ResourceResponse> adopt(PassOwnPtr<CrossThreadResourceResponseData>);
53
54     // Gets a copy of the data suitable for passing to another thread.
55     PassOwnPtr<CrossThreadResourceResponseData> copyData() const;
56
57     bool isNull() const { return m_isNull; }
58     WEBCORE_EXPORT bool isHTTP() const;
59
60     WEBCORE_EXPORT const URL& url() const;
61     WEBCORE_EXPORT void setURL(const URL& url);
62
63     WEBCORE_EXPORT const String& mimeType() const;
64     WEBCORE_EXPORT void setMimeType(const String& mimeType);
65
66     WEBCORE_EXPORT long long expectedContentLength() const;
67     WEBCORE_EXPORT void setExpectedContentLength(long long expectedContentLength);
68
69     WEBCORE_EXPORT const String& textEncodingName() const;
70     WEBCORE_EXPORT void setTextEncodingName(const String& name);
71
72     WEBCORE_EXPORT int httpStatusCode() const;
73     WEBCORE_EXPORT void setHTTPStatusCode(int);
74     
75     WEBCORE_EXPORT const String& httpStatusText() const;
76     WEBCORE_EXPORT void setHTTPStatusText(const String&);
77
78     WEBCORE_EXPORT const HTTPHeaderMap& httpHeaderFields() const;
79
80     String httpHeaderField(const String& name) const;
81     WEBCORE_EXPORT String httpHeaderField(HTTPHeaderName) const;
82     WEBCORE_EXPORT void setHTTPHeaderField(const String& name, const String& value);
83     void setHTTPHeaderField(HTTPHeaderName, const String& value);
84
85     void addHTTPHeaderField(const String& name, const String& value);
86
87     // Instead of passing a string literal to any of these functions, just use a HTTPHeaderName instead.
88     template<size_t length> String httpHeaderField(const char (&)[length]) const = delete;
89     template<size_t length> void setHTTPHeaderField(const char (&)[length], const String&) = delete;
90     template<size_t length> void addHTTPHeaderField(const char (&)[length], const String&) = delete;
91
92     bool isMultipart() const { return mimeType() == "multipart/x-mixed-replace"; }
93
94     WEBCORE_EXPORT bool isAttachment() const;
95     WEBCORE_EXPORT String suggestedFilename() const;
96
97     WEBCORE_EXPORT void includeCertificateInfo() const;
98     bool containsCertificateInfo() const { return m_includesCertificateInfo; }
99     WEBCORE_EXPORT CertificateInfo certificateInfo() const;
100     
101     // These functions return parsed values of the corresponding response headers.
102     // NaN means that the header was not present or had invalid value.
103     WEBCORE_EXPORT bool cacheControlContainsNoCache() const;
104     WEBCORE_EXPORT bool cacheControlContainsNoStore() const;
105     WEBCORE_EXPORT bool cacheControlContainsMustRevalidate() const;
106     WEBCORE_EXPORT bool hasCacheValidatorFields() const;
107     WEBCORE_EXPORT double cacheControlMaxAge() const;
108     double date() const;
109     double age() const;
110     WEBCORE_EXPORT double expires() const;
111     WEBCORE_EXPORT double lastModified() const;
112
113     enum class Source { Unknown, Network, DiskCache, DiskCacheAfterValidation };
114     WEBCORE_EXPORT Source source() const;
115     WEBCORE_EXPORT void setSource(Source);
116
117     ResourceLoadTiming& resourceLoadTiming() const { return m_resourceLoadTiming; }
118
119     // The ResourceResponse subclass may "shadow" this method to provide platform-specific memory usage information
120     unsigned memoryUsage() const
121     {
122         // average size, mostly due to URL and Header Map strings
123         return 1280;
124     }
125
126     static bool compare(const ResourceResponse&, const ResourceResponse&);
127
128     template<class Encoder> void encode(Encoder&) const;
129     template<class Decoder> static bool decode(Decoder&, ResourceResponseBase&);
130
131 protected:
132     enum InitLevel {
133         Uninitialized,
134         CommonFieldsOnly,
135         AllFields
136     };
137
138     WEBCORE_EXPORT ResourceResponseBase();
139     ResourceResponseBase(const URL&, const String& mimeType, long long expectedLength, const String& textEncodingName);
140
141     WEBCORE_EXPORT void lazyInit(InitLevel) const;
142
143     // The ResourceResponse subclass should shadow these functions to lazily initialize platform specific fields
144     void platformLazyInit(InitLevel) { }
145     CertificateInfo platformCertificateInfo() const { return CertificateInfo(); };
146     String platformSuggestedFileName() const { return String(); }
147
148     static bool platformCompare(const ResourceResponse&, const ResourceResponse&) { return true; }
149
150     URL m_url;
151     AtomicString m_mimeType;
152     long long m_expectedContentLength;
153     AtomicString m_textEncodingName;
154     AtomicString m_httpStatusText;
155     HTTPHeaderMap m_httpHeaderFields;
156     mutable ResourceLoadTiming m_resourceLoadTiming;
157
158     mutable bool m_includesCertificateInfo;
159     mutable CertificateInfo m_certificateInfo;
160
161     int m_httpStatusCode;
162
163 private:
164     mutable double m_age;
165     mutable double m_date;
166     mutable double m_expires;
167     mutable double m_lastModified;
168     mutable CacheControlDirectives m_cacheControlDirectives;
169
170 public:
171     bool m_isNull : 1;
172     
173 private:
174     const ResourceResponse& asResourceResponse() const;
175     void parseCacheControlDirectives() const;
176     void updateHeaderParsedState(HTTPHeaderName);
177
178     mutable bool m_haveParsedCacheControlHeader : 1;
179     mutable bool m_haveParsedAgeHeader : 1;
180     mutable bool m_haveParsedDateHeader : 1;
181     mutable bool m_haveParsedExpiresHeader : 1;
182     mutable bool m_haveParsedLastModifiedHeader : 1;
183
184     Source m_source;
185 };
186
187 inline bool operator==(const ResourceResponse& a, const ResourceResponse& b) { return ResourceResponseBase::compare(a, b); }
188 inline bool operator!=(const ResourceResponse& a, const ResourceResponse& b) { return !(a == b); }
189
190 template<class Encoder>
191 void ResourceResponseBase::encode(Encoder& encoder) const
192 {
193     encoder << m_isNull;
194     if (m_isNull)
195         return;
196     lazyInit(AllFields);
197
198     encoder << m_url.string();
199     encoder << m_mimeType;
200     encoder << static_cast<int64_t>(m_expectedContentLength);
201     encoder << m_textEncodingName;
202     encoder << m_httpStatusText;
203     encoder << m_httpHeaderFields;
204     encoder << m_resourceLoadTiming;
205     encoder << m_httpStatusCode;
206     encoder << m_includesCertificateInfo;
207     if (m_includesCertificateInfo)
208         encoder << m_certificateInfo;
209     encoder.encodeEnum(m_source);
210 }
211
212 template<class Decoder>
213 bool ResourceResponseBase::decode(Decoder& decoder, ResourceResponseBase& response)
214 {
215     ASSERT(response.m_isNull);
216     bool responseIsNull;
217     if (!decoder.decode(responseIsNull))
218         return false;
219     if (responseIsNull)
220         return true;
221
222     String url;
223     if (!decoder.decode(url))
224         return false;
225     response.m_url = URL(URL(), url);
226     if (!decoder.decode(response.m_mimeType))
227         return false;
228     int64_t expectedContentLength;
229     if (!decoder.decode(expectedContentLength))
230         return false;
231     response.m_expectedContentLength = expectedContentLength;
232     if (!decoder.decode(response.m_textEncodingName))
233         return false;
234     if (!decoder.decode(response.m_httpStatusText))
235         return false;
236     if (!decoder.decode(response.m_httpHeaderFields))
237         return false;
238     if (!decoder.decode(response.m_resourceLoadTiming))
239         return false;
240     if (!decoder.decode(response.m_httpStatusCode))
241         return false;
242     if (!decoder.decode(response.m_includesCertificateInfo))
243         return false;
244     if (response.m_includesCertificateInfo) {
245         if (!decoder.decode(response.m_certificateInfo))
246             return false;
247     }
248     if (!decoder.decodeEnum(response.m_source))
249         return false;
250     response.m_isNull = false;
251
252     return true;
253 }
254
255 struct CrossThreadResourceResponseDataBase {
256     WTF_MAKE_NONCOPYABLE(CrossThreadResourceResponseDataBase); WTF_MAKE_FAST_ALLOCATED;
257 public:
258     CrossThreadResourceResponseDataBase() { }
259     URL m_url;
260     String m_mimeType;
261     long long m_expectedContentLength;
262     String m_textEncodingName;
263     int m_httpStatusCode;
264     String m_httpStatusText;
265     std::unique_ptr<CrossThreadHTTPHeaderMapData> m_httpHeaders;
266     ResourceLoadTiming m_resourceLoadTiming;
267 };
268
269 } // namespace WebCore
270
271 #endif // ResourceResponseBase_h