2 * Copyright (C) 2006, 2007, 2008 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 "ResourceRequestCFNet.h"
29 #include "FormDataStreamCFNet.h"
30 #include "ResourceRequest.h"
32 #include <CFNetwork/CFURLRequestPriv.h>
36 typedef void (*CFURLRequestSetContentDispositionEncodingFallbackArrayFunction
)(CFMutableURLRequestRef
, CFArrayRef
);
37 typedef CFArrayRef (*CFURLRequestCopyContentDispositionEncodingFallbackArrayFunction
)(CFURLRequestRef
);
39 static HMODULE
findCFNetworkModule()
41 if (HMODULE
module = GetModuleHandleA("CFNetwork"))
43 return GetModuleHandleA("CFNetwork_debug");
46 static CFURLRequestSetContentDispositionEncodingFallbackArrayFunction
findCFURLRequestSetContentDispositionEncodingFallbackArrayFunction()
48 return reinterpret_cast<CFURLRequestSetContentDispositionEncodingFallbackArrayFunction
>(GetProcAddress(findCFNetworkModule(), "_CFURLRequestSetContentDispositionEncodingFallbackArray"));
51 static CFURLRequestCopyContentDispositionEncodingFallbackArrayFunction
findCFURLRequestCopyContentDispositionEncodingFallbackArrayFunction()
53 return reinterpret_cast<CFURLRequestCopyContentDispositionEncodingFallbackArrayFunction
>(GetProcAddress(findCFNetworkModule(), "_CFURLRequestCopyContentDispositionEncodingFallbackArray"));
56 static void setContentDispositionEncodingFallbackArray(CFMutableURLRequestRef request
, CFArrayRef fallbackArray
)
58 static CFURLRequestSetContentDispositionEncodingFallbackArrayFunction function
= findCFURLRequestSetContentDispositionEncodingFallbackArrayFunction();
60 function(request
, fallbackArray
);
63 static CFArrayRef
copyContentDispositionEncodingFallbackArray(CFURLRequestRef request
)
65 static CFURLRequestCopyContentDispositionEncodingFallbackArrayFunction function
= findCFURLRequestCopyContentDispositionEncodingFallbackArrayFunction();
68 return function(request
);
71 CFURLRequestRef
ResourceRequest::cfURLRequest() const
73 updatePlatformRequest();
75 return m_cfRequest
.get();
78 static inline void addHeadersFromHashMap(CFMutableURLRequestRef request
, const HTTPHeaderMap
& requestHeaders
)
80 if (!requestHeaders
.size())
83 HTTPHeaderMap::const_iterator end
= requestHeaders
.end();
84 for (HTTPHeaderMap::const_iterator it
= requestHeaders
.begin(); it
!= end
; ++it
) {
85 CFStringRef key
= it
->first
.createCFString();
86 CFStringRef value
= it
->second
.createCFString();
87 CFURLRequestSetHTTPHeaderFieldValue(request
, key
, value
);
93 void ResourceRequest::doUpdatePlatformRequest()
95 CFMutableURLRequestRef cfRequest
;
97 RetainPtr
<CFURLRef
> url(AdoptCF
, ResourceRequest::url().createCFURL());
98 RetainPtr
<CFURLRef
> mainDocumentURL(AdoptCF
, ResourceRequest::mainDocumentURL().createCFURL());
100 cfRequest
= CFURLRequestCreateMutableCopy(0, m_cfRequest
.get());
101 CFURLRequestSetURL(cfRequest
, url
.get());
102 CFURLRequestSetMainDocumentURL(cfRequest
, mainDocumentURL
.get());
104 cfRequest
= CFURLRequestCreateMutable(0, url
.get(), (CFURLRequestCachePolicy
)cachePolicy(), timeoutInterval(), mainDocumentURL
.get());
107 RetainPtr
<CFStringRef
> requestMethod(AdoptCF
, httpMethod().createCFString());
108 CFURLRequestSetHTTPRequestMethod(cfRequest
, requestMethod
.get());
110 addHeadersFromHashMap(cfRequest
, httpHeaderFields());
111 WebCore::setHTTPBody(cfRequest
, httpBody());
112 CFURLRequestSetShouldHandleHTTPCookies(cfRequest
, allowHTTPCookies());
114 unsigned fallbackCount
= m_responseContentDispositionEncodingFallbackArray
.size();
115 RetainPtr
<CFMutableArrayRef
> encodingFallbacks(AdoptCF
, CFArrayCreateMutable(kCFAllocatorDefault
, fallbackCount
, 0));
116 for (unsigned i
= 0; i
!= fallbackCount
; ++i
) {
117 RetainPtr
<CFStringRef
> encodingName(AdoptCF
, m_responseContentDispositionEncodingFallbackArray
[i
].createCFString());
118 CFStringEncoding encoding
= CFStringConvertIANACharSetNameToEncoding(encodingName
.get());
119 if (encoding
!= kCFStringEncodingInvalidId
)
120 CFArrayAppendValue(encodingFallbacks
.get(), reinterpret_cast<const void*>(encoding
));
122 setContentDispositionEncodingFallbackArray(cfRequest
, encodingFallbacks
.get());
125 RetainPtr
<CFHTTPCookieStorageRef
> cookieStorage(AdoptCF
, CFURLRequestCopyHTTPCookieStorage(m_cfRequest
.get()));
127 CFURLRequestSetHTTPCookieStorage(cfRequest
, cookieStorage
.get());
128 CFURLRequestSetHTTPCookieStorageAcceptPolicy(cfRequest
, CFURLRequestGetHTTPCookieStorageAcceptPolicy(m_cfRequest
.get()));
129 CFURLRequestSetSSLProperties(cfRequest
, CFURLRequestGetSSLProperties(m_cfRequest
.get()));
132 m_cfRequest
.adoptCF(cfRequest
);
135 void ResourceRequest::doUpdateResourceRequest()
137 m_url
= CFURLRequestGetURL(m_cfRequest
.get());
139 m_cachePolicy
= (ResourceRequestCachePolicy
)CFURLRequestGetCachePolicy(m_cfRequest
.get());
140 m_timeoutInterval
= CFURLRequestGetTimeoutInterval(m_cfRequest
.get());
141 m_mainDocumentURL
= CFURLRequestGetMainDocumentURL(m_cfRequest
.get());
142 if (CFStringRef method
= CFURLRequestCopyHTTPRequestMethod(m_cfRequest
.get())) {
143 m_httpMethod
= method
;
146 m_allowHTTPCookies
= CFURLRequestShouldHandleHTTPCookies(m_cfRequest
.get());
148 if (CFDictionaryRef headers
= CFURLRequestCopyAllHTTPHeaderFields(m_cfRequest
.get())) {
149 CFIndex headerCount
= CFDictionaryGetCount(headers
);
150 Vector
<const void*, 128> keys(headerCount
);
151 Vector
<const void*, 128> values(headerCount
);
152 CFDictionaryGetKeysAndValues(headers
, keys
.data(), values
.data());
153 for (int i
= 0; i
< headerCount
; ++i
)
154 m_httpHeaderFields
.set((CFStringRef
)keys
[i
], (CFStringRef
)values
[i
]);
158 m_responseContentDispositionEncodingFallbackArray
.clear();
159 RetainPtr
<CFArrayRef
> encodingFallbacks(AdoptCF
, copyContentDispositionEncodingFallbackArray(m_cfRequest
.get()));
160 if (encodingFallbacks
) {
161 CFIndex count
= CFArrayGetCount(encodingFallbacks
.get());
162 for (CFIndex i
= 0; i
< count
; ++i
) {
163 CFStringEncoding encoding
= reinterpret_cast<CFIndex
>(CFArrayGetValueAtIndex(encodingFallbacks
.get(), i
));
164 if (encoding
!= kCFStringEncodingInvalidId
)
165 m_responseContentDispositionEncodingFallbackArray
.append(CFStringGetNameOfEncoding(encoding
));
169 m_httpBody
= httpBodyFromRequest(m_cfRequest
.get());