911d2e73778c9ef5aa8f5b3239cdbc8d54126228
[WebKit-https.git] / Source / WebKit / Shared / SessionState.cpp
1 /*
2  * Copyright (C) 2014 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 "SessionState.h"
28
29 #include "WebCoreArgumentCoders.h"
30
31 using namespace WebCore;
32
33 namespace WebKit {
34
35 bool isValidEnum(WebCore::ShouldOpenExternalURLsPolicy policy)
36 {
37     switch (policy) {
38     case WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow:
39     case WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes:
40     case WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow:
41         return true;
42     }
43     return false;
44 }
45
46 void HTTPBody::Element::encode(IPC::Encoder& encoder) const
47 {
48     encoder.encodeEnum(type);
49     encoder << data;
50     encoder << filePath;
51     encoder << fileStart;
52     encoder << fileLength;
53     encoder << expectedFileModificationTime;
54     encoder << blobURLString;
55 }
56
57 static bool isValidEnum(HTTPBody::Element::Type type)
58 {
59     switch (type) {
60     case HTTPBody::Element::Type::Data:
61     case HTTPBody::Element::Type::File:
62     case HTTPBody::Element::Type::Blob:
63         return true;
64     }
65
66     return false;
67 }
68
69 auto HTTPBody::Element::decode(IPC::Decoder& decoder) -> std::optional<Element>
70 {
71     Element result;
72     if (!decoder.decodeEnum(result.type) || !isValidEnum(result.type))
73         return std::nullopt;
74     if (!decoder.decode(result.data))
75         return std::nullopt;
76     if (!decoder.decode(result.filePath))
77         return std::nullopt;
78     if (!decoder.decode(result.fileStart))
79         return std::nullopt;
80     if (!decoder.decode(result.fileLength))
81         return std::nullopt;
82     if (!decoder.decode(result.expectedFileModificationTime))
83         return std::nullopt;
84     if (!decoder.decode(result.blobURLString))
85         return std::nullopt;
86
87     return WTFMove(result);
88 }
89
90 void HTTPBody::encode(IPC::Encoder& encoder) const
91 {
92     encoder << contentType;
93     encoder << elements;
94 }
95
96 bool HTTPBody::decode(IPC::Decoder& decoder, HTTPBody& result)
97 {
98     if (!decoder.decode(result.contentType))
99         return false;
100     if (!decoder.decode(result.elements))
101         return false;
102
103     return true;
104 }
105
106 void FrameState::encode(IPC::Encoder& encoder) const
107 {
108     encoder << urlString;
109     encoder << originalURLString;
110     encoder << referrer;
111     encoder << target;
112
113     encoder << documentState;
114     encoder << stateObjectData;
115
116     encoder << documentSequenceNumber;
117     encoder << itemSequenceNumber;
118
119     encoder << scrollPosition;
120     encoder << shouldRestoreScrollPosition;
121     encoder << pageScaleFactor;
122
123     encoder << httpBody;
124
125 #if PLATFORM(IOS)
126     encoder << exposedContentRect;
127     encoder << unobscuredContentRect;
128     encoder << minimumLayoutSizeInScrollViewCoordinates;
129     encoder << contentSize;
130     encoder << scaleIsInitial;
131 #endif
132
133     encoder << children;
134 }
135
136 std::optional<FrameState> FrameState::decode(IPC::Decoder& decoder)
137 {
138     FrameState result;
139     if (!decoder.decode(result.urlString))
140         return std::nullopt;
141     if (!decoder.decode(result.originalURLString))
142         return std::nullopt;
143     if (!decoder.decode(result.referrer))
144         return std::nullopt;
145     if (!decoder.decode(result.target))
146         return std::nullopt;
147
148     if (!decoder.decode(result.documentState))
149         return std::nullopt;
150     if (!decoder.decode(result.stateObjectData))
151         return std::nullopt;
152
153     if (!decoder.decode(result.documentSequenceNumber))
154         return std::nullopt;
155     if (!decoder.decode(result.itemSequenceNumber))
156         return std::nullopt;
157
158     if (!decoder.decode(result.scrollPosition))
159         return std::nullopt;
160     if (!decoder.decode(result.shouldRestoreScrollPosition))
161         return std::nullopt;
162     if (!decoder.decode(result.pageScaleFactor))
163         return std::nullopt;
164
165     if (!decoder.decode(result.httpBody))
166         return std::nullopt;
167
168 #if PLATFORM(IOS)
169     if (!decoder.decode(result.exposedContentRect))
170         return std::nullopt;
171     if (!decoder.decode(result.unobscuredContentRect))
172         return std::nullopt;
173     if (!decoder.decode(result.minimumLayoutSizeInScrollViewCoordinates))
174         return std::nullopt;
175     if (!decoder.decode(result.contentSize))
176         return std::nullopt;
177     if (!decoder.decode(result.scaleIsInitial))
178         return std::nullopt;
179 #endif
180
181     if (!decoder.decode(result.children))
182         return std::nullopt;
183
184     return WTFMove(result);
185 }
186
187 void PageState::encode(IPC::Encoder& encoder) const
188 {
189     encoder << title << mainFrameState << !!sessionStateObject;
190
191     if (sessionStateObject)
192         encoder << sessionStateObject->toWireBytes();
193
194     encoder.encodeEnum(shouldOpenExternalURLsPolicy);
195 }
196
197 bool PageState::decode(IPC::Decoder& decoder, PageState& result)
198 {
199     if (!decoder.decode(result.title))
200         return false;
201     std::optional<FrameState> mainFrameState;
202     decoder >> mainFrameState;
203     if (!mainFrameState)
204         return false;
205     result.mainFrameState = WTFMove(*mainFrameState);
206
207     bool hasSessionState;
208     if (!decoder.decode(hasSessionState))
209         return false;
210
211     if (hasSessionState) {
212         Vector<uint8_t> wireBytes;
213         if (!decoder.decode(wireBytes))
214             return false;
215
216         result.sessionStateObject = SerializedScriptValue::createFromWireBytes(WTFMove(wireBytes));
217     }
218
219     if (!decoder.decodeEnum(result.shouldOpenExternalURLsPolicy) || !isValidEnum(result.shouldOpenExternalURLsPolicy))
220         return false;
221
222     return true;
223 }
224
225 void BackForwardListItemState::encode(IPC::Encoder& encoder) const
226 {
227     encoder << identifier;
228     encoder << pageState;
229 }
230
231 std::optional<BackForwardListItemState> BackForwardListItemState::decode(IPC::Decoder& decoder)
232 {
233     BackForwardListItemState result;
234
235     if (!decoder.decode(result.identifier))
236         return std::nullopt;
237
238     if (!decoder.decode(result.pageState))
239         return std::nullopt;
240
241     return WTFMove(result);
242 }
243
244 void BackForwardListState::encode(IPC::Encoder& encoder) const
245 {
246     encoder << items;
247     encoder << currentIndex;
248 }
249
250 std::optional<BackForwardListState> BackForwardListState::decode(IPC::Decoder& decoder)
251 {
252     std::optional<Vector<BackForwardListItemState>> items;
253     decoder >> items;
254     if (!items)
255         return std::nullopt;
256
257     std::optional<uint32_t> currentIndex;
258     if (!decoder.decode(currentIndex))
259         return std::nullopt;
260
261     return {{ WTFMove(*items), WTFMove(currentIndex) }};
262 }
263
264 } // namespace WebKit