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