2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "ResourceResponseCFNet.h"
29 #include "HTTPParsers.h"
30 #include "MIMETypeRegistry.h"
31 #include "ResourceResponse.h"
32 #include <CFNetwork/CFURLResponsePriv.h>
33 #include <wtf/RetainPtr.h>
37 // We would like a better value for a maximum time_t,
38 // but there is no way to do that in C with any certainty.
39 // INT_MAX should work well enough for our purposes.
40 #define MAX_TIME_T ((time_t)INT_MAX)
44 CFURLResponseRef
ResourceResponse::cfURLResponse() const
46 return m_cfResponse
.get();
49 static inline bool filenameHasSaneExtension(const String
& filename
)
51 int dot
= filename
.find('.');
53 // The dot can't be the first or last character in the filename.
54 int length
= filename
.length();
55 return dot
> 0 && dot
< length
- 1;
58 static time_t toTimeT(CFAbsoluteTime time
)
60 static const double maxTimeAsDouble
= std::numeric_limits
<time_t>::max();
61 static const double minTimeAsDouble
= std::numeric_limits
<time_t>::min();
62 return min(max(minTimeAsDouble
, time
+ kCFAbsoluteTimeIntervalSince1970
), maxTimeAsDouble
);
65 void ResourceResponse::platformLazyInit()
72 ASSERT(!m_cfResponse
.get());
76 // FIXME: We may need to do MIME type sniffing here (unless that is done in CFURLResponseGetMIMEType).
78 m_url
= CFURLResponseGetURL(m_cfResponse
.get());
79 m_mimeType
= CFURLResponseGetMIMEType(m_cfResponse
.get());
80 m_expectedContentLength
= CFURLResponseGetExpectedContentLength(m_cfResponse
.get());
81 m_textEncodingName
= CFURLResponseGetTextEncodingName(m_cfResponse
.get());
83 m_expirationDate
= toTimeT(CFURLResponseGetExpirationTime(m_cfResponse
.get()));
84 m_lastModifiedDate
= toTimeT(CFURLResponseGetLastModifiedDate(m_cfResponse
.get()));
86 RetainPtr
<CFStringRef
> suggestedFilename(AdoptCF
, CFURLResponseCopySuggestedFilename(m_cfResponse
.get()));
87 m_suggestedFilename
= suggestedFilename
.get();
89 CFHTTPMessageRef httpResponse
= CFURLResponseGetHTTPResponse(m_cfResponse
.get());
91 m_httpStatusCode
= CFHTTPMessageGetResponseStatusCode(httpResponse
);
93 RetainPtr
<CFStringRef
> statusLine(AdoptCF
, CFHTTPMessageCopyResponseStatusLine(httpResponse
));
94 String
statusText(statusLine
.get());
95 int spacePos
= statusText
.find(" ");
97 statusText
= statusText
.substring(spacePos
+ 1);
98 m_httpStatusText
= statusText
;
100 RetainPtr
<CFDictionaryRef
> headers(AdoptCF
, CFHTTPMessageCopyAllHeaderFields(httpResponse
));
101 CFIndex headerCount
= CFDictionaryGetCount(headers
.get());
102 Vector
<const void*, 128> keys(headerCount
);
103 Vector
<const void*, 128> values(headerCount
);
104 CFDictionaryGetKeysAndValues(headers
.get(), keys
.data(), values
.data());
105 for (int i
= 0; i
< headerCount
; ++i
)
106 m_httpHeaderFields
.set((CFStringRef
)keys
[i
], (CFStringRef
)values
[i
]);
108 m_httpStatusCode
= 0;
111 bool ResourceResponse::platformCompare(const ResourceResponse
& a
, const ResourceResponse
& b
)
113 return CFEqual(a
.cfURLResponse(), b
.cfURLResponse());