18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "ResourceResponse.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29cad810f21b803229eb11403f9209855525a25d57Steve Block#if USE(CFNETWORK) 30cad810f21b803229eb11403f9209855525a25d57Steve Block 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTTPParsers.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MIMETypeRegistry.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <CFNetwork/CFURLResponsePriv.h> 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/RetainPtr.h> 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std; 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// We would like a better value for a maximum time_t, 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// but there is no way to do that in C with any certainty. 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// INT_MAX should work well enough for our purposes. 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define MAX_TIME_T ((time_t)INT_MAX) 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic CFStringRef const commonHeaderFields[] = { 462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch CFSTR("Age"), CFSTR("Cache-Control"), CFSTR("Date"), CFSTR("Etag"), CFSTR("Expires"), CFSTR("Last-Modified"), CFSTR("Pragma") 472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}; 482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const int numCommonHeaderFields = sizeof(commonHeaderFields) / sizeof(CFStringRef); 492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCFURLResponseRef ResourceResponse::cfURLResponse() const 512bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 522bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!m_cfResponse && !m_isNull) { 532bde8e466a4451c7319e3a072d118917957d6554Steve Block RetainPtr<CFURLRef> url(AdoptCF, m_url.createCFURL()); 542bde8e466a4451c7319e3a072d118917957d6554Steve Block RetainPtr<CFStringRef> mimeType(AdoptCF, m_mimeType.createCFString()); 552bde8e466a4451c7319e3a072d118917957d6554Steve Block RetainPtr<CFStringRef> textEncodingName(AdoptCF, m_textEncodingName.createCFString()); 562bde8e466a4451c7319e3a072d118917957d6554Steve Block m_cfResponse.adoptCF(CFURLResponseCreate(0, url.get(), mimeType.get(), m_expectedContentLength, textEncodingName.get(), kCFURLCacheStorageAllowed)); 572bde8e466a4451c7319e3a072d118917957d6554Steve Block } 582bde8e466a4451c7319e3a072d118917957d6554Steve Block 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_cfResponse.get(); 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline bool filenameHasSaneExtension(const String& filename) 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dot = filename.find('.'); 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The dot can't be the first or last character in the filename. 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int length = filename.length(); 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dot > 0 && dot < length - 1; 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic time_t toTimeT(CFAbsoluteTime time) 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static const double maxTimeAsDouble = std::numeric_limits<time_t>::max(); 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static const double minTimeAsDouble = std::numeric_limits<time_t>::min(); 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return min(max(minTimeAsDouble, time + kCFAbsoluteTimeIntervalSince1970), maxTimeAsDouble); 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid ResourceResponse::platformLazyInit(InitLevel initLevel) 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_initLevel > initLevel) 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_isNull) { 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_cfResponse.get()); 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_initLevel < CommonFieldsOnly && initLevel >= CommonFieldsOnly) { 892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_url = CFURLResponseGetURL(m_cfResponse.get()); 902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_mimeType = CFURLResponseGetMIMEType(m_cfResponse.get()); 912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_expectedContentLength = CFURLResponseGetExpectedContentLength(m_cfResponse.get()); 922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_textEncodingName = CFURLResponseGetTextEncodingName(m_cfResponse.get()); 932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Workaround for <rdar://problem/8757088>, can be removed once that is fixed. 952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned textEncodingNameLength = m_textEncodingName.length(); 962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (textEncodingNameLength >= 2 && m_textEncodingName[0U] == '"' && m_textEncodingName[textEncodingNameLength - 1] == '"') 972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_textEncodingName = m_textEncodingName.substring(1, textEncodingNameLength - 2); 982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_lastModifiedDate = toTimeT(CFURLResponseGetLastModifiedDate(m_cfResponse.get())); 1002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RetainPtr<CFStringRef> suggestedFilename(AdoptCF, CFURLResponseCopySuggestedFilename(m_cfResponse.get())); 1022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_suggestedFilename = suggestedFilename.get(); 1032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch CFHTTPMessageRef httpResponse = CFURLResponseGetHTTPResponse(m_cfResponse.get()); 1052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (httpResponse) { 1062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_httpStatusCode = CFHTTPMessageGetResponseStatusCode(httpResponse); 1072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RetainPtr<CFDictionaryRef> headers(AdoptCF, CFHTTPMessageCopyAllHeaderFields(httpResponse)); 1092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (int i = 0; i < numCommonHeaderFields; i++) { 1112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch CFStringRef value; 1122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (CFDictionaryGetValueIfPresent(headers.get(), commonHeaderFields[i], (const void **)&value)) 1132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_httpHeaderFields.set(commonHeaderFields[i], value); 1142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 1152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } else 1162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_httpStatusCode = 0; 1172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_initLevel < AllFields && initLevel >= AllFields) { 1202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch CFHTTPMessageRef httpResponse = CFURLResponseGetHTTPResponse(m_cfResponse.get()); 1212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (httpResponse) { 1222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RetainPtr<CFStringRef> statusLine(AdoptCF, CFHTTPMessageCopyResponseStatusLine(httpResponse)); 1232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_httpStatusText = extractReasonPhraseFromHTTPStatusLine(statusLine.get()); 1242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RetainPtr<CFDictionaryRef> headers(AdoptCF, CFHTTPMessageCopyAllHeaderFields(httpResponse)); 1262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch CFIndex headerCount = CFDictionaryGetCount(headers.get()); 1272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<const void*, 128> keys(headerCount); 1282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Vector<const void*, 128> values(headerCount); 1292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch CFDictionaryGetKeysAndValues(headers.get(), keys.data(), values.data()); 1302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (int i = 0; i < headerCount; ++i) 1312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_httpHeaderFields.set((CFStringRef)keys[i], (CFStringRef)values[i]); 1322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 1332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_initLevel = initLevel; 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool ResourceResponse::platformCompare(const ResourceResponse& a, const ResourceResponse& b) 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return CFEqual(a.cfURLResponse(), b.cfURLResponse()); 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 144cad810f21b803229eb11403f9209855525a25d57Steve Block} // namespace WebCore 145cad810f21b803229eb11403f9209855525a25d57Steve Block 146cad810f21b803229eb11403f9209855525a25d57Steve Block#endif // USE(CFNETWORK) 147