5ae80327e1803e59f2595abac879186954cd5b00
[WebKit-https.git] / Source / WebKit2 / Shared / soup / WebCoreArgumentCodersSoup.cpp
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
4  * Portions Copyright (c) 2013 Company 100 Inc. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25  * THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "config.h"
29 #include "DataReference.h"
30 #include "WebCoreArgumentCoders.h"
31
32 #include <WebCore/CertificateInfo.h>
33 #include <WebCore/ResourceError.h>
34 #include <WebCore/ResourceRequest.h>
35 #include <WebCore/ResourceResponse.h>
36 #include <wtf/text/CString.h>
37
38 using namespace WebCore;
39
40 namespace IPC {
41
42 void ArgumentCoder<ResourceRequest>::encodePlatformData(ArgumentEncoder& encoder, const ResourceRequest& resourceRequest)
43 {
44     encoder << resourceRequest.url().string();
45     encoder << resourceRequest.httpMethod();
46     encoder << resourceRequest.httpHeaderFields();
47
48     // FIXME: Do not encode HTTP message body.
49     // 1. It can be large and thus costly to send across.
50     // 2. It is misleading to provide a body with some requests, while others use body streams, which cannot be serialized at all.
51     FormData* httpBody = resourceRequest.httpBody();
52     encoder << static_cast<bool>(httpBody);
53     if (httpBody)
54         encoder << httpBody->flattenToString();
55
56     encoder << resourceRequest.firstPartyForCookies().string();
57
58     encoder << static_cast<uint32_t>(resourceRequest.soupMessageFlags());
59     encoder << resourceRequest.initiatingPageID();
60 }
61
62 bool ArgumentCoder<ResourceRequest>::decodePlatformData(ArgumentDecoder& decoder, ResourceRequest& resourceRequest)
63 {
64     String url;
65     if (!decoder.decode(url))
66         return false;
67     resourceRequest.setURL(URL(URL(), url));
68
69     String httpMethod;
70     if (!decoder.decode(httpMethod))
71         return false;
72     resourceRequest.setHTTPMethod(httpMethod);
73
74     HTTPHeaderMap headers;
75     if (!decoder.decode(headers))
76         return false;
77     resourceRequest.setHTTPHeaderFields(WTF::move(headers));
78
79     bool hasHTTPBody;
80     if (!decoder.decode(hasHTTPBody))
81         return false;
82     if (hasHTTPBody) {
83         String httpBody;
84         if (!decoder.decode(httpBody))
85             return false;
86         resourceRequest.setHTTPBody(FormData::create(httpBody.utf8()));
87     }
88
89     String firstPartyForCookies;
90     if (!decoder.decode(firstPartyForCookies))
91         return false;
92     resourceRequest.setFirstPartyForCookies(URL(URL(), firstPartyForCookies));
93
94     uint32_t soupMessageFlags;
95     if (!decoder.decode(soupMessageFlags))
96         return false;
97     resourceRequest.setSoupMessageFlags(static_cast<SoupMessageFlags>(soupMessageFlags));
98
99     uint64_t initiatingPageID;
100     if (!decoder.decode(initiatingPageID))
101         return false;
102     resourceRequest.setInitiatingPageID(initiatingPageID);
103
104     return true;
105 }
106
107 void ArgumentCoder<ResourceResponse>::encodePlatformData(ArgumentEncoder& encoder, const ResourceResponse& resourceResponse)
108 {
109     encoder << static_cast<uint32_t>(resourceResponse.soupMessageFlags());
110 }
111
112 bool ArgumentCoder<ResourceResponse>::decodePlatformData(ArgumentDecoder& decoder, ResourceResponse& resourceResponse)
113 {
114     uint32_t soupMessageFlags;
115     if (!decoder.decode(soupMessageFlags))
116         return false;
117     resourceResponse.setSoupMessageFlags(static_cast<SoupMessageFlags>(soupMessageFlags));
118     return true;
119 }
120
121 void ArgumentCoder<CertificateInfo>::encode(ArgumentEncoder& encoder, const CertificateInfo& certificateInfo)
122 {
123     if (!certificateInfo.certificate()) {
124         encoder << false;
125         return;
126     }
127
128     GByteArray* certificateData = 0;
129     g_object_get(G_OBJECT(certificateInfo.certificate()), "certificate", &certificateData, NULL);
130     if (!certificateData) {
131         encoder << false;
132         return;
133     }
134
135     encoder << true;
136     GRefPtr<GByteArray> certificate = adoptGRef(certificateData);
137     encoder.encodeVariableLengthByteArray(IPC::DataReference(certificate->data, certificate->len));
138     encoder << static_cast<uint32_t>(certificateInfo.tlsErrors());
139 }
140
141 bool ArgumentCoder<CertificateInfo>::decode(ArgumentDecoder& decoder, CertificateInfo& certificateInfo)
142 {
143     bool hasCertificate;
144     if (!decoder.decode(hasCertificate))
145         return false;
146
147     if (!hasCertificate)
148         return true;
149
150     IPC::DataReference certificateDataReference;
151     if (!decoder.decodeVariableLengthByteArray(certificateDataReference))
152         return false;
153
154     GByteArray* certificateData = g_byte_array_sized_new(certificateDataReference.size());
155     certificateData = g_byte_array_append(certificateData, certificateDataReference.data(), certificateDataReference.size());
156     GRefPtr<GByteArray> certificateBytes = adoptGRef(certificateData);
157
158     GTlsBackend* backend = g_tls_backend_get_default();
159     GRefPtr<GTlsCertificate> certificate = adoptGRef(G_TLS_CERTIFICATE(g_initable_new(
160         g_tls_backend_get_certificate_type(backend), 0, 0, "certificate", certificateBytes.get(), nullptr)));
161     certificateInfo.setCertificate(certificate.get());
162
163     uint32_t tlsErrors;
164     if (!decoder.decode(tlsErrors))
165         return false;
166     certificateInfo.setTLSErrors(static_cast<GTlsCertificateFlags>(tlsErrors));
167
168     return true;
169 }
170
171 void ArgumentCoder<ResourceError>::encodePlatformData(ArgumentEncoder& encoder, const ResourceError& resourceError)
172 {
173     bool errorIsNull = resourceError.isNull();
174     encoder << errorIsNull;
175     if (errorIsNull)
176         return;
177
178     encoder << resourceError.domain();
179     encoder << resourceError.errorCode();
180     encoder << resourceError.failingURL();
181     encoder << resourceError.localizedDescription();
182     encoder << resourceError.isCancellation();
183     encoder << resourceError.isTimeout();
184
185     encoder << CertificateInfo(resourceError);
186 }
187
188 bool ArgumentCoder<ResourceError>::decodePlatformData(ArgumentDecoder& decoder, ResourceError& resourceError)
189 {
190     bool errorIsNull;
191     if (!decoder.decode(errorIsNull))
192         return false;
193     if (errorIsNull) {
194         resourceError = ResourceError();
195         return true;
196     }
197
198     String domain;
199     if (!decoder.decode(domain))
200         return false;
201
202     int errorCode;
203     if (!decoder.decode(errorCode))
204         return false;
205
206     String failingURL;
207     if (!decoder.decode(failingURL))
208         return false;
209
210     String localizedDescription;
211     if (!decoder.decode(localizedDescription))
212         return false;
213
214     bool isCancellation;
215     if (!decoder.decode(isCancellation))
216         return false;
217
218     bool isTimeout;
219     if (!decoder.decode(isTimeout))
220         return false;
221
222     resourceError = ResourceError(domain, errorCode, failingURL, localizedDescription);
223     resourceError.setIsCancellation(isCancellation);
224     resourceError.setIsTimeout(isTimeout);
225
226     CertificateInfo certificateInfo;
227     if (!decoder.decode(certificateInfo))
228         return false;
229
230     resourceError.setCertificate(certificateInfo.certificate());
231     resourceError.setTLSErrors(certificateInfo.tlsErrors());
232     return true;
233 }
234
235 void ArgumentCoder<ProtectionSpace>::encodePlatformData(ArgumentEncoder&, const ProtectionSpace&)
236 {
237     ASSERT_NOT_REACHED();
238 }
239
240 bool ArgumentCoder<ProtectionSpace>::decodePlatformData(ArgumentDecoder&, ProtectionSpace&)
241 {
242     ASSERT_NOT_REACHED();
243     return false;
244 }
245
246 void ArgumentCoder<Credential>::encodePlatformData(ArgumentEncoder&, const Credential&)
247 {
248     ASSERT_NOT_REACHED();
249 }
250
251 bool ArgumentCoder<Credential>::decodePlatformData(ArgumentDecoder&, Credential&)
252 {
253     ASSERT_NOT_REACHED();
254     return false;
255 }
256
257 }
258