Reviewed by Adele.
[WebKit-https.git] / WebCore / platform / network / cf / ResourceRequestCFNet.cpp
1 // -*- mode: c++; c-basic-offset: 4 -*-
2 /*
3  * Copyright (C) 2006 Apple Computer, 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 #include "config.h"
28 #include "ResourceRequestCFNet.h"
29
30 #include "FormDataStreamCFNet.h"
31 #include "ResourceRequest.h"
32
33 #include <CFNetwork/CFURLRequestPriv.h>
34
35 namespace WebCore {
36     
37     void getResourceRequest(ResourceRequest& request, CFURLRequestRef cfRequest)
38     {
39         request = ResourceRequest(CFURLRequestGetURL(cfRequest));
40
41         request.setCachePolicy((ResourceRequestCachePolicy)CFURLRequestGetCachePolicy(cfRequest));
42         request.setTimeoutInterval(CFURLRequestGetTimeoutInterval(cfRequest));
43         request.setMainDocumentURL(KURL(CFURLRequestGetMainDocumentURL(cfRequest)));
44         if (CFStringRef method = CFURLRequestCopyHTTPRequestMethod(cfRequest)) {
45             request.setHTTPMethod(method);
46             CFRelease(method);
47         }
48         request.setAllowHTTPCookies(CFURLRequestShouldHandleHTTPCookies(cfRequest));
49
50         if (CFDictionaryRef headers = CFURLRequestCopyAllHTTPHeaderFields(cfRequest)) {
51             CFIndex headerCount = CFDictionaryGetCount(headers);
52             Vector<const void*, 128> keys(headerCount);
53             Vector<const void*, 128> values(headerCount);
54             CFDictionaryGetKeysAndValues(headers, keys.data(), values.data());
55             for (int i = 0; i < headerCount; ++i)
56                 request.setHTTPHeaderField((CFStringRef)keys[i], (CFStringRef)values[i]);
57             CFRelease(headers);
58         }
59        
60
61         if (CFDataRef bodyData = CFURLRequestCopyHTTPRequestBody(cfRequest)) {
62             request.setHTTPBody(FormData(CFDataGetBytePtr(bodyData), CFDataGetLength(bodyData)));
63             CFRelease(bodyData);
64         } else if (CFReadStreamRef bodyStream = CFURLRequestCopyHTTPRequestBodyStream(cfRequest)) {
65             if (const FormData* formData = httpBodyFromStream(bodyStream))
66                 request.setHTTPBody(*formData);
67             CFRelease(bodyStream);
68         }
69         // FIXME: what to do about arbitrary body streams?
70     }
71
72     static void addHeadersFromHashMap(CFMutableURLRequestRef request, const HTTPHeaderMap& requestHeaders) 
73     {
74         if (!requestHeaders.size())
75             return;
76         
77         HTTPHeaderMap::const_iterator end = requestHeaders.end();
78         for (HTTPHeaderMap::const_iterator it = requestHeaders.begin(); it != end; ++it) {
79             CFStringRef key = it->first.createCFString();
80             CFStringRef value = it->second.createCFString();
81             CFURLRequestSetHTTPHeaderFieldValue(request, key, value);
82             CFRelease(key);
83             CFRelease(value);
84         }
85     }
86
87     CFURLRequestRef cfURLRequest(const ResourceRequest& request)
88     {
89         CFURLRef url = request.url().createCFURL();
90         CFURLRef mainDocumentURL = request.mainDocumentURL().createCFURL();
91
92         CFMutableURLRequestRef cfRequest = CFURLRequestCreateMutable(0, url, (CFURLRequestCachePolicy)request.cachePolicy(), request.timeoutInterval(), mainDocumentURL);
93
94         CFRelease(url);
95         CFRelease(mainDocumentURL);
96
97         CFStringRef requestMethod = request.httpMethod().createCFString();
98         CFURLRequestSetHTTPRequestMethod(cfRequest, requestMethod);
99         CFRelease(requestMethod);
100
101         addHeadersFromHashMap(cfRequest, request.httpHeaderFields());
102         setHTTPBody(cfRequest, request.httpBody());
103         CFURLRequestSetShouldHandleHTTPCookies(cfRequest, request.allowHTTPCookies());
104
105         return cfRequest;
106     }
107
108 }