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 COMPUTER, 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 COMPUTER, 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 ResourceResponse_h 28 #define ResourceResponse_h 29 30 #include "core/fileapi/File.h" 31 #include "core/platform/network/HTTPHeaderMap.h" 32 #include "core/platform/network/ResourceLoadInfo.h" 33 #include "core/platform/network/ResourceLoadTiming.h" 34 #include "weborigin/KURL.h" 35 #include "wtf/PassOwnPtr.h" 36 #include "wtf/RefPtr.h" 37 #include "wtf/text/CString.h" 38 39 #if OS(SOLARIS) 40 #include <sys/time.h> // For time_t structure. 41 #endif 42 43 namespace WebCore { 44 45 struct CrossThreadResourceResponseData; 46 47 class ResourceResponse { 48 WTF_MAKE_FAST_ALLOCATED; 49 public: 50 enum HTTPVersion { Unknown, HTTP_0_9, HTTP_1_0, HTTP_1_1 }; 51 52 class ExtraData : public RefCounted<ExtraData> { 53 public: 54 virtual ~ExtraData() { } 55 }; 56 57 static PassOwnPtr<ResourceResponse> adopt(PassOwnPtr<CrossThreadResourceResponseData>); 58 59 // Gets a copy of the data suitable for passing to another thread. 60 PassOwnPtr<CrossThreadResourceResponseData> copyData() const; 61 62 ResourceResponse(); 63 ResourceResponse(const KURL&, const AtomicString& mimeType, long long expectedLength, const AtomicString& textEncodingName, const String& filename); 64 65 bool isNull() const { return m_isNull; } 66 bool isHTTP() const; 67 68 const KURL& url() const; 69 void setURL(const KURL&); 70 71 const AtomicString& mimeType() const; 72 void setMimeType(const AtomicString&); 73 74 long long expectedContentLength() const; 75 void setExpectedContentLength(long long); 76 77 const AtomicString& textEncodingName() const; 78 void setTextEncodingName(const AtomicString&); 79 80 // FIXME: Should compute this on the fly. 81 // There should not be a setter exposed, as suggested file name is determined based on other headers in a manner that WebCore does not necessarily know about. 82 const String& suggestedFilename() const; 83 void setSuggestedFilename(const String&); 84 85 int httpStatusCode() const; 86 void setHTTPStatusCode(int); 87 88 const AtomicString& httpStatusText() const; 89 void setHTTPStatusText(const AtomicString&); 90 91 String httpHeaderField(const AtomicString& name) const; 92 String httpHeaderField(const char* name) const; 93 void setHTTPHeaderField(const AtomicString& name, const String& value); 94 void addHTTPHeaderField(const AtomicString& name, const String& value); 95 const HTTPHeaderMap& httpHeaderFields() const; 96 97 bool isMultipart() const { return mimeType() == "multipart/x-mixed-replace"; } 98 99 bool isAttachment() const; 100 101 // FIXME: These are used by PluginStream on some platforms. Calculations may differ from just returning plain Last-Modified header. 102 // Leaving it for now but this should go away in favor of generic solution. 103 void setLastModifiedDate(time_t); 104 time_t lastModifiedDate() const; 105 106 // These functions return parsed values of the corresponding response headers. 107 // NaN means that the header was not present or had invalid value. 108 bool cacheControlContainsNoCache() const; 109 bool cacheControlContainsNoStore() const; 110 bool cacheControlContainsMustRevalidate() const; 111 bool hasCacheValidatorFields() const; 112 double cacheControlMaxAge() const; 113 double date() const; 114 double age() const; 115 double expires() const; 116 double lastModified() const; 117 118 unsigned connectionID() const; 119 void setConnectionID(unsigned); 120 121 bool connectionReused() const; 122 void setConnectionReused(bool); 123 124 bool wasCached() const; 125 void setWasCached(bool); 126 127 ResourceLoadTiming* resourceLoadTiming() const; 128 void setResourceLoadTiming(PassRefPtr<ResourceLoadTiming>); 129 130 PassRefPtr<ResourceLoadInfo> resourceLoadInfo() const; 131 void setResourceLoadInfo(PassRefPtr<ResourceLoadInfo>); 132 133 HTTPVersion httpVersion() const { return m_httpVersion; } 134 void setHTTPVersion(HTTPVersion version) { m_httpVersion = version; } 135 136 const CString& getSecurityInfo() const { return m_securityInfo; } 137 void setSecurityInfo(const CString& securityInfo) { m_securityInfo = securityInfo; } 138 139 long long appCacheID() const { return m_appCacheID; } 140 void setAppCacheID(long long id) { m_appCacheID = id; } 141 142 const KURL& appCacheManifestURL() const { return m_appCacheManifestURL; } 143 void setAppCacheManifestURL(const KURL& url) { m_appCacheManifestURL = url; } 144 145 bool wasFetchedViaSPDY() const { return m_wasFetchedViaSPDY; } 146 void setWasFetchedViaSPDY(bool value) { m_wasFetchedViaSPDY = value; } 147 148 bool wasNpnNegotiated() const { return m_wasNpnNegotiated; } 149 void setWasNpnNegotiated(bool value) { m_wasNpnNegotiated = value; } 150 151 bool wasAlternateProtocolAvailable() const 152 { 153 return m_wasAlternateProtocolAvailable; 154 } 155 void setWasAlternateProtocolAvailable(bool value) 156 { 157 m_wasAlternateProtocolAvailable = value; 158 } 159 160 bool wasFetchedViaProxy() const { return m_wasFetchedViaProxy; } 161 void setWasFetchedViaProxy(bool value) { m_wasFetchedViaProxy = value; } 162 163 bool isMultipartPayload() const { return m_isMultipartPayload; } 164 void setIsMultipartPayload(bool value) { m_isMultipartPayload = value; } 165 166 double responseTime() const { return m_responseTime; } 167 void setResponseTime(double responseTime) { m_responseTime = responseTime; } 168 169 const AtomicString& remoteIPAddress() const { return m_remoteIPAddress; } 170 void setRemoteIPAddress(const AtomicString& value) { m_remoteIPAddress = value; } 171 172 unsigned short remotePort() const { return m_remotePort; } 173 void setRemotePort(unsigned short value) { m_remotePort = value; } 174 175 const File* downloadedFile() const { return m_downloadedFile.get(); } 176 void setDownloadedFile(PassRefPtr<File> downloadedFile) { m_downloadedFile = downloadedFile; } 177 178 // Extra data associated with this response. 179 ExtraData* extraData() const { return m_extraData.get(); } 180 void setExtraData(PassRefPtr<ExtraData> extraData) { m_extraData = extraData; } 181 182 // The ResourceResponse subclass may "shadow" this method to provide platform-specific memory usage information 183 unsigned memoryUsage() const 184 { 185 // average size, mostly due to URL and Header Map strings 186 return 1280; 187 } 188 189 static bool compare(const ResourceResponse&, const ResourceResponse&); 190 191 private: 192 void parseCacheControlDirectives() const; 193 void updateHeaderParsedState(const AtomicString& name); 194 195 KURL m_url; 196 AtomicString m_mimeType; 197 long long m_expectedContentLength; 198 AtomicString m_textEncodingName; 199 String m_suggestedFilename; 200 int m_httpStatusCode; 201 AtomicString m_httpStatusText; 202 HTTPHeaderMap m_httpHeaderFields; 203 time_t m_lastModifiedDate; 204 bool m_wasCached : 1; 205 unsigned m_connectionID; 206 bool m_connectionReused : 1; 207 RefPtr<ResourceLoadTiming> m_resourceLoadTiming; 208 RefPtr<ResourceLoadInfo> m_resourceLoadInfo; 209 210 bool m_isNull : 1; 211 212 mutable bool m_haveParsedCacheControlHeader : 1; 213 mutable bool m_haveParsedAgeHeader : 1; 214 mutable bool m_haveParsedDateHeader : 1; 215 mutable bool m_haveParsedExpiresHeader : 1; 216 mutable bool m_haveParsedLastModifiedHeader : 1; 217 218 mutable bool m_cacheControlContainsNoCache : 1; 219 mutable bool m_cacheControlContainsNoStore : 1; 220 mutable bool m_cacheControlContainsMustRevalidate : 1; 221 mutable double m_cacheControlMaxAge; 222 223 mutable double m_age; 224 mutable double m_date; 225 mutable double m_expires; 226 mutable double m_lastModified; 227 228 // An opaque value that contains some information regarding the security of 229 // the connection for this request, such as SSL connection info (empty 230 // string if not over HTTPS). 231 CString m_securityInfo; 232 233 // HTTP version used in the response, if known. 234 HTTPVersion m_httpVersion; 235 236 // The id of the appcache this response was retrieved from, or zero if 237 // the response was not retrieved from an appcache. 238 long long m_appCacheID; 239 240 // The manifest url of the appcache this response was retrieved from, if any. 241 // Note: only valid for main resource responses. 242 KURL m_appCacheManifestURL; 243 244 // Set to true if this is part of a multipart response. 245 bool m_isMultipartPayload; 246 247 // Was the resource fetched over SPDY. See http://dev.chromium.org/spdy 248 bool m_wasFetchedViaSPDY; 249 250 // Was the resource fetched over a channel which used TLS/Next-Protocol-Negotiation (also SPDY related). 251 bool m_wasNpnNegotiated; 252 253 // Was the resource fetched over a channel which specified "Alternate-Protocol" 254 // (e.g.: Alternate-Protocol: 443:npn-spdy/1). 255 bool m_wasAlternateProtocolAvailable; 256 257 // Was the resource fetched over an explicit proxy (HTTP, SOCKS, etc). 258 bool m_wasFetchedViaProxy; 259 260 // The time at which the response headers were received. For cached 261 // responses, this time could be "far" in the past. 262 double m_responseTime; 263 264 // Remote IP address of the socket which fetched this resource. 265 AtomicString m_remoteIPAddress; 266 267 // Remote port number of the socket which fetched this resource. 268 unsigned short m_remotePort; 269 270 // The downloaded file if the load streamed to a file. 271 RefPtr<File> m_downloadedFile; 272 273 // ExtraData associated with the response. 274 RefPtr<ExtraData> m_extraData; 275 }; 276 277 inline bool operator==(const ResourceResponse& a, const ResourceResponse& b) { return ResourceResponse::compare(a, b); } 278 inline bool operator!=(const ResourceResponse& a, const ResourceResponse& b) { return !(a == b); } 279 280 struct CrossThreadResourceResponseData { 281 WTF_MAKE_NONCOPYABLE(CrossThreadResourceResponseData); WTF_MAKE_FAST_ALLOCATED; 282 public: 283 CrossThreadResourceResponseData() { } 284 KURL m_url; 285 String m_mimeType; 286 long long m_expectedContentLength; 287 String m_textEncodingName; 288 String m_suggestedFilename; 289 int m_httpStatusCode; 290 String m_httpStatusText; 291 OwnPtr<CrossThreadHTTPHeaderMapData> m_httpHeaders; 292 time_t m_lastModifiedDate; 293 RefPtr<ResourceLoadTiming> m_resourceLoadTiming; 294 CString m_securityInfo; 295 ResourceResponse::HTTPVersion m_httpVersion; 296 long long m_appCacheID; 297 KURL m_appCacheManifestURL; 298 bool m_isMultipartPayload; 299 bool m_wasFetchedViaSPDY; 300 bool m_wasNpnNegotiated; 301 bool m_wasAlternateProtocolAvailable; 302 bool m_wasFetchedViaProxy; 303 double m_responseTime; 304 String m_remoteIPAddress; 305 unsigned short m_remotePort; 306 String m_downloadFilePath; 307 }; 308 309 } // namespace WebCore 310 311 #endif // ResourceResponse_h 312