5fff35994914128832de76009ace57bbf264233c
[WebKit-https.git] / Source / WebCore / platform / network / ResourceResponseBase.h
1 /*
2  * Copyright (C) 2006, 2008, 2016 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 #pragma once
28
29 #include "CacheValidation.h"
30 #include "CertificateInfo.h"
31 #include "HTTPHeaderMap.h"
32 #include "ParsedContentRange.h"
33 #include "ResourceLoadTiming.h"
34 #include "URL.h"
35
36 #if OS(SOLARIS)
37 #include <sys/time.h> // For time_t structure.
38 #endif
39
40 namespace WebCore {
41
42 class ResourceResponse;
43 struct CrossThreadResourceResponseData;
44
45 // Do not use this class directly, use the class ResponseResponse instead
46 class ResourceResponseBase {
47     WTF_MAKE_FAST_ALLOCATED;
48 public:
49     ResourceResponse isolatedCopy() const;
50
51     bool isNull() const { return m_isNull; }
52     WEBCORE_EXPORT bool isHTTP() const;
53
54     WEBCORE_EXPORT const URL& url() const;
55     WEBCORE_EXPORT void setURL(const URL&);
56
57     WEBCORE_EXPORT const String& mimeType() const;
58     WEBCORE_EXPORT void setMimeType(const String& mimeType);
59
60     WEBCORE_EXPORT long long expectedContentLength() const;
61     WEBCORE_EXPORT void setExpectedContentLength(long long expectedContentLength);
62
63     WEBCORE_EXPORT const String& textEncodingName() const;
64     WEBCORE_EXPORT void setTextEncodingName(const String& name);
65
66     WEBCORE_EXPORT int httpStatusCode() const;
67     WEBCORE_EXPORT void setHTTPStatusCode(int);
68     
69     WEBCORE_EXPORT const String& httpStatusText() const;
70     WEBCORE_EXPORT void setHTTPStatusText(const String&);
71
72     WEBCORE_EXPORT const String& httpVersion() const;
73     WEBCORE_EXPORT void setHTTPVersion(const String&);
74     bool isHttpVersion0_9() const;
75
76     WEBCORE_EXPORT const HTTPHeaderMap& httpHeaderFields() const;
77
78     String httpHeaderField(const String& name) const;
79     WEBCORE_EXPORT String httpHeaderField(HTTPHeaderName) const;
80     WEBCORE_EXPORT void setHTTPHeaderField(const String& name, const String& value);
81     void setHTTPHeaderField(HTTPHeaderName, const String& value);
82
83     void addHTTPHeaderField(HTTPHeaderName, const String& value);
84     void addHTTPHeaderField(const String& name, const String& value);
85
86     // Instead of passing a string literal to any of these functions, just use a HTTPHeaderName instead.
87     template<size_t length> String httpHeaderField(const char (&)[length]) const = delete;
88     template<size_t length> void setHTTPHeaderField(const char (&)[length], const String&) = delete;
89     template<size_t length> void addHTTPHeaderField(const char (&)[length], const String&) = delete;
90
91     bool isMultipart() const { return mimeType() == "multipart/x-mixed-replace"; }
92
93     WEBCORE_EXPORT bool isAttachment() const;
94     WEBCORE_EXPORT String suggestedFilename() const;
95
96     WEBCORE_EXPORT void includeCertificateInfo() const;
97     bool containsCertificateInfo() const { return m_includesCertificateInfo; }
98     WEBCORE_EXPORT CertificateInfo certificateInfo() const;
99     
100     // These functions return parsed values of the corresponding response headers.
101     // NaN means that the header was not present or had invalid value.
102     WEBCORE_EXPORT bool cacheControlContainsNoCache() const;
103     WEBCORE_EXPORT bool cacheControlContainsNoStore() const;
104     WEBCORE_EXPORT bool cacheControlContainsMustRevalidate() const;
105     WEBCORE_EXPORT bool hasCacheValidatorFields() const;
106     WEBCORE_EXPORT Optional<std::chrono::microseconds> cacheControlMaxAge() const;
107     WEBCORE_EXPORT Optional<std::chrono::system_clock::time_point> date() const;
108     WEBCORE_EXPORT Optional<std::chrono::microseconds> age() const;
109     WEBCORE_EXPORT Optional<std::chrono::system_clock::time_point> expires() const;
110     WEBCORE_EXPORT Optional<std::chrono::system_clock::time_point> lastModified() const;
111     ParsedContentRange& contentRange() const;
112
113     // This is primarily for testing support. It is not necessarily accurate in all scenarios.
114     enum class Source { Unknown, Network, DiskCache, DiskCacheAfterValidation, MemoryCache, MemoryCacheAfterValidation };
115     WEBCORE_EXPORT Source source() const;
116     WEBCORE_EXPORT void setSource(Source);
117
118     ResourceLoadTiming& resourceLoadTiming() const { return m_resourceLoadTiming; }
119
120     // The ResourceResponse subclass may "shadow" this method to provide platform-specific memory usage information
121     unsigned memoryUsage() const
122     {
123         // average size, mostly due to URL and Header Map strings
124         return 1280;
125     }
126
127     enum class Type { Basic, Cors, Default, Error, Opaque, Opaqueredirect };
128     Type type() const { return m_type; }
129     void setType(Type type) { m_type = type; }
130     bool isRedirected() const { return m_isRedirected; }
131     void setRedirected(bool isRedirected) { m_isRedirected = isRedirected; }
132
133     static bool compare(const ResourceResponse&, const ResourceResponse&);
134
135     template<class Encoder> void encode(Encoder&) const;
136     template<class Decoder> static bool decode(Decoder&, ResourceResponseBase&);
137
138 protected:
139     enum InitLevel {
140         Uninitialized,
141         CommonFieldsOnly,
142         AllFields
143     };
144
145     WEBCORE_EXPORT ResourceResponseBase();
146     WEBCORE_EXPORT ResourceResponseBase(const URL&, const String& mimeType, long long expectedLength, const String& textEncodingName);
147
148     WEBCORE_EXPORT void lazyInit(InitLevel) const;
149
150     // The ResourceResponse subclass should shadow these functions to lazily initialize platform specific fields
151     void platformLazyInit(InitLevel) { }
152     CertificateInfo platformCertificateInfo() const { return CertificateInfo(); };
153     String platformSuggestedFileName() const { return String(); }
154
155     static bool platformCompare(const ResourceResponse&, const ResourceResponse&) { return true; }
156
157 private:
158     const ResourceResponse& asResourceResponse() const;
159     void parseCacheControlDirectives() const;
160     void updateHeaderParsedState(HTTPHeaderName);
161
162     // Gets a copy of the data suitable for passing to another thread.
163     std::unique_ptr<CrossThreadResourceResponseData> copyData() const;
164
165 protected:
166     bool m_isNull;
167     URL m_url;
168     AtomicString m_mimeType;
169     long long m_expectedContentLength;
170     AtomicString m_textEncodingName;
171     AtomicString m_httpStatusText;
172     AtomicString m_httpVersion;
173     HTTPHeaderMap m_httpHeaderFields;
174     mutable ResourceLoadTiming m_resourceLoadTiming;
175
176     mutable bool m_includesCertificateInfo;
177     mutable CertificateInfo m_certificateInfo;
178
179     int m_httpStatusCode;
180
181 private:
182     mutable Optional<std::chrono::microseconds> m_age;
183     mutable Optional<std::chrono::system_clock::time_point> m_date;
184     mutable Optional<std::chrono::system_clock::time_point> m_expires;
185     mutable Optional<std::chrono::system_clock::time_point> m_lastModified;
186     mutable ParsedContentRange m_contentRange;
187     mutable CacheControlDirectives m_cacheControlDirectives;
188
189     mutable bool m_haveParsedCacheControlHeader { false };
190     mutable bool m_haveParsedAgeHeader { false };
191     mutable bool m_haveParsedDateHeader { false };
192     mutable bool m_haveParsedExpiresHeader { false };
193     mutable bool m_haveParsedLastModifiedHeader { false };
194     mutable bool m_haveParsedContentRangeHeader { false };
195
196     Source m_source { Source::Unknown };
197
198     Type m_type { Type::Default };
199     bool m_isRedirected { false };
200 };
201
202 inline bool operator==(const ResourceResponse& a, const ResourceResponse& b) { return ResourceResponseBase::compare(a, b); }
203 inline bool operator!=(const ResourceResponse& a, const ResourceResponse& b) { return !(a == b); }
204
205 template<class Encoder>
206 void ResourceResponseBase::encode(Encoder& encoder) const
207 {
208     encoder << m_isNull;
209     if (m_isNull)
210         return;
211     lazyInit(AllFields);
212
213     encoder << m_url;
214     encoder << m_mimeType;
215     encoder << static_cast<int64_t>(m_expectedContentLength);
216     encoder << m_textEncodingName;
217     encoder << m_httpStatusText;
218     encoder << m_httpVersion;
219     encoder << m_httpHeaderFields;
220     encoder << m_resourceLoadTiming;
221     encoder << m_httpStatusCode;
222     encoder << m_includesCertificateInfo;
223     if (m_includesCertificateInfo)
224         encoder << m_certificateInfo;
225     encoder.encodeEnum(m_source);
226     encoder.encodeEnum(m_type);
227     encoder << m_isRedirected;
228 }
229
230 template<class Decoder>
231 bool ResourceResponseBase::decode(Decoder& decoder, ResourceResponseBase& response)
232 {
233     ASSERT(response.m_isNull);
234     bool responseIsNull;
235     if (!decoder.decode(responseIsNull))
236         return false;
237     if (responseIsNull)
238         return true;
239
240     if (!decoder.decode(response.m_url))
241         return false;
242     if (!decoder.decode(response.m_mimeType))
243         return false;
244     int64_t expectedContentLength;
245     if (!decoder.decode(expectedContentLength))
246         return false;
247     response.m_expectedContentLength = expectedContentLength;
248     if (!decoder.decode(response.m_textEncodingName))
249         return false;
250     if (!decoder.decode(response.m_httpStatusText))
251         return false;
252     if (!decoder.decode(response.m_httpVersion))
253         return false;
254     if (!decoder.decode(response.m_httpHeaderFields))
255         return false;
256     if (!decoder.decode(response.m_resourceLoadTiming))
257         return false;
258     if (!decoder.decode(response.m_httpStatusCode))
259         return false;
260     if (!decoder.decode(response.m_includesCertificateInfo))
261         return false;
262     if (response.m_includesCertificateInfo) {
263         if (!decoder.decode(response.m_certificateInfo))
264             return false;
265     }
266     if (!decoder.decodeEnum(response.m_source))
267         return false;
268     if (!decoder.decodeEnum(response.m_type))
269         return false;
270     if (!decoder.decode(response.m_isRedirected))
271         return false;
272     response.m_isNull = false;
273
274     return true;
275 }
276
277 struct CrossThreadResourceResponseDataBase {
278     WTF_MAKE_NONCOPYABLE(CrossThreadResourceResponseDataBase); WTF_MAKE_FAST_ALLOCATED;
279 public:
280     CrossThreadResourceResponseDataBase() { }
281     URL m_url;
282     String m_mimeType;
283     long long m_expectedContentLength;
284     String m_textEncodingName;
285     int m_httpStatusCode;
286     String m_httpStatusText;
287     String m_httpVersion;
288     std::unique_ptr<CrossThreadHTTPHeaderMapData> m_httpHeaders;
289     ResourceLoadTiming m_resourceLoadTiming;
290     ResourceResponseBase::Type m_type;
291     bool m_isRedirected;
292 };
293
294 } // namespace WebCore