mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-15 23:09:05 +00:00
LibWeb+LibWebView: Add an internal API to expire cookies with an offset
Cookies have a minimum expiry resolution of 1 second. So to test cookie expiration, the test had to idle for at least a second, which is quite a noticeable delay now that LibWeb tests are parallelized. Instead, we can add an internal API to expire cookies with a time offset to avoid this idle delay.
This commit is contained in:
parent
6ce473af72
commit
e070ed5658
Notes:
github-actions[bot]
2024-10-14 06:54:34 +00:00
Author: https://github.com/trflynn89
Commit: e070ed5658
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1771
Reviewed-by: https://github.com/shannonbooth
13 changed files with 51 additions and 24 deletions
|
@ -16,10 +16,10 @@ SameSite=Lax: "cookie=value"
|
||||||
SameSite=Strict: "cookie=value"
|
SameSite=Strict: "cookie=value"
|
||||||
SameSite=None: ""
|
SameSite=None: ""
|
||||||
Max-Age (before expiration): "cookie-max-age1=value; cookie-max-age2=value"
|
Max-Age (before expiration): "cookie-max-age1=value; cookie-max-age2=value"
|
||||||
Expires (before expiration): "cookie-expires=value; cookie-max-age1=value; cookie-max-age2=value"
|
|
||||||
Max-Age (after expiration): "cookie-max-age2=value"
|
Max-Age (after expiration): "cookie-max-age2=value"
|
||||||
Expires (after expiration): ""
|
|
||||||
Max-Age in past: ""
|
Max-Age in past: ""
|
||||||
|
Expires (before expiration): "cookie-expires=value"
|
||||||
|
Expires (after expiration): ""
|
||||||
Expires in past: ""
|
Expires in past: ""
|
||||||
Invalid expiry (date does not exist): "cookie=value"
|
Invalid expiry (date does not exist): "cookie=value"
|
||||||
Invalid expiry (missing time): "cookie=value"
|
Invalid expiry (missing time): "cookie=value"
|
||||||
|
|
|
@ -122,13 +122,12 @@
|
||||||
deleteCookie("cookie");
|
deleteCookie("cookie");
|
||||||
};
|
};
|
||||||
|
|
||||||
const maxAgeTest1 = () => {
|
const maxAgeTest = () => {
|
||||||
document.cookie = "cookie-max-age1=value; max-age=1";
|
document.cookie = "cookie-max-age1=value; max-age=1";
|
||||||
document.cookie = `cookie-max-age2=value; max-age=${"1".repeat(1024)}`;
|
document.cookie = `cookie-max-age2=value; max-age=${"1".repeat(1024)}`;
|
||||||
printCookies("Max-Age (before expiration)");
|
printCookies("Max-Age (before expiration)");
|
||||||
};
|
|
||||||
|
|
||||||
const maxAgeTest2 = () => {
|
internals.expireCookiesWithTimeOffset(2);
|
||||||
printCookies("Max-Age (after expiration)");
|
printCookies("Max-Age (after expiration)");
|
||||||
deleteCookie("cookie-max-age2");
|
deleteCookie("cookie-max-age2");
|
||||||
};
|
};
|
||||||
|
@ -139,15 +138,14 @@
|
||||||
printCookies("Max-Age in past");
|
printCookies("Max-Age in past");
|
||||||
};
|
};
|
||||||
|
|
||||||
const expiresTest1 = () => {
|
const expiresTest = () => {
|
||||||
let expiry = new Date(Date.now() + 1000);
|
let expiry = new Date(Date.now() + 1000);
|
||||||
expiry = expiry.toUTCString();
|
expiry = expiry.toUTCString();
|
||||||
|
|
||||||
document.cookie = `cookie-expires=value; expires=${expiry}`;
|
document.cookie = `cookie-expires=value; expires=${expiry}`;
|
||||||
printCookies("Expires (before expiration)");
|
printCookies("Expires (before expiration)");
|
||||||
};
|
|
||||||
|
|
||||||
const expiresTest2 = () => {
|
internals.expireCookiesWithTimeOffset(2);
|
||||||
printCookies("Expires (after expiration)");
|
printCookies("Expires (after expiration)");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -179,7 +177,7 @@
|
||||||
deleteCookie("cookie");
|
deleteCookie("cookie");
|
||||||
};
|
};
|
||||||
|
|
||||||
asyncTest(done => {
|
test(() => {
|
||||||
basicTest();
|
basicTest();
|
||||||
multipleCookiesTest();
|
multipleCookiesTest();
|
||||||
|
|
||||||
|
@ -200,18 +198,11 @@
|
||||||
publicSuffixTest();
|
publicSuffixTest();
|
||||||
sameSiteTest();
|
sameSiteTest();
|
||||||
|
|
||||||
maxAgeTest1();
|
maxAgeTest();
|
||||||
expiresTest1();
|
maxAgeInPastTest();
|
||||||
|
|
||||||
setTimeout(() => {
|
expiresTest();
|
||||||
maxAgeTest2();
|
expiresInPastTest();
|
||||||
expiresTest2();
|
invalidExpiryTest();
|
||||||
|
|
||||||
maxAgeInPastTest();
|
|
||||||
expiresInPastTest();
|
|
||||||
invalidExpiryTest();
|
|
||||||
|
|
||||||
done();
|
|
||||||
}, 1200);
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -184,4 +184,9 @@ void Internals::simulate_drop(double x, double y)
|
||||||
page.handle_drag_and_drop_event(DragEvent::Type::Drop, position, position, UIEvents::MouseButton::Primary, 0, 0, {});
|
page.handle_drag_and_drop_event(DragEvent::Type::Drop, position, position, UIEvents::MouseButton::Primary, 0, 0, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Internals::expire_cookies_with_time_offset(WebIDL::LongLong seconds)
|
||||||
|
{
|
||||||
|
internals_page().client().page_did_expire_cookies_with_time_offset(AK::Duration::from_seconds(seconds));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,8 @@ public:
|
||||||
void simulate_drag_move(double x, double y);
|
void simulate_drag_move(double x, double y);
|
||||||
void simulate_drop(double x, double y);
|
void simulate_drop(double x, double y);
|
||||||
|
|
||||||
|
void expire_cookies_with_time_offset(WebIDL::LongLong seconds);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Internals(JS::Realm&);
|
explicit Internals(JS::Realm&);
|
||||||
virtual void initialize(JS::Realm&) override;
|
virtual void initialize(JS::Realm&) override;
|
||||||
|
|
|
@ -33,4 +33,6 @@ interface Internals {
|
||||||
undefined simulateDragStart(double x, double y, DOMString mimeType, DOMString contents);
|
undefined simulateDragStart(double x, double y, DOMString mimeType, DOMString contents);
|
||||||
undefined simulateDragMove(double x, double y);
|
undefined simulateDragMove(double x, double y);
|
||||||
undefined simulateDrop(double x, double y);
|
undefined simulateDrop(double x, double y);
|
||||||
|
|
||||||
|
undefined expireCookiesWithTimeOffset(long long seconds);
|
||||||
};
|
};
|
||||||
|
|
|
@ -343,6 +343,7 @@ public:
|
||||||
virtual String page_did_request_cookie(URL::URL const&, Cookie::Source) { return {}; }
|
virtual String page_did_request_cookie(URL::URL const&, Cookie::Source) { return {}; }
|
||||||
virtual void page_did_set_cookie(URL::URL const&, Cookie::ParsedCookie const&, Cookie::Source) { }
|
virtual void page_did_set_cookie(URL::URL const&, Cookie::ParsedCookie const&, Cookie::Source) { }
|
||||||
virtual void page_did_update_cookie(Web::Cookie::Cookie) { }
|
virtual void page_did_update_cookie(Web::Cookie::Cookie) { }
|
||||||
|
virtual void page_did_expire_cookies_with_time_offset(AK::Duration) { }
|
||||||
virtual void page_did_update_resource_count(i32) { }
|
virtual void page_did_update_resource_count(i32) { }
|
||||||
struct NewWebViewResult {
|
struct NewWebViewResult {
|
||||||
JS::GCPtr<Page> page;
|
JS::GCPtr<Page> page;
|
||||||
|
|
|
@ -213,6 +213,11 @@ Optional<Web::Cookie::Cookie> CookieJar::get_named_cookie(URL::URL const& url, S
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CookieJar::expire_cookies_with_time_offset(AK::Duration offset)
|
||||||
|
{
|
||||||
|
m_transient_storage.purge_expired_cookies(offset);
|
||||||
|
}
|
||||||
|
|
||||||
// https://www.ietf.org/archive/id/draft-ietf-httpbis-rfc6265bis-15.html#section-5.1.2
|
// https://www.ietf.org/archive/id/draft-ietf-httpbis-rfc6265bis-15.html#section-5.1.2
|
||||||
Optional<String> CookieJar::canonicalize_domain(const URL::URL& url)
|
Optional<String> CookieJar::canonicalize_domain(const URL::URL& url)
|
||||||
{
|
{
|
||||||
|
@ -643,12 +648,19 @@ Optional<Web::Cookie::Cookie> CookieJar::TransientStorage::get_cookie(CookieStor
|
||||||
return m_cookies.get(key);
|
return m_cookies.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnixDateTime CookieJar::TransientStorage::purge_expired_cookies()
|
UnixDateTime CookieJar::TransientStorage::purge_expired_cookies(Optional<AK::Duration> offset)
|
||||||
{
|
{
|
||||||
auto now = UnixDateTime::now();
|
auto now = UnixDateTime::now();
|
||||||
auto is_expired = [&](auto const&, auto const& cookie) { return cookie.expiry_time < now; };
|
if (offset.has_value()) {
|
||||||
|
now += *offset;
|
||||||
|
|
||||||
|
for (auto& cookie : m_dirty_cookies)
|
||||||
|
cookie.value.expiry_time -= *offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto is_expired = [&](auto const&, auto const& cookie) { return cookie.expiry_time < now; };
|
||||||
m_cookies.remove_all_matching(is_expired);
|
m_cookies.remove_all_matching(is_expired);
|
||||||
|
|
||||||
return now;
|
return now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ class CookieJar {
|
||||||
|
|
||||||
size_t size() const { return m_cookies.size(); }
|
size_t size() const { return m_cookies.size(); }
|
||||||
|
|
||||||
UnixDateTime purge_expired_cookies();
|
UnixDateTime purge_expired_cookies(Optional<AK::Duration> offset = {});
|
||||||
|
|
||||||
auto take_dirty_cookies() { return move(m_dirty_cookies); }
|
auto take_dirty_cookies() { return move(m_dirty_cookies); }
|
||||||
|
|
||||||
|
@ -94,6 +94,7 @@ public:
|
||||||
Vector<Web::Cookie::Cookie> get_all_cookies();
|
Vector<Web::Cookie::Cookie> get_all_cookies();
|
||||||
Vector<Web::Cookie::Cookie> get_all_cookies(URL::URL const& url);
|
Vector<Web::Cookie::Cookie> get_all_cookies(URL::URL const& url);
|
||||||
Optional<Web::Cookie::Cookie> get_named_cookie(URL::URL const& url, StringView name);
|
Optional<Web::Cookie::Cookie> get_named_cookie(URL::URL const& url, StringView name);
|
||||||
|
void expire_cookies_with_time_offset(AK::Duration);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit CookieJar(Optional<PersistedStorage>);
|
explicit CookieJar(Optional<PersistedStorage>);
|
||||||
|
|
|
@ -445,6 +445,11 @@ void WebContentClient::did_update_cookie(Web::Cookie::Cookie const& cookie)
|
||||||
Application::cookie_jar().update_cookie(cookie);
|
Application::cookie_jar().update_cookie(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebContentClient::did_expire_cookies_with_time_offset(AK::Duration offset)
|
||||||
|
{
|
||||||
|
Application::cookie_jar().expire_cookies_with_time_offset(offset);
|
||||||
|
}
|
||||||
|
|
||||||
Messages::WebContentClient::DidRequestNewWebViewResponse WebContentClient::did_request_new_web_view(u64 page_id, Web::HTML::ActivateTab const& activate_tab, Web::HTML::WebViewHints const& hints, Optional<u64> const& page_index)
|
Messages::WebContentClient::DidRequestNewWebViewResponse WebContentClient::did_request_new_web_view(u64 page_id, Web::HTML::ActivateTab const& activate_tab, Web::HTML::WebViewHints const& hints, Optional<u64> const& page_index)
|
||||||
{
|
{
|
||||||
if (auto view = view_for_page_id(page_id); view.has_value()) {
|
if (auto view = view_for_page_id(page_id); view.has_value()) {
|
||||||
|
|
|
@ -93,6 +93,7 @@ private:
|
||||||
virtual Messages::WebContentClient::DidRequestCookieResponse did_request_cookie(URL::URL const&, Web::Cookie::Source) override;
|
virtual Messages::WebContentClient::DidRequestCookieResponse did_request_cookie(URL::URL const&, Web::Cookie::Source) override;
|
||||||
virtual void did_set_cookie(URL::URL const&, Web::Cookie::ParsedCookie const&, Web::Cookie::Source) override;
|
virtual void did_set_cookie(URL::URL const&, Web::Cookie::ParsedCookie const&, Web::Cookie::Source) override;
|
||||||
virtual void did_update_cookie(Web::Cookie::Cookie const&) override;
|
virtual void did_update_cookie(Web::Cookie::Cookie const&) override;
|
||||||
|
virtual void did_expire_cookies_with_time_offset(AK::Duration) override;
|
||||||
virtual Messages::WebContentClient::DidRequestNewWebViewResponse did_request_new_web_view(u64 page_id, Web::HTML::ActivateTab const&, Web::HTML::WebViewHints const&, Optional<u64> const& page_index) override;
|
virtual Messages::WebContentClient::DidRequestNewWebViewResponse did_request_new_web_view(u64 page_id, Web::HTML::ActivateTab const&, Web::HTML::WebViewHints const&, Optional<u64> const& page_index) override;
|
||||||
virtual void did_request_activate_tab(u64 page_id) override;
|
virtual void did_request_activate_tab(u64 page_id) override;
|
||||||
virtual void did_close_browsing_context(u64 page_id) override;
|
virtual void did_close_browsing_context(u64 page_id) override;
|
||||||
|
|
|
@ -502,6 +502,11 @@ void PageClient::page_did_update_cookie(Web::Cookie::Cookie cookie)
|
||||||
client().async_did_update_cookie(move(cookie));
|
client().async_did_update_cookie(move(cookie));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PageClient::page_did_expire_cookies_with_time_offset(AK::Duration offset)
|
||||||
|
{
|
||||||
|
client().async_did_expire_cookies_with_time_offset(offset);
|
||||||
|
}
|
||||||
|
|
||||||
void PageClient::page_did_update_resource_count(i32 count_waiting)
|
void PageClient::page_did_update_resource_count(i32 count_waiting)
|
||||||
{
|
{
|
||||||
client().async_did_update_resource_count(m_id, count_waiting);
|
client().async_did_update_resource_count(m_id, count_waiting);
|
||||||
|
|
|
@ -146,6 +146,7 @@ private:
|
||||||
virtual String page_did_request_cookie(URL::URL const&, Web::Cookie::Source) override;
|
virtual String page_did_request_cookie(URL::URL const&, Web::Cookie::Source) override;
|
||||||
virtual void page_did_set_cookie(URL::URL const&, Web::Cookie::ParsedCookie const&, Web::Cookie::Source) override;
|
virtual void page_did_set_cookie(URL::URL const&, Web::Cookie::ParsedCookie const&, Web::Cookie::Source) override;
|
||||||
virtual void page_did_update_cookie(Web::Cookie::Cookie) override;
|
virtual void page_did_update_cookie(Web::Cookie::Cookie) override;
|
||||||
|
virtual void page_did_expire_cookies_with_time_offset(AK::Duration) override;
|
||||||
virtual void page_did_update_resource_count(i32) override;
|
virtual void page_did_update_resource_count(i32) override;
|
||||||
virtual NewWebViewResult page_did_request_new_web_view(Web::HTML::ActivateTab, Web::HTML::WebViewHints, Web::HTML::TokenizedFeature::NoOpener) override;
|
virtual NewWebViewResult page_did_request_new_web_view(Web::HTML::ActivateTab, Web::HTML::WebViewHints, Web::HTML::TokenizedFeature::NoOpener) override;
|
||||||
virtual void page_did_request_activate_tab() override;
|
virtual void page_did_request_activate_tab() override;
|
||||||
|
|
|
@ -71,6 +71,7 @@ endpoint WebContentClient
|
||||||
did_request_cookie(URL::URL url, Web::Cookie::Source source) => (String cookie)
|
did_request_cookie(URL::URL url, Web::Cookie::Source source) => (String cookie)
|
||||||
did_set_cookie(URL::URL url, Web::Cookie::ParsedCookie cookie, Web::Cookie::Source source) => ()
|
did_set_cookie(URL::URL url, Web::Cookie::ParsedCookie cookie, Web::Cookie::Source source) => ()
|
||||||
did_update_cookie(Web::Cookie::Cookie cookie) =|
|
did_update_cookie(Web::Cookie::Cookie cookie) =|
|
||||||
|
did_expire_cookies_with_time_offset(AK::Duration offset) =|
|
||||||
did_update_resource_count(u64 page_id, i32 count_waiting) =|
|
did_update_resource_count(u64 page_id, i32 count_waiting) =|
|
||||||
did_request_new_web_view(u64 page_id, Web::HTML::ActivateTab activate_tab, Web::HTML::WebViewHints hints, Optional<u64> page_index) => (String handle)
|
did_request_new_web_view(u64 page_id, Web::HTML::ActivateTab activate_tab, Web::HTML::WebViewHints hints, Optional<u64> page_index) => (String handle)
|
||||||
did_request_activate_tab(u64 page_id) =|
|
did_request_activate_tab(u64 page_id) =|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue