Modernize how many platform/network classes do isolatedCopy().
[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
44 // Do not use this class directly, use the class ResponseResponse instead
45 class ResourceResponseBase {
46     WTF_MAKE_FAST_ALLOCATED;
47 public:
48     ResourceResponse isolatedCopy() const;
49
50     bool isNull() const { return m_isNull; }
51     WEBCORE_EXPORT bool isHTTP() const;
52
53     WEBCORE_EXPORT const URL& url() const;
54     WEBCORE_EXPORT void setURL(const URL&);
55
56     WEBCORE_EXPORT const String& mimeType() const;
57     WEBCORE_EXPORT void setMimeType(const String& mimeType);
58
59     WEBCORE_EXPORT long long expectedContentLength() const;
60     WEBCORE_EXPORT void setExpectedContentLength(long long expectedContentLength);
61
62     WEBCORE_EXPORT const String& textEncodingName() const;
63     WEBCORE_EXPORT void setTextEncodingName(const String& name);
64
65     WEBCORE_EXPORT int httpStatusCode() const;
66     WEBCORE_EXPORT void setHTTPStatusCode(int);
67     
68     WEBCORE_EXPORT const String& httpStatusText() const;
69     WEBCORE_EXPORT void setHTTPStatusText(const String&);
70
71     WEBCORE_EXPORT const String& httpVersion() const;
72     WEBCORE_EXPORT void setHTTPVersion(const String&);
73     bool isHttpVersion0_9() const;
74
75     WEBCORE_EXPORT const HTTPHeaderMap& httpHeaderFields() const;
76
77     String httpHeaderField(const String& name) const;
78     WEBCORE_EXPORT String httpHeaderField(HTTPHeaderName) const;
79     WEBCORE_EXPORT void setHTTPHeaderField(const String& name, const String& value);
80     void setHTTPHeaderField(HTTPHeaderName, const String& value);
81
82     void addHTTPHeaderField(HTTPHeaderName, const String& value);
83     void addHTTPHeaderField(const String& name, const String& value);
84
85     // Instead of passing a string literal to any of these functions, just use a HTTPHeaderName instead.
86     template<size_t length> String httpHeaderField(const char (&)[length]) const = delete;
87     template<size_t length> void setHTTPHeaderField(const char (&)[length], const String&) = delete;
88     template<size_t length> void addHTTPHeaderField(const char (&)[length], const String&) = delete;
89
90     bool isMultipart() const { return mimeType() == "multipart/x-mixed-replace"; }
91
92     WEBCORE_EXPORT bool isAttachment() const;
93     WEBCORE_EXPORT String suggestedFilename() const;
94
95     WEBCORE_EXPORT void includeCertificateInfo() const;
96     bool containsCertificateInfo() const { return m_includesCertificateInfo; }
97     WEBCORE_EXPORT CertificateInfo certificateInfo() const;
98     
99     // These functions return parsed values of the corresponding response headers.
100     // NaN means that the header was not present or had invalid value.
101     WEBCORE_EXPORT bool cacheControlContainsNoCache() const;
102     WEBCORE_EXPORT bool cacheControlContainsNoStore() const;
103     WEBCORE_EXPORT bool cacheControlContainsMustRevalidate() const;
104     WEBCORE_EXPORT bool hasCacheValidatorFields() const;
105     WEBCORE_EXPORT Optional<std::chrono::microseconds> cacheControlMaxAge() const;
106     WEBCORE_EXPORT Optional<std::chrono::system_clock::time_point> date() const;
107     WEBCORE_EXPORT Optional<std::chrono::microseconds> age() const;
108     WEBCORE_EXPORT Optional<std::chrono::system_clock::time_point> expires() const;
109     WEBCORE_EXPORT Optional<std::chrono::system_clock::time_point> lastModified() const;
110     ParsedContentRange& contentRange() const;
111
112     // This is primarily for testing support. It is not necessarily accurate in all scenarios.
113     enum class Source { Unknown, Network, DiskCache, DiskCacheAfterValidation, MemoryCache, MemoryCacheAfterValidation };
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     enum class Type { Basic, Cors, Default, Error, Opaque, Opaqueredirect };
127     Type type() const { return m_type; }
128     void setType(Type type) { m_type = type; }
129     bool isRedirected() const { return m_isRedirected; }
130     void setRedirected(bool isRedirected) { m_isRedirected = isRedirected; }
131
132     static bool compare(const ResourceResponse&, const ResourceResponse&);
133
134     template<class Encoder> void encode(Encoder&) const;
135     template<class Decoder> static bool decode(Decoder&, ResourceResponseBase&);
136
137 protected:
138     enum InitLevel {
139         Uninitialized,
140         CommonFieldsOnly,
141         AllFields
142     };
143
144     WEBCORE_EXPORT ResourceResponseBase();
145     WEBCORE_EXPORT ResourceResponseBase(const URL&, const String& mimeType, long long expectedLength, const String& textEncodingName);
146
147     WEBCORE_EXPORT void lazyInit(InitLevel) const;
148
149     // The ResourceResponse subclass should shadow these functions to lazily initialize platform specific fields
150     void platformLazyInit(InitLevel) { }
151     CertificateInfo platformCertificateInfo() const { return CertificateInfo(); };
152     String platformSuggestedFileName() const { return String(); }
153
154     static bool platformCompare(const ResourceResponse&, const ResourceResponse&) { return true; }
155
156 private:
157     const ResourceResponse& asResourceResponse() const;
158     void parseCacheControlDirectives() const;
159     void updateHeaderParsedState(HTTPHeaderName);
160
161 protected:
162     bool m_isNull;
163     URL m_url;
164     AtomicString m_mimeType;
165     long long m_expectedContentLength;
166     AtomicString m_textEncodingName;
167     AtomicString m_httpStatusText;
168     AtomicString m_httpVersion;
169     HTTPHeaderMap m_httpHeaderFields;
170     mutable ResourceLoadTiming m_resourceLoadTiming;
171
172     mutable bool m_includesCertificateInfo;
173     mutable CertificateInfo m_certificateInfo;
174
175     int m_httpStatusCode;
176
177 private:
178     mutable Optional<std::chrono::microseconds> m_age;
179     mutable Optional<std::chrono::system_clock::time_point> m_date;
180     mutable Optional<std::chrono::system_clock::time_point> m_expires;
181     mutable Optional<std::chrono::system_clock::time_point> m_lastModified;
182     mutable ParsedContentRange m_contentRange;
183     mutable CacheControlDirectives m_cacheControlDirectives;
184
185     mutable bool m_haveParsedCacheControlHeader { false };
186     mutable bool m_haveParsedAgeHeader { false };
187     mutable bool m_haveParsedDateHeader { false };
188     mutable bool m_haveParsedExpiresHeader { false };
189     mutable bool m_haveParsedLastModifiedHeader { false };
190     mutable bool m_haveParsedContentRangeHeader { false };
191
192     Source m_source { Source::Unknown };
193
194     Type m_type { Type::Default };
195     bool m_isRedirected { false };
196 };
197
198 inline bool operator==(const ResourceResponse& a, const ResourceResponse& b) { return ResourceResponseBase::compare(a, b); }
199 inline bool operator!=(const ResourceResponse& a, const ResourceResponse& b) { return !(a == b); }
200
201 template<class Encoder>
202 void ResourceResponseBase::encode(Encoder& encoder) const
203 {
204     encoder << m_isNull;
205     if (m_isNull)
206         return;
207     lazyInit(AllFields);
208
209     encoder << m_url;
210     encoder << m_mimeType;
211     encoder << static_cast<int64_t>(m_expectedContentLength);
212     encoder << m_textEncodingName;
213     encoder << m_httpStatusText;
214     encoder << m_httpVersion;
215     encoder << m_httpHeaderFields;
216     encoder << m_resourceLoadTiming;
217     encoder << m_httpStatusCode;
218     encoder << m_includesCertificateInfo;
219     if (m_includesCertificateInfo)
220         encoder << m_certificateInfo;
221     encoder.encodeEnum(m_source);
222     encoder.encodeEnum(m_type);
223     encoder << m_isRedirected;
224 }
225
226 template<class Decoder>
227 bool ResourceResponseBase::decode(Decoder& decoder, ResourceResponseBase& response)
228 {
229     ASSERT(response.m_isNull);
230     bool responseIsNull;
231     if (!decoder.decode(responseIsNull))
232         return false;
233     if (responseIsNull)
234         return true;
235
236     if (!decoder.decode(response.m_url))
237         return false;
238     if (!decoder.decode(response.m_mimeType))
239         return false;
240     int64_t expectedContentLength;
241     if (!decoder.decode(expectedContentLength))
242         return false;
243     response.m_expectedContentLength = expectedContentLength;
244     if (!decoder.decode(response.m_textEncodingName))
245         return false;
246     if (!decoder.decode(response.m_httpStatusText))
247         return false;
248     if (!decoder.decode(response.m_httpVersion))
249         return false;
250     if (!decoder.decode(response.m_httpHeaderFields))
251         return false;
252     if (!decoder.decode(response.m_resourceLoadTiming))
253         return false;
254     if (!decoder.decode(response.m_httpStatusCode))
255         return false;
256     if (!decoder.decode(response.m_includesCertificateInfo))
257         return false;
258     if (response.m_includesCertificateInfo) {
259         if (!decoder.decode(response.m_certificateInfo))
260             return false;
261     }
262     if (!decoder.decodeEnum(response.m_source))
263         return false;
264     if (!decoder.decodeEnum(response.m_type))
265         return false;
266     if (!decoder.decode(response.m_isRedirected))
267         return false;
268     response.m_isNull = false;
269
270     return true;
271 }
272
273 } // namespace WebCore