2011-03-28 Jeff Miller <jeffm@apple.com>
[WebKit-https.git] / Source / WebKit2 / Shared / win / WebCoreArgumentCodersWin.cpp
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebCoreArgumentCoders.h"
28
29 #if USE(CFNETWORK)
30 #include "ArgumentCodersCF.h"
31 #include "PlatformCertificateInfo.h"
32 #include <WebKitSystemInterface/WebKitSystemInterface.h>
33 #endif
34
35 namespace CoreIPC {
36
37 // FIXME: These coders should really go in a WebCoreArgumentCodersCFNetwork file.
38
39 void encodeResourceRequest(ArgumentEncoder* encoder, const WebCore::ResourceRequest& resourceRequest)
40 {
41 #if USE(CFNETWORK)
42     bool requestIsPresent = resourceRequest.cfURLRequest();
43     encoder->encode(requestIsPresent);
44
45     if (!requestIsPresent)
46         return;
47
48     RetainPtr<CFDictionaryRef> dictionary(AdoptCF, wkCFURLRequestCreateSerializableRepresentation(resourceRequest.cfURLRequest(), CoreIPC::tokenNullTypeRef()));
49     encode(encoder, dictionary.get());
50 #endif
51 }
52
53 bool decodeResourceRequest(ArgumentDecoder* decoder, WebCore::ResourceRequest& resourceRequest)
54 {
55 #if USE(CFNETWORK)
56     bool requestIsPresent;
57     if (!decoder->decode(requestIsPresent))
58         return false;
59
60     if (!requestIsPresent) {
61         resourceRequest = WebCore::ResourceRequest();
62         return true;
63     }
64
65     RetainPtr<CFDictionaryRef> dictionary;
66     if (!decode(decoder, dictionary))
67         return false;
68
69     CFURLRequestRef cfURLRequest = wkCFURLRequestCreateFromSerializableRepresentation(dictionary.get(), CoreIPC::tokenNullTypeRef());
70     if (!cfURLRequest)
71         return false;
72
73     resourceRequest = WebCore::ResourceRequest(cfURLRequest);
74     return true;
75 #else
76     return false;
77 #endif
78 }
79
80 void encodeResourceResponse(ArgumentEncoder* encoder, const WebCore::ResourceResponse& resourceResponse)
81 {
82 #if USE(CFNETWORK)
83     bool responseIsPresent = resourceResponse.cfURLResponse();
84     encoder->encode(responseIsPresent);
85
86     if (!responseIsPresent)
87         return;
88
89     RetainPtr<CFDictionaryRef> dictionary(AdoptCF, wkCFURLResponseCreateSerializableRepresentation(resourceResponse.cfURLResponse(), CoreIPC::tokenNullTypeRef()));
90     encode(encoder, dictionary.get());
91 #endif
92 }
93
94 bool decodeResourceResponse(ArgumentDecoder* decoder, WebCore::ResourceResponse& resourceResponse)
95 {
96 #if USE(CFNETWORK)
97     bool responseIsPresent;
98     if (!decoder->decode(responseIsPresent))
99         return false;
100
101     if (!responseIsPresent) {
102         resourceResponse = WebCore::ResourceResponse();
103         return true;
104     }
105
106     RetainPtr<CFDictionaryRef> dictionary;
107     if (!decode(decoder, dictionary))
108         return false;
109
110     CFURLResponseRef cfURLResponse = wkCFURLResponseCreateFromSerializableRepresentation(dictionary.get(), CoreIPC::tokenNullTypeRef());
111     if (!cfURLResponse)
112         return false;
113
114     resourceResponse = WebCore::ResourceResponse(cfURLResponse);
115     return true;
116 #else
117     return false;
118 #endif
119 }
120
121 void encodeResourceError(ArgumentEncoder* encoder, const WebCore::ResourceError& resourceError)
122 {
123     encoder->encode(CoreIPC::In(resourceError.domain(), resourceError.errorCode(), resourceError.failingURL(), resourceError.localizedDescription()));
124
125 #if USE(CFNETWORK)
126     CFErrorRef cfError = resourceError.cfError();
127     if (!cfError) {
128         encoder->encode(WebKit::PlatformCertificateInfo());
129         return;
130     }
131     
132     CFDataRef certificateData = resourceError.certificate();
133     if (!certificateData) {
134         encoder->encode(WebKit::PlatformCertificateInfo());
135         return;
136     }
137
138     PCCERT_CONTEXT certificate = reinterpret_cast<PCCERT_CONTEXT>(CFDataGetBytePtr(certificateData));
139     if (!certificate) {
140         encoder->encode(WebKit::PlatformCertificateInfo());
141         return;
142     }
143     
144     encoder->encode(WebKit::PlatformCertificateInfo(certificate));
145 #endif
146 }
147
148 #if USE(CFNETWORK)
149 static void deallocCertContext(void* ptr, void* info)
150 {
151     if (ptr)
152         CertFreeCertificateContext(static_cast<PCCERT_CONTEXT>(ptr));
153 }
154
155 static CFAllocatorRef createCertContextDeallocator()
156 {
157     CFAllocatorContext allocContext = {
158         0, 0, 0, 0, 0, 0, 0, deallocCertContext, 0
159     };
160     return CFAllocatorCreate(kCFAllocatorDefault, &allocContext);
161 }
162
163 static CFDataRef copyCert(PCCERT_CONTEXT cert)
164 {
165     static CFAllocatorRef certDealloc = createCertContextDeallocator();
166     PCCERT_CONTEXT certCopy = CertDuplicateCertificateContext(cert);
167     return CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(certCopy), sizeof(*certCopy), certDealloc);
168 }
169 #endif // USE(CFNETWORK)
170
171 bool decodeResourceError(ArgumentDecoder* decoder, WebCore::ResourceError& resourceError)
172 {
173     String domain;
174     int errorCode;
175     String failingURL;
176     String localizedDescription;
177     if (!decoder->decode(CoreIPC::Out(domain, errorCode, failingURL, localizedDescription)))
178         return false;
179
180 #if USE(CFNETWORK)
181     WebKit::PlatformCertificateInfo certificate;
182     if (!decoder->decode(certificate))
183         return false;
184     
185     const Vector<PCCERT_CONTEXT> certificateChain = certificate.certificateChain();
186     if (!certificateChain.isEmpty()) {
187         ASSERT(certificateChain.size() == 1);
188         resourceError = WebCore::ResourceError(domain, errorCode, failingURL, localizedDescription, copyCert(certificateChain.first()));
189         return true;
190     }
191 #endif
192
193     resourceError = WebCore::ResourceError(domain, errorCode, failingURL, localizedDescription);
194     return true;
195 }
196
197 } // namespace CoreIPC